use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class LoopTransformations method isUnrollableLoop.
public static boolean isUnrollableLoop(LoopEx loop) {
if (!loop.isCounted() || !loop.counted().getCounter().isConstantStride() || !loop.loop().getChildren().isEmpty()) {
return false;
}
LoopBeginNode loopBegin = loop.loopBegin();
LogicNode condition = loop.counted().getLimitTest().condition();
if (!(condition instanceof CompareNode)) {
return false;
}
if (((CompareNode) condition).condition() == CanonicalCondition.EQ) {
condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s condition unsupported %s ", loopBegin, ((CompareNode) condition).condition());
return false;
}
if (loopBegin.isMainLoop() || loopBegin.isSimpleLoop()) {
// as well.
if (loop.loop().getBlocks().size() < 3) {
return true;
}
condition.getDebug().log(DebugContext.VERBOSE_LEVEL, "isUnrollableLoop %s too large to unroll %s ", loopBegin, loop.loop().getBlocks().size());
}
return false;
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class LoopFragmentInside method placeNewSegmentAndCleanup.
private void placeNewSegmentAndCleanup(LoopEx loop) {
CountedLoopInfo mainCounted = loop.counted();
LoopBeginNode mainLoopBegin = loop.loopBegin();
// Discard the segment entry and its flow, after if merging it into the loop
StructuredGraph graph = mainLoopBegin.graph();
IfNode loopTest = mainCounted.getLimitTest();
IfNode newSegmentTest = getDuplicatedNode(loopTest);
AbstractBeginNode trueSuccessor = loopTest.trueSuccessor();
AbstractBeginNode falseSuccessor = loopTest.falseSuccessor();
FixedNode firstNode;
boolean codeInTrueSide = false;
if (trueSuccessor == mainCounted.getBody()) {
firstNode = trueSuccessor.next();
codeInTrueSide = true;
} else {
assert (falseSuccessor == mainCounted.getBody());
firstNode = falseSuccessor.next();
}
trueSuccessor = newSegmentTest.trueSuccessor();
falseSuccessor = newSegmentTest.falseSuccessor();
for (Node usage : falseSuccessor.anchored().snapshot()) {
usage.replaceFirstInput(falseSuccessor, loopTest.falseSuccessor());
}
for (Node usage : trueSuccessor.anchored().snapshot()) {
usage.replaceFirstInput(trueSuccessor, loopTest.trueSuccessor());
}
AbstractBeginNode startBlockNode;
if (codeInTrueSide) {
startBlockNode = trueSuccessor;
} else {
graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, mainLoopBegin.graph(), "before");
startBlockNode = falseSuccessor;
}
FixedNode lastNode = getBlockEnd(startBlockNode);
LoopEndNode loopEndNode = mainLoopBegin.getSingleLoopEnd();
FixedWithNextNode lastCodeNode = (FixedWithNextNode) loopEndNode.predecessor();
FixedNode newSegmentFirstNode = getDuplicatedNode(firstNode);
FixedWithNextNode newSegmentLastNode = getDuplicatedNode(lastCodeNode);
graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "Before placing segment");
if (firstNode instanceof LoopEndNode) {
GraphUtil.killCFG(getDuplicatedNode(mainLoopBegin));
} else {
newSegmentLastNode.clearSuccessors();
startBlockNode.setNext(lastNode);
lastCodeNode.replaceFirstSuccessor(loopEndNode, newSegmentFirstNode);
newSegmentLastNode.replaceFirstSuccessor(lastNode, loopEndNode);
lastCodeNode.setNext(newSegmentFirstNode);
newSegmentLastNode.setNext(loopEndNode);
startBlockNode.clearSuccessors();
lastNode.safeDelete();
Node newSegmentTestStart = newSegmentTest.predecessor();
LogicNode newSegmentIfTest = newSegmentTest.condition();
newSegmentTestStart.clearSuccessors();
newSegmentTest.safeDelete();
newSegmentIfTest.safeDelete();
trueSuccessor.safeDelete();
falseSuccessor.safeDelete();
newSegmentTestStart.safeDelete();
}
graph.getDebug().dump(DebugContext.DETAILED_LEVEL, loopEndNode.graph(), "After placing segment");
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class DefaultJavaLoweringProvider method getBoundsCheck.
protected GuardingNode getBoundsCheck(AccessIndexedNode n, ValueNode array, LoweringTool tool) {
StructuredGraph graph = n.graph();
ValueNode arrayLength = readArrayLength(array, tool.getConstantReflection());
if (arrayLength == null) {
arrayLength = createReadArrayLength(array, n, tool);
} else {
arrayLength = arrayLength.isAlive() ? arrayLength : graph.addOrUniqueWithInputs(arrayLength);
}
LogicNode boundsCheck = IntegerBelowNode.create(n.index(), arrayLength, NodeView.DEFAULT);
if (boundsCheck.isTautology()) {
return null;
}
return tool.createGuard(n, graph.addOrUniqueWithInputs(boundsCheck), BoundsCheckException, InvalidateReprofile);
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class DefaultJavaLoweringProvider method lowerStoreIndexedNode.
protected void lowerStoreIndexedNode(StoreIndexedNode storeIndexed, LoweringTool tool) {
StructuredGraph graph = storeIndexed.graph();
ValueNode value = storeIndexed.value();
ValueNode array = storeIndexed.array();
array = this.createNullCheckedValue(array, storeIndexed, tool);
GuardingNode boundsCheck = getBoundsCheck(storeIndexed, array, tool);
JavaKind elementKind = storeIndexed.elementKind();
LogicNode condition = null;
if (elementKind == JavaKind.Object && !StampTool.isPointerAlwaysNull(value)) {
/* Array store check. */
TypeReference arrayType = StampTool.typeReferenceOrNull(array);
if (arrayType != null && arrayType.isExact()) {
ResolvedJavaType elementType = arrayType.getType().getComponentType();
if (!elementType.isJavaLangObject()) {
TypeReference typeReference = TypeReference.createTrusted(storeIndexed.graph().getAssumptions(), elementType);
LogicNode typeTest = graph.addOrUniqueWithInputs(InstanceOfNode.create(typeReference, value));
condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, GraalDirectives.UNLIKELY_PROBABILITY);
}
} else {
/*
* The guard on the read hub should be the null check of the array that was
* introduced earlier.
*/
ValueNode arrayClass = createReadHub(graph, array, tool);
ValueNode componentHub = createReadArrayComponentHub(graph, arrayClass, storeIndexed);
LogicNode typeTest = graph.unique(InstanceOfDynamicNode.create(graph.getAssumptions(), tool.getConstantReflection(), componentHub, value, false));
condition = LogicNode.or(graph.unique(IsNullNode.create(value)), typeTest, GraalDirectives.UNLIKELY_PROBABILITY);
}
}
AddressNode address = createArrayIndexAddress(graph, array, elementKind, storeIndexed.index(), boundsCheck);
WriteNode memoryWrite = graph.add(new WriteNode(address, NamedLocationIdentity.getArrayLocation(elementKind), implicitStoreConvert(graph, elementKind, value), arrayStoreBarrierType(storeIndexed.elementKind())));
memoryWrite.setGuard(boundsCheck);
if (condition != null) {
tool.createGuard(storeIndexed, condition, DeoptimizationReason.ArrayStoreException, DeoptimizationAction.InvalidateReprofile);
}
memoryWrite.setStateAfter(storeIndexed.stateAfter());
graph.replaceFixedWithFixed(storeIndexed, memoryWrite);
}
use of org.graalvm.compiler.nodes.LogicNode in project graal by oracle.
the class ConditionalEliminationTest14 method test1.
@Test
public void test1() {
StructuredGraph graph = parseEager("test1Snippet", AllowAssumptions.YES);
CanonicalizerPhase canonicalizer = new CanonicalizerPhase();
PhaseContext context = new PhaseContext(getProviders());
/* Convert the LoadIndexNode to ReadNode with floating guards. */
new LoweringPhase(canonicalizer, LoweringTool.StandardLoweringStage.HIGH_TIER).apply(graph, context);
/* Convert the ReadNode to FloatingReadNode. */
new FloatingReadPhase().apply(graph);
/* Apply the phase that we want to test. */
new IterativeConditionalEliminationPhase(canonicalizer, true).apply(graph, context);
Assert.assertEquals("All guards must be floating", 0, graph.getNodes(FixedGuardNode.TYPE).count());
Assert.assertEquals("All array accesses must have been lowered", 0, graph.getNodes().filter(LoadIndexedNode.class).count());
Assert.assertEquals("All reads must be floating", 0, graph.getNodes().filter(ReadNode.class).count());
Assert.assertEquals("Must have floating reads (3 array accesses, 1 array length)", 4, graph.getNodes().filter(FloatingReadNode.class).count());
NodeIterable<GuardNode> boundsChecks = graph.getNodes(GuardNode.TYPE).filter(n -> ((GuardNode) n).getReason() == DeoptimizationReason.BoundsCheckException);
Assert.assertEquals("Must have only 1 bounds check remaining", 1, boundsChecks.count());
LogicNode condition = boundsChecks.first().getCondition();
Assert.assertTrue("Bounds check must check for array length 8", condition instanceof IntegerBelowNode && ((IntegerBelowNode) condition).getY().valueEquals(ConstantNode.forInt(8)));
}
Aggregations