use of org.graalvm.compiler.nodes.ControlSplitNode in project graal by oracle.
the class LoopTransformations method unswitch.
public static void unswitch(LoopEx loop, List<ControlSplitNode> controlSplitNodeSet) {
ControlSplitNode firstNode = controlSplitNodeSet.iterator().next();
LoopFragmentWhole originalLoop = loop.whole();
StructuredGraph graph = firstNode.graph();
loop.loopBegin().incrementUnswitches();
// create new control split out of loop
ControlSplitNode newControlSplit = (ControlSplitNode) firstNode.copyWithInputs();
originalLoop.entryPoint().replaceAtPredecessor(newControlSplit);
/*
* The code below assumes that all of the control split nodes have the same successor
* structure, which should have been enforced by findUnswitchable.
*/
Iterator<Position> successors = firstNode.successorPositions().iterator();
assert successors.hasNext();
// original loop is used as first successor
Position firstPosition = successors.next();
AbstractBeginNode originalLoopBegin = BeginNode.begin(originalLoop.entryPoint());
firstPosition.set(newControlSplit, originalLoopBegin);
while (successors.hasNext()) {
Position position = successors.next();
// create a new loop duplicate and connect it.
LoopFragmentWhole duplicateLoop = originalLoop.duplicate();
AbstractBeginNode newBegin = BeginNode.begin(duplicateLoop.entryPoint());
position.set(newControlSplit, newBegin);
// For each cloned ControlSplitNode, simplify the proper path
for (ControlSplitNode controlSplitNode : controlSplitNodeSet) {
ControlSplitNode duplicatedControlSplit = duplicateLoop.getDuplicatedNode(controlSplitNode);
if (duplicatedControlSplit.isAlive()) {
AbstractBeginNode survivingSuccessor = (AbstractBeginNode) position.get(duplicatedControlSplit);
survivingSuccessor.replaceAtUsages(InputType.Guard, newBegin);
graph.removeSplitPropagate(duplicatedControlSplit, survivingSuccessor);
}
}
}
// original loop is simplified last to avoid deleting controlSplitNode too early
for (ControlSplitNode controlSplitNode : controlSplitNodeSet) {
if (controlSplitNode.isAlive()) {
AbstractBeginNode survivingSuccessor = (AbstractBeginNode) firstPosition.get(controlSplitNode);
survivingSuccessor.replaceAtUsages(InputType.Guard, originalLoopBegin);
graph.removeSplitPropagate(controlSplitNode, survivingSuccessor);
}
}
// TODO (gd) probabilities need some amount of fixup.. (probably also in other transforms)
}
use of org.graalvm.compiler.nodes.ControlSplitNode in project graal by oracle.
the class BinaryGraphPrinter method nodeProperties.
@Override
@SuppressWarnings({ "unchecked", "rawtypes" })
public void nodeProperties(GraphInfo info, Node node, Map<String, Object> props) {
node.getDebugProperties((Map) props);
Graph graph = info.graph;
ControlFlowGraph cfg = info.cfg;
NodeMap<Block> nodeToBlocks = info.nodeToBlocks;
if (cfg != null && DebugOptions.PrintGraphProbabilities.getValue(graph.getOptions()) && node instanceof FixedNode) {
try {
props.put("probability", cfg.blockFor(node).probability());
} catch (Throwable t) {
props.put("probability", 0.0);
props.put("probability-exception", t);
}
}
try {
props.put("NodeCost-Size", node.estimatedNodeSize());
props.put("NodeCost-Cycles", node.estimatedNodeCycles());
} catch (Throwable t) {
props.put("node-cost-exception", t.getMessage());
}
if (nodeToBlocks != null) {
Object block = getBlockForNode(node, nodeToBlocks);
if (block != null) {
props.put("node-to-block", block);
}
}
if (node instanceof ControlSinkNode) {
props.put("category", "controlSink");
} else if (node instanceof ControlSplitNode) {
props.put("category", "controlSplit");
} else if (node instanceof AbstractMergeNode) {
props.put("category", "merge");
} else if (node instanceof AbstractBeginNode) {
props.put("category", "begin");
} else if (node instanceof AbstractEndNode) {
props.put("category", "end");
} else if (node instanceof FixedNode) {
props.put("category", "fixed");
} else if (node instanceof VirtualState) {
props.put("category", "state");
} else if (node instanceof PhiNode) {
props.put("category", "phi");
} else if (node instanceof ProxyNode) {
props.put("category", "proxy");
} else {
if (node instanceof ConstantNode) {
ConstantNode cn = (ConstantNode) node;
updateStringPropertiesForConstant((Map) props, cn);
}
props.put("category", "floating");
}
if (getSnippetReflectionProvider() != null) {
for (Map.Entry<String, Object> prop : props.entrySet()) {
if (prop.getValue() instanceof JavaConstantFormattable) {
props.put(prop.getKey(), ((JavaConstantFormattable) prop.getValue()).format(this));
}
}
}
}
use of org.graalvm.compiler.nodes.ControlSplitNode in project graal by oracle.
the class PostOrderNodeIterator method apply.
public void apply() {
FixedNode current = start;
do {
if (current instanceof InvokeWithExceptionNode) {
invoke((Invoke) current);
queueSuccessors(current, null);
current = nextQueuedNode();
} else if (current instanceof LoopBeginNode) {
state.loopBegin((LoopBeginNode) current);
nodeStates.put(current, state);
state = state.clone();
loopBegin((LoopBeginNode) current);
current = ((LoopBeginNode) current).next();
assert current != null;
} else if (current instanceof LoopEndNode) {
loopEnd((LoopEndNode) current);
finishLoopEnds((LoopEndNode) current);
current = nextQueuedNode();
} else if (current instanceof AbstractMergeNode) {
merge((AbstractMergeNode) current);
current = ((AbstractMergeNode) current).next();
assert current != null;
} else if (current instanceof FixedWithNextNode) {
FixedNode next = ((FixedWithNextNode) current).next();
assert next != null : current;
node(current);
current = next;
} else if (current instanceof EndNode) {
end((EndNode) current);
queueMerge((EndNode) current);
current = nextQueuedNode();
} else if (current instanceof ControlSinkNode) {
node(current);
current = nextQueuedNode();
} else if (current instanceof ControlSplitNode) {
Set<Node> successors = controlSplit((ControlSplitNode) current);
queueSuccessors(current, successors);
current = nextQueuedNode();
} else {
assert false : current;
}
} while (current != null);
finished();
}
use of org.graalvm.compiler.nodes.ControlSplitNode in project graal by oracle.
the class ComputeInliningRelevance method computeFastPathMinProbability.
/**
* Computes the minimum probability along the most probable path within the scope. During
* iteration, the method returns immediately once a loop exit is discovered.
*/
private double computeFastPathMinProbability(FixedNode scopeStart) {
ArrayList<FixedNode> pathBeginNodes = new ArrayList<>();
pathBeginNodes.add(scopeStart);
double minPathProbability = nodeProbabilities.applyAsDouble(scopeStart);
boolean isLoopScope = scopeStart instanceof LoopBeginNode;
do {
Node current = pathBeginNodes.remove(pathBeginNodes.size() - 1);
do {
if (isLoopScope && current instanceof LoopExitNode && ((LoopBeginNode) scopeStart).loopExits().contains((LoopExitNode) current)) {
return minPathProbability;
} else if (current instanceof LoopBeginNode && current != scopeStart) {
current = getMaxProbabilityLoopExit((LoopBeginNode) current, pathBeginNodes);
minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability);
} else if (current instanceof ControlSplitNode) {
current = getMaxProbabilitySux((ControlSplitNode) current, pathBeginNodes);
minPathProbability = getMinPathProbability((FixedNode) current, minPathProbability);
} else {
assert current.successors().count() <= 1;
current = current.successors().first();
}
} while (current != null);
} while (!pathBeginNodes.isEmpty());
return minPathProbability;
}
use of org.graalvm.compiler.nodes.ControlSplitNode in project graal by oracle.
the class FixedNodeProbabilityCache method findBegin.
private static FixedNode findBegin(FixedNode node) {
FixedNode current = node;
while (true) {
assert current != null;
Node predecessor = current.predecessor();
if (current instanceof AbstractBeginNode) {
if (predecessor == null) {
break;
} else if (predecessor.successors().count() != 1) {
assert predecessor instanceof ControlSplitNode : "a FixedNode with multiple successors needs to be a ControlSplitNode: " + current + " / " + predecessor;
break;
}
} else if (predecessor == null) {
current = null;
break;
}
current = (FixedNode) predecessor;
}
return current;
}
Aggregations