use of org.graalvm.compiler.nodes.cfg.ControlFlowGraph in project graal by oracle.
the class ReentrantBlockIteratorTest method getVisitedBlocksInOrder.
private List<Block> getVisitedBlocksInOrder(String snippet) {
StructuredGraph graph = parseEager(snippet, AllowAssumptions.YES);
// after FSA to ensure HIR loop data structure does not contain loop exits
graph.setGuardsStage(GuardsStage.AFTER_FSA);
ArrayList<Block> blocks = new ArrayList<>();
class VoidState {
}
final VoidState voidState = new VoidState();
BlockIteratorClosure<VoidState> closure = new BlockIteratorClosure<VoidState>() {
@Override
protected VoidState getInitialState() {
return voidState;
}
@Override
protected VoidState processBlock(Block block, VoidState currentState) {
// remember the visit order
blocks.add(block);
return currentState;
}
@Override
protected VoidState merge(Block merge, List<VoidState> states) {
return voidState;
}
@Override
protected VoidState cloneState(VoidState oldState) {
return voidState;
}
@Override
protected List<VoidState> processLoop(Loop<Block> loop, VoidState initialState) {
return ReentrantBlockIterator.processLoop(this, loop, initialState).exitStates;
}
};
ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, false);
ReentrantBlockIterator.apply(closure, cfg.getStartBlock());
// schedule for IGV
new SchedulePhase(graph.getOptions()).apply(graph);
return blocks;
}
use of org.graalvm.compiler.nodes.cfg.ControlFlowGraph in project graal by oracle.
the class SimpleCFGTest method testImplies.
@Test
public void testImplies() {
OptionValues options = getInitialOptions();
DebugContext debug = DebugContext.create(options, new GraalDebugHandlersFactory(getSnippetReflection()));
StructuredGraph graph = new StructuredGraph.Builder(options, debug, AllowAssumptions.YES).build();
EndNode trueEnd = graph.add(new EndNode());
EndNode falseEnd = graph.add(new EndNode());
AbstractBeginNode trueBegin = graph.add(new BeginNode());
trueBegin.setNext(trueEnd);
AbstractBeginNode falseBegin = graph.add(new BeginNode());
falseBegin.setNext(falseEnd);
IfNode ifNode = graph.add(new IfNode(null, trueBegin, falseBegin, 0.5));
graph.start().setNext(ifNode);
AbstractMergeNode merge = graph.add(new MergeNode());
merge.addForwardEnd(trueEnd);
merge.addForwardEnd(falseEnd);
ReturnNode returnNode = graph.add(new ReturnNode(null));
merge.setNext(returnNode);
dumpGraph(graph);
ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
Block[] blocks = cfg.getBlocks();
// check number of blocks
assertDeepEquals(4, blocks.length);
// check block - node assignment
assertDeepEquals(blocks[0], cfg.blockFor(graph.start()));
assertDeepEquals(blocks[0], cfg.blockFor(ifNode));
assertDeepEquals(blocks[1], cfg.blockFor(trueBegin));
assertDeepEquals(blocks[1], cfg.blockFor(trueEnd));
assertDeepEquals(blocks[2], cfg.blockFor(falseBegin));
assertDeepEquals(blocks[2], cfg.blockFor(falseEnd));
assertDeepEquals(blocks[3], cfg.blockFor(merge));
assertDeepEquals(blocks[3], cfg.blockFor(returnNode));
// check dominators
assertDominator(blocks[0], null);
assertDominator(blocks[1], blocks[0]);
assertDominator(blocks[2], blocks[0]);
assertDominator(blocks[3], blocks[0]);
// check dominated
assertDominatedSize(blocks[0], 3);
assertDominatedSize(blocks[1], 0);
assertDominatedSize(blocks[2], 0);
assertDominatedSize(blocks[3], 0);
// check postdominators
assertPostdominator(blocks[0], blocks[3]);
assertPostdominator(blocks[1], blocks[3]);
assertPostdominator(blocks[2], blocks[3]);
assertPostdominator(blocks[3], null);
}
use of org.graalvm.compiler.nodes.cfg.ControlFlowGraph in project graal by oracle.
the class LoopEx method nodesInLoopBranch.
public void nodesInLoopBranch(NodeBitMap branchNodes, AbstractBeginNode branch) {
EconomicSet<AbstractBeginNode> blocks = EconomicSet.create();
Collection<AbstractBeginNode> exits = new LinkedList<>();
Queue<Block> work = new LinkedList<>();
ControlFlowGraph cfg = loopsData().getCFG();
work.add(cfg.blockFor(branch));
while (!work.isEmpty()) {
Block b = work.remove();
if (loop().getExits().contains(b)) {
assert !exits.contains(b.getBeginNode());
exits.add(b.getBeginNode());
} else if (blocks.add(b.getBeginNode())) {
Block d = b.getDominatedSibling();
while (d != null) {
if (loop.getBlocks().contains(d)) {
work.add(d);
}
d = d.getDominatedSibling();
}
}
}
LoopFragment.computeNodes(branchNodes, branch.graph(), blocks, exits);
}
use of org.graalvm.compiler.nodes.cfg.ControlFlowGraph 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.cfg.ControlFlowGraph in project graal by oracle.
the class NodeCostUtil method computeGraphCycles.
@SuppressWarnings("try")
public static double computeGraphCycles(StructuredGraph graph, boolean fullSchedule) {
Function<Block, Iterable<? extends Node>> blockToNodes;
ControlFlowGraph cfg;
if (fullSchedule) {
SchedulePhase schedule = new SchedulePhase(SchedulePhase.SchedulingStrategy.LATEST_OUT_OF_LOOPS, true);
schedule.apply(graph);
cfg = graph.getLastSchedule().getCFG();
blockToNodes = b -> graph.getLastSchedule().getBlockToNodesMap().get(b);
} else {
cfg = ControlFlowGraph.compute(graph, true, true, false, false);
BlockMap<List<FixedNode>> nodes = new BlockMap<>(cfg);
for (Block b : cfg.getBlocks()) {
ArrayList<FixedNode> curNodes = new ArrayList<>();
for (FixedNode node : b.getNodes()) {
curNodes.add(node);
}
nodes.put(b, curNodes);
}
blockToNodes = b -> nodes.get(b);
}
double weightedCycles = 0D;
DebugContext debug = graph.getDebug();
try (DebugContext.Scope s = debug.scope("NodeCostSummary")) {
for (Block block : cfg.getBlocks()) {
for (Node n : blockToNodes.apply(block)) {
double probWeighted = n.estimatedNodeCycles().value * block.probability();
assert Double.isFinite(probWeighted);
weightedCycles += probWeighted;
if (debug.isLogEnabled()) {
debug.log("Node %s contributes cycles:%f size:%d to graph %s [block prob:%f]", n, n.estimatedNodeCycles().value * block.probability(), n.estimatedNodeSize().value, graph, block.probability());
}
}
}
}
assert weightedCycles >= 0D;
assert Double.isFinite(weightedCycles);
return weightedCycles;
}
Aggregations