27 import static org.graalvm.compiler.loop.MathUtil.unsignedDivBefore; |
27 import static org.graalvm.compiler.loop.MathUtil.unsignedDivBefore; |
28 |
28 |
29 import org.graalvm.compiler.core.common.type.IntegerStamp; |
29 import org.graalvm.compiler.core.common.type.IntegerStamp; |
30 import org.graalvm.compiler.core.common.type.Stamp; |
30 import org.graalvm.compiler.core.common.type.Stamp; |
31 import org.graalvm.compiler.core.common.util.UnsignedLong; |
31 import org.graalvm.compiler.core.common.util.UnsignedLong; |
|
32 import org.graalvm.compiler.debug.DebugCloseable; |
32 import org.graalvm.compiler.loop.InductionVariable.Direction; |
33 import org.graalvm.compiler.loop.InductionVariable.Direction; |
33 import org.graalvm.compiler.nodes.AbstractBeginNode; |
34 import org.graalvm.compiler.nodes.AbstractBeginNode; |
34 import org.graalvm.compiler.nodes.ConstantNode; |
35 import org.graalvm.compiler.nodes.ConstantNode; |
35 import org.graalvm.compiler.nodes.GuardNode; |
36 import org.graalvm.compiler.nodes.GuardNode; |
36 import org.graalvm.compiler.nodes.IfNode; |
37 import org.graalvm.compiler.nodes.IfNode; |
221 |
222 |
222 public GuardingNode getOverFlowGuard() { |
223 public GuardingNode getOverFlowGuard() { |
223 return loop.loopBegin().getOverflowGuard(); |
224 return loop.loopBegin().getOverflowGuard(); |
224 } |
225 } |
225 |
226 |
|
227 @SuppressWarnings("try") |
226 public GuardingNode createOverFlowGuard() { |
228 public GuardingNode createOverFlowGuard() { |
227 GuardingNode overflowGuard = getOverFlowGuard(); |
229 GuardingNode overflowGuard = getOverFlowGuard(); |
228 if (overflowGuard != null) { |
230 if (overflowGuard != null) { |
229 return overflowGuard; |
231 return overflowGuard; |
230 } |
232 } |
231 IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT); |
233 try (DebugCloseable position = loop.loopBegin().withNodeSourcePosition()) { |
232 StructuredGraph graph = iv.valueNode().graph(); |
234 IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT); |
233 CompareNode cond; // we use a negated guard with a < condition to achieve a >= |
235 StructuredGraph graph = iv.valueNode().graph(); |
234 ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph); |
236 CompareNode cond; // we use a negated guard with a < condition to achieve a >= |
235 if (iv.direction() == Direction.Up) { |
237 ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph); |
236 ValueNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one)); |
238 if (iv.direction() == Direction.Up) { |
237 if (oneOff) { |
239 ValueNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one)); |
238 v1 = sub(graph, v1, one); |
240 if (oneOff) { |
|
241 v1 = sub(graph, v1, one); |
|
242 } |
|
243 cond = graph.unique(new IntegerLessThanNode(v1, end)); |
|
244 } else { |
|
245 assert iv.direction() == Direction.Down; |
|
246 ValueNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode())); |
|
247 if (oneOff) { |
|
248 v1 = add(graph, v1, one); |
|
249 } |
|
250 cond = graph.unique(new IntegerLessThanNode(end, v1)); |
239 } |
251 } |
240 cond = graph.unique(new IntegerLessThanNode(v1, end)); |
252 assert graph.getGuardsStage().allowsFloatingGuards(); |
241 } else { |
253 overflowGuard = graph.unique(new GuardNode(cond, AbstractBeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true, |
242 assert iv.direction() == Direction.Down; |
254 JavaConstant.NULL_POINTER)); // TODO gd: use speculation |
243 ValueNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode())); |
255 loop.loopBegin().setOverflowGuard(overflowGuard); |
244 if (oneOff) { |
256 return overflowGuard; |
245 v1 = add(graph, v1, one); |
257 } |
246 } |
|
247 cond = graph.unique(new IntegerLessThanNode(end, v1)); |
|
248 } |
|
249 assert graph.getGuardsStage().allowsFloatingGuards(); |
|
250 overflowGuard = graph.unique(new GuardNode(cond, AbstractBeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true, |
|
251 JavaConstant.NULL_POINTER)); // TODO gd: use speculation |
|
252 loop.loopBegin().setOverflowGuard(overflowGuard); |
|
253 return overflowGuard; |
|
254 } |
258 } |
255 |
259 |
256 public IntegerStamp getStamp() { |
260 public IntegerStamp getStamp() { |
257 return (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT); |
261 return (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT); |
258 } |
262 } |