30 import org.graalvm.compiler.core.common.type.AbstractPointerStamp; |
30 import org.graalvm.compiler.core.common.type.AbstractPointerStamp; |
31 import org.graalvm.compiler.core.common.type.ObjectStamp; |
31 import org.graalvm.compiler.core.common.type.ObjectStamp; |
32 import org.graalvm.compiler.core.common.type.Stamp; |
32 import org.graalvm.compiler.core.common.type.Stamp; |
33 import org.graalvm.compiler.core.common.type.StampFactory; |
33 import org.graalvm.compiler.core.common.type.StampFactory; |
34 import org.graalvm.compiler.core.common.type.TypeReference; |
34 import org.graalvm.compiler.core.common.type.TypeReference; |
|
35 import org.graalvm.compiler.debug.DebugContext; |
35 import org.graalvm.compiler.graph.IterableNodeType; |
36 import org.graalvm.compiler.graph.IterableNodeType; |
36 import org.graalvm.compiler.graph.Node; |
37 import org.graalvm.compiler.graph.Node; |
37 import org.graalvm.compiler.graph.NodeClass; |
38 import org.graalvm.compiler.graph.NodeClass; |
38 import org.graalvm.compiler.graph.spi.Canonicalizable; |
39 import org.graalvm.compiler.graph.spi.Canonicalizable; |
39 import org.graalvm.compiler.graph.spi.CanonicalizerTool; |
40 import org.graalvm.compiler.graph.spi.CanonicalizerTool; |
98 this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), |
99 this(object, StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), |
99 nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT)))); |
100 nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT)))); |
100 } |
101 } |
101 |
102 |
102 public static ValueNode create(ValueNode object, Stamp stamp) { |
103 public static ValueNode create(ValueNode object, Stamp stamp) { |
103 ValueNode value = canonical(object, stamp, null); |
104 ValueNode value = canonical(object, stamp, null, null); |
104 if (value != null) { |
105 if (value != null) { |
105 return value; |
106 return value; |
106 } |
107 } |
107 return new PiNode(object, stamp); |
108 return new PiNode(object, stamp); |
108 } |
109 } |
109 |
110 |
110 public static ValueNode create(ValueNode object, Stamp stamp, ValueNode guard) { |
111 public static ValueNode create(ValueNode object, Stamp stamp, ValueNode guard) { |
111 ValueNode value = canonical(object, stamp, (GuardingNode) guard); |
112 ValueNode value = canonical(object, stamp, (GuardingNode) guard, null); |
112 if (value != null) { |
113 if (value != null) { |
113 return value; |
114 return value; |
114 } |
115 } |
115 return new PiNode(object, stamp, guard); |
116 return new PiNode(object, stamp, guard); |
116 } |
117 } |
117 |
118 |
118 public static ValueNode create(ValueNode object, ValueNode guard) { |
119 public static ValueNode create(ValueNode object, ValueNode guard) { |
119 Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT)); |
120 Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT)); |
120 ValueNode value = canonical(object, stamp, (GuardingNode) guard); |
121 ValueNode value = canonical(object, stamp, (GuardingNode) guard, null); |
121 if (value != null) { |
122 if (value != null) { |
122 return value; |
123 return value; |
123 } |
124 } |
124 return new PiNode(object, stamp, guard); |
125 return new PiNode(object, stamp, guard); |
125 } |
126 } |
126 |
127 |
127 @SuppressWarnings("unused") |
128 @SuppressWarnings("unused") |
128 public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) { |
129 public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ValueNode guard) { |
129 Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT)); |
130 Stamp stamp = AbstractPointerStamp.pointerNonNull(object.stamp(NodeView.DEFAULT)); |
130 ValueNode value = canonical(object, stamp, (GuardingNode) guard); |
131 ValueNode value = canonical(object, stamp, (GuardingNode) guard, null); |
131 if (value == null) { |
132 if (value == null) { |
132 value = new PiNode(object, stamp, guard); |
133 value = new PiNode(object, stamp, guard); |
133 } |
134 } |
134 b.push(JavaKind.Object, b.append(value)); |
135 b.push(JavaKind.Object, b.append(value)); |
135 return true; |
136 return true; |
137 |
138 |
138 @SuppressWarnings("unused") |
139 @SuppressWarnings("unused") |
139 public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { |
140 public static boolean intrinsify(GraphBuilderContext b, ResolvedJavaMethod method, ValueNode object, ResolvedJavaType toType, boolean exactType, boolean nonNull) { |
140 Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), |
141 Stamp stamp = StampFactory.object(exactType ? TypeReference.createExactTrusted(toType) : TypeReference.createWithoutAssumptions(toType), |
141 nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT))); |
142 nonNull || StampTool.isPointerNonNull(object.stamp(NodeView.DEFAULT))); |
142 ValueNode value = canonical(object, stamp, null); |
143 ValueNode value = canonical(object, stamp, null, null); |
143 if (value == null) { |
144 if (value == null) { |
144 value = new PiNode(object, stamp); |
145 value = new PiNode(object, stamp); |
145 } |
146 } |
146 b.push(JavaKind.Object, b.append(value)); |
147 b.push(JavaKind.Object, b.append(value)); |
147 return true; |
148 return true; |
175 @Override |
176 @Override |
176 public void virtualize(VirtualizerTool tool) { |
177 public void virtualize(VirtualizerTool tool) { |
177 ValueNode alias = tool.getAlias(object()); |
178 ValueNode alias = tool.getAlias(object()); |
178 if (alias instanceof VirtualObjectNode) { |
179 if (alias instanceof VirtualObjectNode) { |
179 VirtualObjectNode virtual = (VirtualObjectNode) alias; |
180 VirtualObjectNode virtual = (VirtualObjectNode) alias; |
180 if (StampTool.typeOrNull(this) != null && StampTool.typeOrNull(this).isAssignableFrom(virtual.type())) { |
181 ResolvedJavaType type = StampTool.typeOrNull(this, tool.getMetaAccess()); |
|
182 if (type != null && type.isAssignableFrom(virtual.type())) { |
181 tool.replaceWithVirtual(virtual); |
183 tool.replaceWithVirtual(virtual); |
|
184 } else { |
|
185 tool.getDebug().log(DebugContext.INFO_LEVEL, "could not virtualize Pi because of type mismatch: %s %s vs %s", this, type, virtual.type()); |
182 } |
186 } |
183 } |
187 } |
184 } |
188 } |
185 |
189 |
186 public static ValueNode canonical(ValueNode object, Stamp stamp, GuardingNode guard) { |
190 public static ValueNode canonical(ValueNode object, Stamp stamp, GuardingNode guard, PiNode self) { |
187 // Use most up to date stamp. |
191 // Use most up to date stamp. |
188 Stamp computedStamp = stamp.improveWith(object.stamp(NodeView.DEFAULT)); |
192 Stamp computedStamp = stamp.improveWith(object.stamp(NodeView.DEFAULT)); |
189 |
193 |
190 // The pi node does not give any additional information => skip it. |
194 // The pi node does not give any additional information => skip it. |
191 if (computedStamp.equals(object.stamp(NodeView.DEFAULT))) { |
195 if (computedStamp.equals(object.stamp(NodeView.DEFAULT))) { |
199 readNode.setStamp(readNode.stamp(NodeView.DEFAULT).improveWith(stamp)); |
203 readNode.setStamp(readNode.stamp(NodeView.DEFAULT).improveWith(stamp)); |
200 return readNode; |
204 return readNode; |
201 } |
205 } |
202 } else { |
206 } else { |
203 for (Node n : guard.asNode().usages()) { |
207 for (Node n : guard.asNode().usages()) { |
204 if (n instanceof PiNode) { |
208 if (n instanceof PiNode && n != self) { |
205 PiNode otherPi = (PiNode) n; |
209 PiNode otherPi = (PiNode) n; |
|
210 assert otherPi.guard == guard; |
206 if (object == otherPi.object() && computedStamp.equals(otherPi.stamp(NodeView.DEFAULT))) { |
211 if (object == otherPi.object() && computedStamp.equals(otherPi.stamp(NodeView.DEFAULT))) { |
207 /* |
212 /* |
208 * Two PiNodes with the same guard and same result, so return the one with |
213 * Two PiNodes with the same guard and same result, so return the one with |
209 * the more precise piStamp. |
214 * the more precise piStamp. |
210 */ |
215 */ |