use of org.graalvm.compiler.nodes.calc.IntegerLessThanNode in project graal by oracle.
the class CountedLoopInfo method maxTripCountNode.
/**
* Returns a node that computes the maximum trip count of this loop. That is the trip count of
* this loop assuming it is not exited by an other exit than the {@linkplain #getLimitTest()
* count check}.
*
* This count is exact if {@link #isExactTripCount()} returns true.
*
* THIS VALUE SHOULD BE TREATED AS UNSIGNED.
*
* @param assumePositive if true the check that the loop is entered at all will be omitted.
*/
public ValueNode maxTripCountNode(boolean assumePositive) {
StructuredGraph graph = iv.valueNode().graph();
Stamp stamp = iv.valueNode().stamp(NodeView.DEFAULT);
ValueNode max;
ValueNode min;
ValueNode range;
ValueNode absStride;
if (iv.direction() == Direction.Up) {
absStride = iv.strideNode();
range = sub(graph, end, iv.initNode());
max = end;
min = iv.initNode();
} else {
assert iv.direction() == Direction.Down;
absStride = graph.maybeAddOrUnique(NegateNode.create(iv.strideNode(), NodeView.DEFAULT));
range = sub(graph, iv.initNode(), end);
max = iv.initNode();
min = end;
}
ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
if (oneOff) {
range = add(graph, range, one);
}
// round-away-from-zero divison: (range + stride -/+ 1) / stride
ValueNode denominator = add(graph, range, sub(graph, absStride, one));
ValueNode div = unsignedDivBefore(graph, loop.entryPoint(), denominator, absStride);
if (assumePositive) {
return div;
}
ConstantNode zero = ConstantNode.forIntegerStamp(stamp, 0, graph);
return graph.unique(new ConditionalNode(graph.unique(new IntegerLessThanNode(max, min)), zero, div));
}
use of org.graalvm.compiler.nodes.calc.IntegerLessThanNode in project graal by oracle.
the class CountedLoopInfo method createOverFlowGuard.
@SuppressWarnings("try")
public GuardingNode createOverFlowGuard() {
GuardingNode overflowGuard = getOverFlowGuard();
if (overflowGuard != null) {
return overflowGuard;
}
try (DebugCloseable position = loop.loopBegin().withNodeSourcePosition()) {
IntegerStamp stamp = (IntegerStamp) iv.valueNode().stamp(NodeView.DEFAULT);
StructuredGraph graph = iv.valueNode().graph();
// we use a negated guard with a < condition to achieve a >=
CompareNode cond;
ConstantNode one = ConstantNode.forIntegerStamp(stamp, 1, graph);
if (iv.direction() == Direction.Up) {
ValueNode v1 = sub(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.maxValue(stamp.getBits()), graph), sub(graph, iv.strideNode(), one));
if (oneOff) {
v1 = sub(graph, v1, one);
}
cond = graph.unique(new IntegerLessThanNode(v1, end));
} else {
assert iv.direction() == Direction.Down;
ValueNode v1 = add(graph, ConstantNode.forIntegerStamp(stamp, CodeUtil.minValue(stamp.getBits()), graph), sub(graph, one, iv.strideNode()));
if (oneOff) {
v1 = add(graph, v1, one);
}
cond = graph.unique(new IntegerLessThanNode(end, v1));
}
assert graph.getGuardsStage().allowsFloatingGuards();
overflowGuard = graph.unique(new GuardNode(cond, AbstractBeginNode.prevBegin(loop.entryPoint()), DeoptimizationReason.LoopLimitCheck, DeoptimizationAction.InvalidateRecompile, true, // TODO gd: use speculation
JavaConstant.NULL_POINTER));
loop.loopBegin().setOverflowGuard(overflowGuard);
return overflowGuard;
}
}
use of org.graalvm.compiler.nodes.calc.IntegerLessThanNode in project graal by oracle.
the class WordOperationPlugin method comparisonOp.
private ValueNode comparisonOp(GraphBuilderContext graph, Condition condition, ValueNode left, ValueNode right) {
assert left.getStackKind() == wordKind && right.getStackKind() == wordKind;
CanonicalizedCondition canonical = condition.canonicalize();
ValueNode a = canonical.mustMirror() ? right : left;
ValueNode b = canonical.mustMirror() ? left : right;
CompareNode comparison;
if (canonical.getCanonicalCondition() == CanonicalCondition.EQ) {
comparison = new IntegerEqualsNode(a, b);
} else if (canonical.getCanonicalCondition() == CanonicalCondition.BT) {
comparison = new IntegerBelowNode(a, b);
} else {
assert canonical.getCanonicalCondition() == CanonicalCondition.LT;
comparison = new IntegerLessThanNode(a, b);
}
ConstantNode trueValue = graph.add(forInt(1));
ConstantNode falseValue = graph.add(forInt(0));
if (canonical.mustNegate()) {
ConstantNode temp = trueValue;
trueValue = falseValue;
falseValue = temp;
}
return graph.add(new ConditionalNode(graph.add(comparison), trueValue, falseValue));
}
use of org.graalvm.compiler.nodes.calc.IntegerLessThanNode in project graal by oracle.
the class JNIPrimitiveArrayOperationMethod method newArray.
private ValueNode newArray(HostedProviders providers, JNIGraphKit kit, List<ValueNode> arguments) {
ResolvedJavaType elementType = providers.getMetaAccess().lookupJavaType(elementKind.toJavaClass());
ValueNode length = arguments.get(1);
ConstantNode zero = kit.createInt(0);
kit.startIf(new IntegerLessThanNode(length, zero), BranchProbabilityNode.VERY_SLOW_PATH_PROBABILITY);
kit.thenPart();
ValueNode nullHandle = kit.createConstant(JavaConstant.INT_0, providers.getWordTypes().getWordKind());
kit.elsePart();
ValueNode array = kit.append(new NewArrayNode(elementType, length, true));
ValueNode arrayHandle = kit.boxObjectInLocalHandle(array);
AbstractMergeNode merge = kit.endIf();
Stamp handleStamp = providers.getWordTypes().getWordStamp(providers.getMetaAccess().lookupJavaType(JNIObjectHandle.class));
return kit.unique(new ValuePhiNode(handleStamp, merge, new ValueNode[] { nullHandle, arrayHandle }));
}
use of org.graalvm.compiler.nodes.calc.IntegerLessThanNode in project graal by oracle.
the class LoopEx method detectCounted.
public boolean detectCounted() {
LoopBeginNode loopBegin = loopBegin();
FixedNode next = loopBegin.next();
while (next instanceof FixedGuardNode || next instanceof ValueAnchorNode || next instanceof FullInfopointNode) {
next = ((FixedWithNextNode) next).next();
}
if (next instanceof IfNode) {
IfNode ifNode = (IfNode) next;
boolean negated = false;
if (!loopBegin.isLoopExit(ifNode.falseSuccessor())) {
if (!loopBegin.isLoopExit(ifNode.trueSuccessor())) {
return false;
}
negated = true;
}
LogicNode ifTest = ifNode.condition();
if (!(ifTest instanceof IntegerLessThanNode) && !(ifTest instanceof IntegerEqualsNode)) {
if (ifTest instanceof IntegerBelowNode) {
ifTest.getDebug().log("Ignored potential Counted loop at %s with |<|", loopBegin);
}
return false;
}
CompareNode lessThan = (CompareNode) ifTest;
Condition condition = null;
InductionVariable iv = null;
ValueNode limit = null;
if (isOutsideLoop(lessThan.getX())) {
iv = getInductionVariables().get(lessThan.getY());
if (iv != null) {
condition = lessThan.condition().asCondition().mirror();
limit = lessThan.getX();
}
} else if (isOutsideLoop(lessThan.getY())) {
iv = getInductionVariables().get(lessThan.getX());
if (iv != null) {
condition = lessThan.condition().asCondition();
limit = lessThan.getY();
}
}
if (condition == null) {
return false;
}
if (negated) {
condition = condition.negate();
}
boolean oneOff = false;
switch(condition) {
case EQ:
return false;
case NE:
{
if (!iv.isConstantStride() || Math.abs(iv.constantStride()) != 1) {
return false;
}
IntegerStamp initStamp = (IntegerStamp) iv.initNode().stamp(NodeView.DEFAULT);
IntegerStamp limitStamp = (IntegerStamp) limit.stamp(NodeView.DEFAULT);
if (iv.direction() == Direction.Up) {
if (initStamp.upperBound() > limitStamp.lowerBound()) {
return false;
}
} else if (iv.direction() == Direction.Down) {
if (initStamp.lowerBound() < limitStamp.upperBound()) {
return false;
}
} else {
return false;
}
break;
}
case LE:
oneOff = true;
if (iv.direction() != Direction.Up) {
return false;
}
break;
case LT:
if (iv.direction() != Direction.Up) {
return false;
}
break;
case GE:
oneOff = true;
if (iv.direction() != Direction.Down) {
return false;
}
break;
case GT:
if (iv.direction() != Direction.Down) {
return false;
}
break;
default:
throw GraalError.shouldNotReachHere();
}
counted = new CountedLoopInfo(this, iv, ifNode, limit, oneOff, negated ? ifNode.falseSuccessor() : ifNode.trueSuccessor());
return true;
}
return false;
}
Aggregations