|
30 | 30 | import static org.graalvm.compiler.nodeinfo.NodeSize.SIZE_0;
|
31 | 31 |
|
32 | 32 | import org.graalvm.compiler.core.common.type.StampFactory;
|
| 33 | +import org.graalvm.compiler.graph.Node; |
33 | 34 | import org.graalvm.compiler.graph.NodeClass;
|
34 | 35 | import org.graalvm.compiler.graph.spi.NodeWithIdentity;
|
35 | 36 | import org.graalvm.compiler.nodeinfo.NodeInfo;
|
36 |
| -import org.graalvm.compiler.nodes.AbstractBeginNode; |
37 |
| -import org.graalvm.compiler.nodes.FixedNode; |
38 | 37 | import org.graalvm.compiler.nodes.FixedWithNextNode;
|
39 |
| -import org.graalvm.compiler.nodes.ValueNode; |
40 | 38 | import org.graalvm.compiler.nodes.debug.ControlFlowAnchored;
|
41 |
| -import org.graalvm.compiler.nodes.memory.FixedAccessNode; |
| 39 | +import org.graalvm.compiler.nodes.spi.Canonicalizable; |
| 40 | +import org.graalvm.compiler.nodes.spi.CanonicalizerTool; |
42 | 41 | import org.graalvm.compiler.nodes.spi.LIRLowerable;
|
43 | 42 | import org.graalvm.compiler.nodes.spi.NodeLIRBuilderTool;
|
44 |
| -import org.graalvm.compiler.nodes.spi.Simplifiable; |
45 |
| -import org.graalvm.compiler.nodes.spi.SimplifierTool; |
46 |
| -import org.graalvm.compiler.nodes.spi.Virtualizable; |
47 |
| -import org.graalvm.compiler.nodes.spi.VirtualizerTool; |
48 |
| -import org.graalvm.compiler.nodes.util.GraphUtil; |
49 |
| -import org.graalvm.compiler.nodes.virtual.VirtualObjectNode; |
50 | 43 |
|
51 | 44 | /**
|
52 |
| - * This node can be used for two different kinds of anchoring for non-CFG (floating) nodes: It can |
53 |
| - * 1) keep one node above a certain point in the graph by specifying that node as the |
54 |
| - * {@link #anchored} node; or 2) it can keep nodes below a certain point in the graph by using this |
55 |
| - * node as an Anchor or Guard input. |
| 45 | + * This node can be used to keep nodes below a certain point in the graph by using this node as an |
| 46 | + * Anchor or Guard input. |
56 | 47 | *
|
57 | 48 | * This node must not move in the CFG, because that would change the anchor point. So optimizations
|
58 | 49 | * like de-duplication are not allowed and this node implements {@link NodeWithIdentity}. However,
|
59 | 50 | * duplication is allowed, i.e., it is on purpose that this node does not implement
|
60 | 51 | * {@link ControlFlowAnchored}.
|
61 | 52 | */
|
62 | 53 | @NodeInfo(allowedUsageTypes = {Anchor, Guard}, cycles = CYCLES_0, size = SIZE_0)
|
63 |
| -public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Simplifiable, Virtualizable, AnchoringNode, GuardingNode, NodeWithIdentity { |
| 54 | +public final class ValueAnchorNode extends FixedWithNextNode implements LIRLowerable, Canonicalizable, AnchoringNode, GuardingNode, NodeWithIdentity { |
64 | 55 |
|
65 | 56 | public static final NodeClass<ValueAnchorNode> TYPE = NodeClass.create(ValueAnchorNode.class);
|
66 |
| - @OptionalInput(Guard) ValueNode anchored; |
67 | 57 |
|
68 |
| - public ValueAnchorNode(ValueNode value) { |
| 58 | + public ValueAnchorNode() { |
69 | 59 | super(TYPE, StampFactory.forVoid());
|
70 |
| - this.anchored = value; |
71 | 60 | }
|
72 | 61 |
|
73 | 62 | @Override
|
74 | 63 | public void generate(NodeLIRBuilderTool gen) {
|
75 | 64 | // Nothing to emit, since this node is used for structural purposes only.
|
76 | 65 | }
|
77 | 66 |
|
78 |
| - public ValueNode getAnchoredNode() { |
79 |
| - return anchored; |
80 |
| - } |
81 |
| - |
82 | 67 | @Override
|
83 |
| - public void simplify(SimplifierTool tool) { |
84 |
| - while (next() instanceof ValueAnchorNode) { |
85 |
| - ValueAnchorNode nextAnchor = (ValueAnchorNode) next(); |
86 |
| - if (nextAnchor.anchored == anchored || nextAnchor.anchored == null) { |
87 |
| - // two anchors for the same anchored -> coalesce |
88 |
| - // nothing anchored on the next anchor -> coalesce |
89 |
| - nextAnchor.replaceAtUsages(this); |
90 |
| - GraphUtil.removeFixedWithUnusedInputs(nextAnchor); |
91 |
| - /* |
92 |
| - * Combining two anchors can allow the combining of two PiNode that are now anchored |
93 |
| - * at the same place. |
94 |
| - */ |
95 |
| - tool.addToWorkList(usages()); |
96 |
| - } else { |
97 |
| - break; |
98 |
| - } |
99 |
| - } |
100 |
| - if (tool.allUsagesAvailable() && hasNoUsages() && next() instanceof FixedAccessNode) { |
101 |
| - FixedAccessNode currentNext = (FixedAccessNode) next(); |
102 |
| - if (currentNext.getGuard() == anchored) { |
103 |
| - GraphUtil.removeFixedWithUnusedInputs(this); |
104 |
| - return; |
105 |
| - } |
106 |
| - } |
107 |
| - |
108 |
| - if (anchored != null && (anchored.isConstant() || anchored instanceof FixedNode)) { |
109 |
| - // anchoring fixed nodes and constants is useless |
110 |
| - removeAnchoredNode(); |
111 |
| - } |
112 |
| - |
113 |
| - if (anchored == null && hasNoUsages()) { |
114 |
| - // anchor is not necessary any more => remove. |
115 |
| - GraphUtil.removeFixedWithUnusedInputs(this); |
| 68 | + public Node canonical(CanonicalizerTool tool) { |
| 69 | + if (tool.allUsagesAvailable() && hasNoUsages()) { |
| 70 | + return null; |
116 | 71 | }
|
117 |
| - } |
118 |
| - |
119 |
| - @Override |
120 |
| - public void virtualize(VirtualizerTool tool) { |
121 |
| - if (anchored == null || anchored instanceof AbstractBeginNode) { |
122 |
| - tool.delete(); |
123 |
| - } else { |
124 |
| - ValueNode alias = tool.getAlias(anchored); |
125 |
| - if (alias instanceof VirtualObjectNode) { |
126 |
| - tool.delete(); |
127 |
| - } |
128 |
| - } |
129 |
| - } |
130 |
| - |
131 |
| - public void removeAnchoredNode() { |
132 |
| - this.updateUsages(anchored, null); |
133 |
| - this.anchored = null; |
| 72 | + return this; |
134 | 73 | }
|
135 | 74 | }
|
0 commit comments