use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class IntrinsicContext method createFrameState.
public FrameState createFrameState(StructuredGraph graph, SideEffectsState sideEffects, StateSplit forStateSplit, NodeSourcePosition sourcePosition) {
assert forStateSplit != graph.start();
if (forStateSplit.hasSideEffect()) {
if (sideEffects.isAfterSideEffect()) {
// Only the last side effect on any execution path in a replacement
// can inherit the stateAfter of the replaced node
FrameState invalid = graph.add(new FrameState(INVALID_FRAMESTATE_BCI));
if (graph.trackNodeSourcePosition()) {
invalid.setNodeSourcePosition(sourcePosition);
}
for (StateSplit lastSideEffect : sideEffects.sideEffects()) {
lastSideEffect.setStateAfter(invalid);
}
}
sideEffects.addSideEffect(forStateSplit);
FrameState frameState;
if (forStateSplit instanceof ExceptionObjectNode) {
frameState = graph.add(new FrameState(AFTER_EXCEPTION_BCI, (ExceptionObjectNode) forStateSplit));
} else {
frameState = graph.add(new FrameState(AFTER_BCI));
}
if (graph.trackNodeSourcePosition()) {
frameState.setNodeSourcePosition(sourcePosition);
}
return frameState;
} else {
if (forStateSplit instanceof AbstractMergeNode) {
// Merge nodes always need a frame state
if (sideEffects.isAfterSideEffect()) {
// A merge after one or more side effects
FrameState frameState = graph.add(new FrameState(AFTER_BCI));
if (graph.trackNodeSourcePosition()) {
frameState.setNodeSourcePosition(sourcePosition);
}
return frameState;
} else {
// A merge before any side effects
FrameState frameState = graph.add(new FrameState(BEFORE_BCI));
if (graph.trackNodeSourcePosition()) {
frameState.setNodeSourcePosition(sourcePosition);
}
return frameState;
}
} else {
// Other non-side-effects do not need a state
return null;
}
}
}
use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class ProfileNode method simplify.
@Override
public void simplify(SimplifierTool tool) {
for (Node p = predecessor(); p != null; p = p.predecessor()) {
// Terminate search when we hit a control split or merge.
if (p instanceof ControlSplitNode || p instanceof AbstractMergeNode) {
break;
}
if (p instanceof ProfileNode) {
ProfileNode that = (ProfileNode) p;
if (this.canBeMergedWith(that)) {
that.setStep(this.getStep() + that.getStep());
removeFixedWithUnusedInputs(this);
tool.addToWorkList(that);
break;
}
}
}
}
use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class ConvertDeoptimizeToGuardPhase method processFixedGuardAndPhis.
private void processFixedGuardAndPhis(FixedGuardNode fixedGuard, PhaseContext context, CompareNode compare, ValueNode x, ValuePhiNode xPhi, ValueNode y, ValuePhiNode yPhi) {
AbstractBeginNode pred = AbstractBeginNode.prevBegin(fixedGuard);
if (pred instanceof AbstractMergeNode) {
AbstractMergeNode merge = (AbstractMergeNode) pred;
if (xPhi != null && xPhi.merge() != merge) {
return;
}
if (yPhi != null && yPhi.merge() != merge) {
return;
}
processFixedGuardAndMerge(fixedGuard, context, compare, x, xPhi, y, yPhi, merge);
}
}
use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class DeoptimizationGroupingPhase method run.
@Override
protected void run(StructuredGraph graph, MidTierContext context) {
ControlFlowGraph cfg = null;
for (FrameState fs : graph.getNodes(FrameState.TYPE)) {
FixedNode target = null;
PhiNode reasonActionPhi = null;
PhiNode speculationPhi = null;
List<AbstractDeoptimizeNode> obsoletes = null;
for (AbstractDeoptimizeNode deopt : fs.usages().filter(AbstractDeoptimizeNode.class)) {
if (target == null) {
target = deopt;
} else {
if (cfg == null) {
cfg = ControlFlowGraph.compute(graph, true, true, false, false);
}
AbstractMergeNode merge;
if (target instanceof AbstractDeoptimizeNode) {
merge = graph.add(new MergeNode());
EndNode firstEnd = graph.add(new EndNode());
ValueNode actionAndReason = ((AbstractDeoptimizeNode) target).getActionAndReason(context.getMetaAccess());
ValueNode speculation = ((AbstractDeoptimizeNode) target).getSpeculation(context.getMetaAccess());
reasonActionPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(actionAndReason.getStackKind()), merge));
speculationPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(speculation.getStackKind()), merge));
merge.addForwardEnd(firstEnd);
reasonActionPhi.addInput(actionAndReason);
speculationPhi.addInput(speculation);
target.replaceAtPredecessor(firstEnd);
exitLoops((AbstractDeoptimizeNode) target, firstEnd, cfg);
merge.setNext(graph.add(new DynamicDeoptimizeNode(reasonActionPhi, speculationPhi)));
obsoletes = new LinkedList<>();
obsoletes.add((AbstractDeoptimizeNode) target);
target = merge;
} else {
merge = (AbstractMergeNode) target;
}
EndNode newEnd = graph.add(new EndNode());
merge.addForwardEnd(newEnd);
reasonActionPhi.addInput(deopt.getActionAndReason(context.getMetaAccess()));
speculationPhi.addInput(deopt.getSpeculation(context.getMetaAccess()));
deopt.replaceAtPredecessor(newEnd);
exitLoops(deopt, newEnd, cfg);
obsoletes.add(deopt);
}
}
if (obsoletes != null) {
((DynamicDeoptimizeNode) ((AbstractMergeNode) target).next()).setStateBefore(fs);
for (AbstractDeoptimizeNode obsolete : obsoletes) {
obsolete.safeDelete();
}
}
}
}
use of org.graalvm.compiler.nodes.AbstractMergeNode in project graal by oracle.
the class PropagateDeoptimizeProbabilityPhase method run.
@Override
@SuppressWarnings("try")
protected void run(final StructuredGraph graph, PhaseContext context) {
assert !graph.hasValueProxies() : "ConvertDeoptimizeToGuardPhase always creates proxies";
if (graph.hasNode(AbstractDeoptimizeNode.TYPE)) {
NodeStack stack = new NodeStack();
EconomicMap<ControlSplitNode, EconomicSet<AbstractBeginNode>> reachableSplits = EconomicMap.create();
// Mark all control flow nodes that are post-dominated by a deoptimization.
for (AbstractDeoptimizeNode d : graph.getNodes(AbstractDeoptimizeNode.TYPE)) {
stack.push(AbstractBeginNode.prevBegin(d));
while (!stack.isEmpty()) {
AbstractBeginNode beginNode = (AbstractBeginNode) stack.pop();
FixedNode fixedNode = (FixedNode) beginNode.predecessor();
if (fixedNode == null) {
// Can happen for start node.
} else if (fixedNode instanceof AbstractMergeNode) {
AbstractMergeNode mergeNode = (AbstractMergeNode) fixedNode;
for (AbstractEndNode end : mergeNode.forwardEnds()) {
AbstractBeginNode newBeginNode = AbstractBeginNode.prevBegin(end);
stack.push(newBeginNode);
}
} else if (fixedNode instanceof ControlSplitNode) {
ControlSplitNode controlSplitNode = (ControlSplitNode) fixedNode;
EconomicSet<AbstractBeginNode> reachableSuccessors = reachableSplits.get(controlSplitNode);
if (reachableSuccessors == null) {
reachableSuccessors = EconomicSet.create();
reachableSplits.put(controlSplitNode, reachableSuccessors);
}
if (controlSplitNode.getSuccessorCount() == reachableSuccessors.size() - 1) {
// All successors of this split lead to deopt, propagate reachability
// further upwards.
reachableSplits.removeKey(controlSplitNode);
stack.push(AbstractBeginNode.prevBegin((FixedNode) controlSplitNode.predecessor()));
} else {
reachableSuccessors.add(beginNode);
}
} else {
stack.push(AbstractBeginNode.prevBegin(fixedNode));
}
}
}
// Make sure the probability on the path towards the deoptimization is 0.0.
MapCursor<ControlSplitNode, EconomicSet<AbstractBeginNode>> entries = reachableSplits.getEntries();
while (entries.advance()) {
ControlSplitNode controlSplitNode = entries.getKey();
EconomicSet<AbstractBeginNode> value = entries.getValue();
for (AbstractBeginNode begin : value) {
double probability = controlSplitNode.probability(begin);
if (probability != 0.0) {
controlSplitNode.setProbability(begin, 0.0);
}
}
}
}
}
Aggregations