MemoryMapNode.java revision 13175:3df8ef613001
1/*
2 * Copyright (c) 2014, 2016, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23package org.graalvm.compiler.nodes.memory;
24
25import static org.graalvm.compiler.nodeinfo.InputType.Extension;
26import static org.graalvm.compiler.nodeinfo.InputType.Memory;
27import static org.graalvm.compiler.nodeinfo.NodeCycles.CYCLES_0;
28import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
29import static org.graalvm.word.LocationIdentity.any;
30
31import java.util.ArrayList;
32import java.util.Collection;
33import java.util.List;
34
35import org.graalvm.compiler.core.common.type.StampFactory;
36import org.graalvm.compiler.graph.NodeClass;
37import org.graalvm.compiler.graph.NodeInputList;
38import org.graalvm.compiler.nodeinfo.NodeInfo;
39import org.graalvm.compiler.nodes.StartNode;
40import org.graalvm.compiler.nodes.ValueNode;
41import org.graalvm.compiler.nodes.calc.FloatingNode;
42import org.graalvm.compiler.nodes.spi.LIRLowerable;
43import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
44import org.graalvm.util.Equivalence;
45import org.graalvm.util.EconomicMap;
46import org.graalvm.util.MapCursor;
47import org.graalvm.word.LocationIdentity;
48
49@NodeInfo(allowedUsageTypes = {Extension, Memory}, cycles = CYCLES_0, size = SIZE_0)
50public final class MemoryMapNode extends FloatingNode implements MemoryMap, MemoryNode, LIRLowerable {
51
52    public static final NodeClass<MemoryMapNode> TYPE = NodeClass.create(MemoryMapNode.class);
53    protected final List<LocationIdentity> locationIdentities;
54    @Input(Memory) NodeInputList<ValueNode> nodes;
55
56    private boolean checkOrder(EconomicMap<LocationIdentity, MemoryNode> mmap) {
57        for (int i = 0; i < locationIdentities.size(); i++) {
58            LocationIdentity locationIdentity = locationIdentities.get(i);
59            ValueNode n = nodes.get(i);
60            assertTrue(mmap.get(locationIdentity) == n, "iteration order of keys differs from values in input map");
61        }
62        return true;
63    }
64
65    public MemoryMapNode(EconomicMap<LocationIdentity, MemoryNode> mmap) {
66        super(TYPE, StampFactory.forVoid());
67        int size = mmap.size();
68        locationIdentities = new ArrayList<>(size);
69        nodes = new NodeInputList<>(this, size);
70        int index = 0;
71        MapCursor<LocationIdentity, MemoryNode> cursor = mmap.getEntries();
72        while (cursor.advance()) {
73            locationIdentities.add(cursor.getKey());
74            nodes.initialize(index, (ValueNode) cursor.getValue());
75            index++;
76        }
77        assert checkOrder(mmap);
78    }
79
80    public boolean isEmpty() {
81        if (locationIdentities.isEmpty()) {
82            return true;
83        }
84        if (locationIdentities.size() == 1) {
85            if (nodes.get(0) instanceof StartNode) {
86                return true;
87            }
88        }
89        return false;
90    }
91
92    @Override
93    public MemoryNode getLastLocationAccess(LocationIdentity locationIdentity) {
94        if (locationIdentity.isImmutable()) {
95            return null;
96        } else {
97            int index = locationIdentities.indexOf(locationIdentity);
98            if (index == -1) {
99                index = locationIdentities.indexOf(any());
100            }
101            assert index != -1;
102            return (MemoryNode) nodes.get(index);
103        }
104    }
105
106    @Override
107    public Collection<LocationIdentity> getLocations() {
108        return locationIdentities;
109    }
110
111    public EconomicMap<LocationIdentity, MemoryNode> toMap() {
112        EconomicMap<LocationIdentity, MemoryNode> res = EconomicMap.create(Equivalence.DEFAULT, locationIdentities.size());
113        for (int i = 0; i < nodes.size(); i++) {
114            res.put(locationIdentities.get(i), (MemoryNode) nodes.get(i));
115        }
116        return res;
117    }
118
119    @Override
120    public void generate(NodeLIRBuilderTool generator) {
121        // nothing to do...
122    }
123}
124