40 import org.graalvm.compiler.nodes.LogicNegationNode; |
40 import org.graalvm.compiler.nodes.LogicNegationNode; |
41 import org.graalvm.compiler.nodes.LogicNode; |
41 import org.graalvm.compiler.nodes.LogicNode; |
42 import org.graalvm.compiler.nodes.NodeView; |
42 import org.graalvm.compiler.nodes.NodeView; |
43 import org.graalvm.compiler.nodes.StructuredGraph; |
43 import org.graalvm.compiler.nodes.StructuredGraph; |
44 import org.graalvm.compiler.nodes.ValueNode; |
44 import org.graalvm.compiler.nodes.ValueNode; |
|
45 import org.graalvm.compiler.options.OptionValues; |
45 |
46 |
46 import jdk.vm.ci.meta.Constant; |
47 import jdk.vm.ci.meta.Constant; |
47 import jdk.vm.ci.meta.ConstantReflectionProvider; |
48 import jdk.vm.ci.meta.ConstantReflectionProvider; |
|
49 import jdk.vm.ci.meta.MetaAccessProvider; |
48 import jdk.vm.ci.meta.PrimitiveConstant; |
50 import jdk.vm.ci.meta.PrimitiveConstant; |
49 import org.graalvm.compiler.options.OptionValues; |
|
50 |
51 |
51 @NodeInfo(cycles = CYCLES_1) |
52 @NodeInfo(cycles = CYCLES_1) |
52 public abstract class CompareNode extends BinaryOpLogicNode implements Canonicalizable.Binary<ValueNode> { |
53 public abstract class CompareNode extends BinaryOpLogicNode implements Canonicalizable.Binary<ValueNode> { |
53 |
54 |
54 public static final NodeClass<CompareNode> TYPE = NodeClass.create(CompareNode.class); |
55 public static final NodeClass<CompareNode> TYPE = NodeClass.create(CompareNode.class); |
55 protected final Condition condition; |
56 protected final CanonicalCondition condition; |
56 protected final boolean unorderedIsTrue; |
57 protected final boolean unorderedIsTrue; |
57 |
58 |
58 /** |
59 /** |
59 * Constructs a new Compare instruction. |
60 * Constructs a new Compare instruction. |
60 * |
61 * |
61 * @param x the instruction producing the first input to the instruction |
62 * @param x the instruction producing the first input to the instruction |
62 * @param y the instruction that produces the second input to this instruction |
63 * @param y the instruction that produces the second input to this instruction |
63 */ |
64 */ |
64 protected CompareNode(NodeClass<? extends CompareNode> c, Condition condition, boolean unorderedIsTrue, ValueNode x, ValueNode y) { |
65 protected CompareNode(NodeClass<? extends CompareNode> c, CanonicalCondition condition, boolean unorderedIsTrue, ValueNode x, ValueNode y) { |
65 super(c, x, y); |
66 super(c, x, y); |
66 this.condition = condition; |
67 this.condition = condition; |
67 this.unorderedIsTrue = unorderedIsTrue; |
68 this.unorderedIsTrue = unorderedIsTrue; |
68 } |
69 } |
69 |
70 |
70 /** |
71 /** |
71 * Gets the condition (comparison operation) for this instruction. |
72 * Gets the condition (comparison operation) for this instruction. |
72 * |
73 * |
73 * @return the condition |
74 * @return the condition |
74 */ |
75 */ |
75 public final Condition condition() { |
76 public final CanonicalCondition condition() { |
76 return condition; |
77 return condition; |
77 } |
78 } |
78 |
79 |
79 /** |
80 /** |
80 * Checks whether unordered inputs mean true or false (only applies to float operations). |
81 * Checks whether unordered inputs mean true or false (only applies to float operations). |
83 */ |
84 */ |
84 public final boolean unorderedIsTrue() { |
85 public final boolean unorderedIsTrue() { |
85 return this.unorderedIsTrue; |
86 return this.unorderedIsTrue; |
86 } |
87 } |
87 |
88 |
88 public static LogicNode tryConstantFold(Condition condition, ValueNode forX, ValueNode forY, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) { |
89 public static LogicNode tryConstantFold(CanonicalCondition condition, ValueNode forX, ValueNode forY, ConstantReflectionProvider constantReflection, boolean unorderedIsTrue) { |
89 if (forX.isConstant() && forY.isConstant() && (constantReflection != null || forX.asConstant() instanceof PrimitiveConstant)) { |
90 if (forX.isConstant() && forY.isConstant() && (constantReflection != null || forX.asConstant() instanceof PrimitiveConstant)) { |
90 return LogicConstantNode.forBoolean(condition.foldCondition(forX.asConstant(), forY.asConstant(), constantReflection, unorderedIsTrue)); |
91 return LogicConstantNode.forBoolean(condition.foldCondition(forX.asConstant(), forY.asConstant(), constantReflection, unorderedIsTrue)); |
91 } |
92 } |
92 return null; |
93 return null; |
93 } |
94 } |
94 |
95 |
95 @SuppressWarnings("unused") |
96 @SuppressWarnings("unused") |
96 public static LogicNode tryConstantFoldPrimitive(Condition condition, ValueNode forX, ValueNode forY, boolean unorderedIsTrue, NodeView view) { |
97 public static LogicNode tryConstantFoldPrimitive(CanonicalCondition condition, ValueNode forX, ValueNode forY, boolean unorderedIsTrue, NodeView view) { |
97 if (forX.asConstant() instanceof PrimitiveConstant && forY.asConstant() instanceof PrimitiveConstant) { |
98 if (forX.asConstant() instanceof PrimitiveConstant && forY.asConstant() instanceof PrimitiveConstant) { |
98 return LogicConstantNode.forBoolean(condition.foldCondition((PrimitiveConstant) forX.asConstant(), (PrimitiveConstant) forY.asConstant(), unorderedIsTrue)); |
99 return LogicConstantNode.forBoolean(condition.foldCondition((PrimitiveConstant) forX.asConstant(), (PrimitiveConstant) forY.asConstant(), unorderedIsTrue)); |
99 } |
100 } |
100 return null; |
101 return null; |
101 } |
102 } |
149 } |
150 } |
150 return null; |
151 return null; |
151 } |
152 } |
152 |
153 |
153 protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, |
154 protected LogicNode canonicalizeSymmetricConstant(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, |
154 Condition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue, NodeView view) { |
155 CanonicalCondition condition, Constant constant, ValueNode nonConstant, boolean mirrored, boolean unorderedIsTrue, NodeView view) { |
155 if (nonConstant instanceof ConditionalNode) { |
156 if (nonConstant instanceof ConditionalNode) { |
156 return optimizeConditional(constant, (ConditionalNode) nonConstant, constantReflection, mirrored ? condition.mirror() : condition, unorderedIsTrue); |
157 Condition realCondition = condition.asCondition(); |
|
158 if (mirrored) { |
|
159 realCondition = realCondition.mirror(); |
|
160 } |
|
161 return optimizeConditional(constant, (ConditionalNode) nonConstant, constantReflection, realCondition, unorderedIsTrue); |
157 } else if (nonConstant instanceof NormalizeCompareNode) { |
162 } else if (nonConstant instanceof NormalizeCompareNode) { |
158 return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (NormalizeCompareNode) nonConstant, mirrored, view); |
163 return optimizeNormalizeCompare(constantReflection, metaAccess, options, smallestCompareWidth, constant, (NormalizeCompareNode) nonConstant, mirrored, view); |
159 } else if (nonConstant instanceof ConvertNode) { |
164 } else if (nonConstant instanceof ConvertNode) { |
160 ConvertNode convert = (ConvertNode) nonConstant; |
165 ConvertNode convert = (ConvertNode) nonConstant; |
161 boolean multiUsage = (convert.asNode().hasMoreThanOneUsage() && convert.getValue().hasExactlyOneUsage()); |
166 boolean multiUsage = (convert.asNode().hasMoreThanOneUsage() && convert.getValue().hasExactlyOneUsage()); |
233 } |
238 } |
234 |
239 |
235 protected abstract LogicNode duplicateModified(ValueNode newW, ValueNode newY, boolean unorderedIsTrue, NodeView view); |
240 protected abstract LogicNode duplicateModified(ValueNode newW, ValueNode newY, boolean unorderedIsTrue, NodeView view); |
236 } |
241 } |
237 |
242 |
238 public static LogicNode createCompareNode(StructuredGraph graph, Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) { |
243 public static LogicNode createCompareNode(StructuredGraph graph, CanonicalCondition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) { |
239 LogicNode result = createCompareNode(condition, x, y, constantReflection, view); |
244 LogicNode result = createCompareNode(condition, x, y, constantReflection, view); |
240 return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result); |
245 return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result); |
241 } |
246 } |
242 |
247 |
243 public static LogicNode createCompareNode(Condition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) { |
248 public static LogicNode createCompareNode(CanonicalCondition condition, ValueNode x, ValueNode y, ConstantReflectionProvider constantReflection, NodeView view) { |
244 assert x.getStackKind() == y.getStackKind(); |
249 assert x.getStackKind() == y.getStackKind(); |
245 assert condition.isCanonical(); |
|
246 assert !x.getStackKind().isNumericFloat(); |
250 assert !x.getStackKind().isNumericFloat(); |
247 |
251 |
248 LogicNode comparison; |
252 LogicNode comparison; |
249 if (condition == Condition.EQ) { |
253 if (condition == CanonicalCondition.EQ) { |
250 if (x.stamp(view) instanceof AbstractObjectStamp) { |
254 if (x.stamp(view) instanceof AbstractObjectStamp) { |
251 comparison = ObjectEqualsNode.create(x, y, constantReflection, view); |
255 comparison = ObjectEqualsNode.create(x, y, constantReflection, view); |
252 } else if (x.stamp(view) instanceof AbstractPointerStamp) { |
256 } else if (x.stamp(view) instanceof AbstractPointerStamp) { |
253 comparison = PointerEqualsNode.create(x, y, view); |
257 comparison = PointerEqualsNode.create(x, y, view); |
254 } else { |
258 } else { |
255 assert x.getStackKind().isNumericInteger(); |
259 assert x.getStackKind().isNumericInteger(); |
256 comparison = IntegerEqualsNode.create(x, y, view); |
260 comparison = IntegerEqualsNode.create(x, y, view); |
257 } |
261 } |
258 } else if (condition == Condition.LT) { |
262 } else if (condition == CanonicalCondition.LT) { |
259 assert x.getStackKind().isNumericInteger(); |
263 assert x.getStackKind().isNumericInteger(); |
260 comparison = IntegerLessThanNode.create(x, y, view); |
264 comparison = IntegerLessThanNode.create(x, y, view); |
261 } else { |
265 } else { |
262 assert condition == Condition.BT; |
266 assert condition == CanonicalCondition.BT; |
263 assert x.getStackKind().isNumericInteger(); |
267 assert x.getStackKind().isNumericInteger(); |
264 comparison = IntegerBelowNode.create(x, y, view); |
268 comparison = IntegerBelowNode.create(x, y, view); |
265 } |
269 } |
266 |
270 |
267 return comparison; |
271 return comparison; |
268 } |
272 } |
269 |
273 |
270 public static LogicNode createCompareNode(StructuredGraph graph, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, |
274 public static LogicNode createCompareNode(StructuredGraph graph, ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, |
271 Condition condition, ValueNode x, ValueNode y, NodeView view) { |
275 CanonicalCondition condition, ValueNode x, ValueNode y, NodeView view) { |
272 LogicNode result = createCompareNode(constantReflection, metaAccess, options, smallestCompareWidth, condition, x, y, view); |
276 LogicNode result = createCompareNode(constantReflection, metaAccess, options, smallestCompareWidth, condition, x, y, view); |
273 return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result); |
277 return (result.graph() == null ? graph.addOrUniqueWithInputs(result) : result); |
274 } |
278 } |
275 |
279 |
276 public static LogicNode createCompareNode(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, |
280 public static LogicNode createCompareNode(ConstantReflectionProvider constantReflection, MetaAccessProvider metaAccess, OptionValues options, Integer smallestCompareWidth, |
277 Condition condition, ValueNode x, ValueNode y, NodeView view) { |
281 CanonicalCondition condition, ValueNode x, ValueNode y, NodeView view) { |
278 assert x.getStackKind() == y.getStackKind(); |
282 assert x.getStackKind() == y.getStackKind(); |
279 assert condition.isCanonical(); |
|
280 assert !x.getStackKind().isNumericFloat(); |
283 assert !x.getStackKind().isNumericFloat(); |
281 |
284 |
282 LogicNode comparison; |
285 LogicNode comparison; |
283 if (condition == Condition.EQ) { |
286 if (condition == CanonicalCondition.EQ) { |
284 if (x.stamp(view) instanceof AbstractObjectStamp) { |
287 if (x.stamp(view) instanceof AbstractObjectStamp) { |
285 assert smallestCompareWidth == null; |
288 assert smallestCompareWidth == null; |
286 comparison = ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y, view); |
289 comparison = ObjectEqualsNode.create(constantReflection, metaAccess, options, x, y, view); |
287 } else if (x.stamp(view) instanceof AbstractPointerStamp) { |
290 } else if (x.stamp(view) instanceof AbstractPointerStamp) { |
288 comparison = PointerEqualsNode.create(x, y, view); |
291 comparison = PointerEqualsNode.create(x, y, view); |
289 } else { |
292 } else { |
290 assert x.getStackKind().isNumericInteger(); |
293 assert x.getStackKind().isNumericInteger(); |
291 comparison = IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view); |
294 comparison = IntegerEqualsNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view); |
292 } |
295 } |
293 } else if (condition == Condition.LT) { |
296 } else if (condition == CanonicalCondition.LT) { |
294 assert x.getStackKind().isNumericInteger(); |
297 assert x.getStackKind().isNumericInteger(); |
295 comparison = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view); |
298 comparison = IntegerLessThanNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view); |
296 } else { |
299 } else { |
297 assert condition == Condition.BT; |
300 assert condition == CanonicalCondition.BT; |
298 assert x.getStackKind().isNumericInteger(); |
301 assert x.getStackKind().isNumericInteger(); |
299 comparison = IntegerBelowNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view); |
302 comparison = IntegerBelowNode.create(constantReflection, metaAccess, options, smallestCompareWidth, x, y, view); |
300 } |
303 } |
301 |
304 |
302 return comparison; |
305 return comparison; |