use of org.graalvm.compiler.nodes.spi.Simplifiable in project graal by oracle.
the class ConvertDeoptimizeToGuardPhase method propagateFixed.
@SuppressWarnings("try")
private static void propagateFixed(FixedNode from, StaticDeoptimizingNode deopt, CoreProviders providers, LazyValue<LoopsData> lazyLoops) {
Node current = from;
while (current != null) {
if (GraalOptions.GuardPriorities.getValue(from.getOptions()) && current instanceof FixedGuardNode) {
FixedGuardNode otherGuard = (FixedGuardNode) current;
if (otherGuard.computePriority().isHigherPriorityThan(deopt.computePriority())) {
moveAsDeoptAfter(otherGuard, deopt);
return;
}
} else if (current instanceof AbstractBeginNode) {
if (current instanceof AbstractMergeNode) {
AbstractMergeNode mergeNode = (AbstractMergeNode) current;
FixedNode next = mergeNode.next();
while (mergeNode.isAlive()) {
AbstractEndNode end = mergeNode.forwardEnds().first();
propagateFixed(end, deopt, providers, lazyLoops);
}
if (next.isAlive()) {
propagateFixed(next, deopt, providers, lazyLoops);
}
return;
} else if (current.predecessor() instanceof IfNode) {
AbstractBeginNode begin = (AbstractBeginNode) current;
IfNode ifNode = (IfNode) current.predecessor();
if (isOsrLoopExit(begin) || isCountedLoopExit(ifNode, lazyLoops)) {
moveAsDeoptAfter(begin, deopt);
} else {
// Prioritize the source position of the IfNode
try (DebugCloseable closable = ifNode.withNodeSourcePosition()) {
StructuredGraph graph = ifNode.graph();
LogicNode conditionNode = ifNode.condition();
boolean negateGuardCondition = current == ifNode.trueSuccessor();
NodeSourcePosition survivingSuccessorPosition = negateGuardCondition ? ifNode.falseSuccessor().getNodeSourcePosition() : ifNode.trueSuccessor().getNodeSourcePosition();
FixedGuardNode guard = graph.add(new FixedGuardNode(conditionNode, deopt.getReason(), deopt.getAction(), deopt.getSpeculation(), negateGuardCondition, survivingSuccessorPosition));
FixedWithNextNode pred = (FixedWithNextNode) ifNode.predecessor();
AbstractBeginNode survivingSuccessor;
if (negateGuardCondition) {
survivingSuccessor = ifNode.falseSuccessor();
} else {
survivingSuccessor = ifNode.trueSuccessor();
}
graph.removeSplitPropagate(ifNode, survivingSuccessor);
Node newGuard = guard;
if (survivingSuccessor instanceof LoopExitNode) {
newGuard = ProxyNode.forGuard(guard, (LoopExitNode) survivingSuccessor);
}
survivingSuccessor.replaceAtUsages(newGuard, InputType.Guard);
graph.getDebug().log("Converting deopt on %-5s branch of %s to guard for remaining branch %s.", negateGuardCondition, ifNode, survivingSuccessor);
FixedNode next = pred.next();
pred.setNext(guard);
guard.setNext(next);
assert providers != null;
SimplifierTool simplifierTool = GraphUtil.getDefaultSimplifier(providers, false, graph.getAssumptions(), graph.getOptions());
((Simplifiable) survivingSuccessor).simplify(simplifierTool);
}
}
return;
} else if (current.predecessor() == null || current.predecessor() instanceof ControlSplitNode) {
assert current.predecessor() != null || (current instanceof StartNode && current == ((AbstractBeginNode) current).graph().start());
moveAsDeoptAfter((AbstractBeginNode) current, deopt);
return;
}
}
current = current.predecessor();
}
}
use of org.graalvm.compiler.nodes.spi.Simplifiable in project graal by oracle.
the class LoopTransformations method fullUnroll.
@SuppressWarnings("try")
public static void fullUnroll(LoopEx loop, CoreProviders context, CanonicalizerPhase canonicalizer) {
// assert loop.isCounted(); //TODO (gd) strengthen : counted with known trip count
LoopBeginNode loopBegin = loop.loopBegin();
StructuredGraph graph = loopBegin.graph();
int initialNodeCount = graph.getNodeCount();
SimplifierTool defaultSimplifier = GraphUtil.getDefaultSimplifier(context, canonicalizer.getCanonicalizeReads(), graph.getAssumptions(), graph.getOptions());
/*
* IMPORTANT: Canonicalizations inside the body of the remaining loop can introduce new
* control flow that is not automatically picked up by the control flow graph computation of
* the original LoopEx data structure, thus we disable simplification and manually simplify
* conditions in the peeled iteration to simplify the exit path.
*/
CanonicalizerPhase c = canonicalizer.copyWithoutSimplification();
EconomicSetNodeEventListener l = new EconomicSetNodeEventListener();
int peelings = 0;
try (NodeEventScope ev = graph.trackNodeEvents(l)) {
while (!loopBegin.isDeleted()) {
Mark newNodes = graph.getMark();
/*
* Mark is not enough for the canonicalization of the floating nodes in the unrolled
* code since pre-existing constants are not new nodes. Therefore, we canonicalize
* (without simplification) all floating nodes changed during peeling but only
* simplify new (in the peeled iteration) ones.
*/
EconomicSetNodeEventListener peeledListener = new EconomicSetNodeEventListener();
try (NodeEventScope peeledScope = graph.trackNodeEvents(peeledListener)) {
LoopTransformations.peel(loop);
}
graph.getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, graph, "After peeling loop %s", loop);
c.applyIncremental(graph, context, peeledListener.getNodes());
loop.invalidateFragmentsAndIVs();
for (Node n : graph.getNewNodes(newNodes)) {
if (n.isAlive() && (n instanceof IfNode || n instanceof SwitchNode || n instanceof FixedGuardNode || n instanceof BeginNode)) {
Simplifiable s = (Simplifiable) n;
s.simplify(defaultSimplifier);
graph.getDebug().dump(DebugContext.VERY_DETAILED_LEVEL, graph, "After simplifying if %s", s);
}
}
if (graph.getNodeCount() > initialNodeCount + MaximumDesiredSize.getValue(graph.getOptions()) * 2 || peelings > DefaultLoopPolicies.Options.FullUnrollMaxIterations.getValue(graph.getOptions())) {
throw new RetryableBailoutException("FullUnroll : Graph seems to grow out of proportion");
}
peelings++;
}
}
// Canonicalize with the original canonicalizer to capture all simplifications
canonicalizer.applyIncremental(graph, context, l.getNodes());
}
Aggregations