use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.
the class GraalCompiler method emitLIR0.
@SuppressWarnings("try")
private static LIRGenerationResult emitLIR0(Backend backend, StructuredGraph graph, Object stub, RegisterConfig registerConfig, LIRSuites lirSuites, String[] allocationRestrictedTo) {
DebugContext debug = graph.getDebug();
try (DebugContext.Scope ds = debug.scope("EmitLIR");
DebugCloseable a = EmitLIR.start(debug)) {
assert !graph.hasValueProxies();
ScheduleResult schedule = graph.getLastSchedule();
Block[] blocks = schedule.getCFG().getBlocks();
Block startBlock = schedule.getCFG().getStartBlock();
assert startBlock != null;
assert startBlock.getPredecessorCount() == 0;
AbstractBlockBase<?>[] codeEmittingOrder = ComputeBlockOrder.computeCodeEmittingOrder(blocks.length, startBlock);
AbstractBlockBase<?>[] linearScanOrder = ComputeBlockOrder.computeLinearScanOrder(blocks.length, startBlock);
LIR lir = new LIR(schedule.getCFG(), linearScanOrder, codeEmittingOrder, graph.getOptions(), graph.getDebug());
FrameMapBuilder frameMapBuilder = backend.newFrameMapBuilder(registerConfig);
LIRGenerationResult lirGenRes = backend.newLIRGenerationResult(graph.compilationId(), lir, frameMapBuilder, graph, stub);
LIRGeneratorTool lirGen = backend.newLIRGenerator(lirGenRes);
NodeLIRBuilderTool nodeLirGen = backend.newNodeLIRBuilder(graph, lirGen);
// LIR generation
LIRGenerationContext context = new LIRGenerationContext(lirGen, nodeLirGen, graph, schedule);
new LIRGenerationPhase().apply(backend.getTarget(), lirGenRes, context);
try (DebugContext.Scope s = debug.scope("LIRStages", nodeLirGen, lirGenRes, lir)) {
// Dump LIR along with HIR (the LIR is looked up from context)
debug.dump(DebugContext.BASIC_LEVEL, graph.getLastSchedule(), "After LIR generation");
LIRGenerationResult result = emitLowLevel(backend.getTarget(), lirGenRes, lirGen, lirSuites, backend.newRegisterAllocationConfig(registerConfig, allocationRestrictedTo));
return result;
} catch (Throwable e) {
throw debug.handle(e);
}
} catch (Throwable e) {
throw debug.handle(e);
} finally {
graph.checkCancellation();
}
}
use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.
the class DefaultLoopPolicies method shouldUnswitch.
@Override
public boolean shouldUnswitch(LoopEx loop, List<ControlSplitNode> controlSplits) {
int phis = 0;
StructuredGraph graph = loop.loopBegin().graph();
DebugContext debug = graph.getDebug();
NodeBitMap branchNodes = graph.createNodeBitMap();
for (ControlSplitNode controlSplit : controlSplits) {
for (Node successor : controlSplit.successors()) {
AbstractBeginNode branch = (AbstractBeginNode) successor;
// this may count twice because of fall-through in switches
loop.nodesInLoopBranch(branchNodes, branch);
}
Block postDomBlock = loop.loopsData().getCFG().blockFor(controlSplit).getPostdominator();
if (postDomBlock != null) {
IsolatedInitialization.UNSWITCH_SPLIT_WITH_PHIS.increment(debug);
phis += ((MergeNode) postDomBlock.getBeginNode()).phis().count();
}
}
int inBranchTotal = branchNodes.count();
CountingClosure stateNodesCount = new CountingClosure();
double loopFrequency = loop.loopBegin().loopFrequency();
OptionValues options = loop.loopBegin().getOptions();
int maxDiff = Options.LoopUnswitchTrivial.getValue(options) + (int) (Options.LoopUnswitchFrequencyBoost.getValue(options) * (loopFrequency - 1.0 + phis));
maxDiff = Math.min(maxDiff, Options.LoopUnswitchMaxIncrease.getValue(options));
int remainingGraphSpace = MaximumDesiredSize.getValue(options) - graph.getNodeCount();
maxDiff = Math.min(maxDiff, remainingGraphSpace);
loop.loopBegin().stateAfter().applyToVirtual(stateNodesCount);
int loopTotal = loop.size() - loop.loopBegin().phis().count() - stateNodesCount.count - 1;
int actualDiff = (loopTotal - inBranchTotal);
ControlSplitNode firstSplit = controlSplits.get(0);
if (firstSplit instanceof TypeSwitchNode) {
int copies = firstSplit.successors().count() - 1;
for (Node succ : firstSplit.successors()) {
FixedNode current = (FixedNode) succ;
while (current instanceof FixedWithNextNode) {
current = ((FixedWithNextNode) current).next();
}
if (current instanceof DeoptimizeNode) {
copies--;
}
}
actualDiff = actualDiff * copies;
}
debug.log("shouldUnswitch(%s, %s) : delta=%d (%.2f%% inside of branches), max=%d, f=%.2f, phis=%d -> %b", loop, controlSplits, actualDiff, (double) (inBranchTotal) / loopTotal * 100, maxDiff, loopFrequency, phis, actualDiff <= maxDiff);
if (actualDiff <= maxDiff) {
// check whether we're allowed to unswitch this loop
return loop.canDuplicateLoop();
} else {
return false;
}
}
use of org.graalvm.compiler.nodes.cfg.Block in project graal by oracle.
the class LoopFragmentWhole method cleanupLoopExits.
void cleanupLoopExits() {
LoopBeginNode loopBegin = original().loop().loopBegin();
assert nodes == null || nodes.contains(loopBegin);
StructuredGraph graph = loopBegin.graph();
if (graph.getGuardsStage() == StructuredGraph.GuardsStage.AFTER_FSA) {
// After FrameStateAssignment ControlFlowGraph treats loop exits differently which means
// that the LoopExitNodes can be in a block which post dominates the true loop exit. For
// cloning to work right they must agree.
EconomicSet<LoopExitNode> exits = EconomicSet.create();
for (Block exitBlock : original().loop().loop().getExits()) {
LoopExitNode exitNode = exitBlock.getLoopExit();
if (exitNode == null) {
exitNode = graph.add(new LoopExitNode(loopBegin));
graph.addAfterFixed(exitBlock.getBeginNode(), exitNode);
if (nodes != null) {
nodes.mark(exitNode);
}
graph.getDebug().dump(DebugContext.VERBOSE_LEVEL, graph, "Adjusting loop exit node for %s", loopBegin);
}
exits.add(exitNode);
}
for (LoopExitNode exitNode : loopBegin.loopExits()) {
if (!exits.contains(exitNode)) {
if (nodes != null) {
nodes.clear(exitNode);
}
graph.removeFixed(exitNode);
}
}
}
}
use of org.graalvm.compiler.nodes.cfg.Block 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.Block 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));
}
}
}
}
Aggregations