use of org.graalvm.compiler.nodes.BeginNode in project graal by oracle.
the class InliningUtil method finishInlining.
private static ValueNode finishInlining(Invoke invoke, StructuredGraph graph, FixedNode firstNode, List<ReturnNode> returnNodes, UnwindNode unwindNode, Assumptions inlinedAssumptions, StructuredGraph inlineGraph) {
FixedNode invokeNode = invoke.asNode();
FrameState stateAfter = invoke.stateAfter();
assert stateAfter == null || stateAfter.isAlive();
invokeNode.replaceAtPredecessor(firstNode);
if (invoke instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invokeWithException = ((InvokeWithExceptionNode) invoke);
if (unwindNode != null && unwindNode.isAlive()) {
assert unwindNode.predecessor() != null;
assert invokeWithException.exceptionEdge().successors().count() == 1;
ExceptionObjectNode obj = (ExceptionObjectNode) invokeWithException.exceptionEdge();
obj.replaceAtUsages(unwindNode.exception());
Node n = obj.next();
obj.setNext(null);
unwindNode.replaceAndDelete(n);
obj.replaceAtPredecessor(null);
obj.safeDelete();
} else {
invokeWithException.killExceptionEdge();
}
// get rid of memory kill
AbstractBeginNode begin = invokeWithException.next();
if (begin instanceof KillingBeginNode) {
AbstractBeginNode newBegin = new BeginNode();
graph.addAfterFixed(begin, graph.add(newBegin));
begin.replaceAtUsages(newBegin);
graph.removeFixed(begin);
}
} else {
if (unwindNode != null && unwindNode.isAlive()) {
DeoptimizeNode deoptimizeNode = addDeoptimizeNode(graph, DeoptimizationAction.InvalidateRecompile, DeoptimizationReason.NotCompiledExceptionHandler);
unwindNode.replaceAndDelete(deoptimizeNode);
}
}
ValueNode returnValue;
if (!returnNodes.isEmpty()) {
FixedNode n = invoke.next();
invoke.setNext(null);
if (returnNodes.size() == 1) {
ReturnNode returnNode = returnNodes.get(0);
returnValue = returnNode.result();
invokeNode.replaceAtUsages(returnValue);
returnNode.replaceAndDelete(n);
} else {
MergeNode merge = graph.add(new MergeNode());
merge.setStateAfter(stateAfter);
returnValue = mergeReturns(merge, returnNodes);
invokeNode.replaceAtUsages(returnValue);
if (merge.isPhiAtMerge(returnValue)) {
fixFrameStates(graph, merge, (PhiNode) returnValue);
}
merge.setNext(n);
}
} else {
returnValue = null;
invokeNode.replaceAtUsages(null);
GraphUtil.killCFG(invoke.next());
}
// Copy assumptions from inlinee to caller
Assumptions assumptions = graph.getAssumptions();
if (assumptions != null) {
if (inlinedAssumptions != null) {
assumptions.record(inlinedAssumptions);
}
} else {
assert inlinedAssumptions == null : String.format("cannot inline graph (%s) which makes assumptions into a graph (%s) that doesn't", inlineGraph, graph);
}
// Copy inlined methods from inlinee to caller
graph.updateMethods(inlineGraph);
// Update the set of accessed fields
if (GraalOptions.GeneratePIC.getValue(graph.getOptions())) {
graph.updateFields(inlineGraph);
}
if (inlineGraph.hasUnsafeAccess()) {
graph.markUnsafeAccess();
}
assert inlineGraph.getSpeculationLog() == null || inlineGraph.getSpeculationLog() == graph.getSpeculationLog() : "Only the root graph should have a speculation log";
return returnValue;
}
use of org.graalvm.compiler.nodes.BeginNode in project graal by oracle.
the class MultiTypeGuardInlineInfo method createInvocationBlock.
private static AbstractBeginNode createInvocationBlock(StructuredGraph graph, Invoke invoke, AbstractMergeNode returnMerge, PhiNode returnValuePhi, AbstractMergeNode exceptionMerge, PhiNode exceptionObjectPhi, boolean useForInlining) {
Invoke duplicatedInvoke = duplicateInvokeForInlining(graph, invoke, exceptionMerge, exceptionObjectPhi, useForInlining);
AbstractBeginNode calleeEntryNode = graph.add(new BeginNode());
calleeEntryNode.setNext(duplicatedInvoke.asNode());
EndNode endNode = graph.add(new EndNode());
duplicatedInvoke.setNext(endNode);
returnMerge.addForwardEnd(endNode);
if (returnValuePhi != null) {
returnValuePhi.addInput(duplicatedInvoke.asNode());
}
return calleeEntryNode;
}
use of org.graalvm.compiler.nodes.BeginNode in project graal by oracle.
the class OptimizeExceptionCallsPhase method setBranchProbability.
/**
* Sets the branch probability of the guarding IfNode to a small value. The effect is that the
* exception call block is put at the end of the method. The other block (= the regular path)
* gets the fall-through block of the IfNode. This should give a better performance - and it
* looks nicer in the disassembly.
*/
private static void setBranchProbability(Node endNode) {
Node node = endNode;
Node predecessor = node.predecessor();
// Go "up" the graph until we find an IfNode
while (predecessor != null) {
if (predecessor instanceof IfNode && node instanceof BeginNode) {
// We found an IfNode which branches to our runtime exception call
IfNode ifNode = (IfNode) predecessor;
ifNode.setTrueSuccessorProbability(node == ifNode.trueSuccessor() ? 0.00001 : 0.99999);
return;
}
if (predecessor instanceof MergeNode || predecessor instanceof ControlSplitNode) {
// Any other split or merge is suspicious: we abort
return;
}
node = predecessor;
predecessor = node.predecessor();
}
}
use of org.graalvm.compiler.nodes.BeginNode 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.BeginNode in project graal by oracle.
the class BytecodeParser method emitExplicitBoundsCheck.
protected void emitExplicitBoundsCheck(ValueNode index, ValueNode length) {
AbstractBeginNode trueSucc = graph.add(new BeginNode());
BytecodeExceptionNode exception = graph.add(new BytecodeExceptionNode(metaAccess, ArrayIndexOutOfBoundsException.class, index));
append(new IfNode(genUnique(IntegerBelowNode.create(constantReflection, metaAccess, options, null, index, length, NodeView.DEFAULT)), trueSucc, exception, FAST_PATH_PROBABILITY));
lastInstr = trueSucc;
exception.setStateAfter(createFrameState(bci(), exception));
exception.setNext(handleException(exception, bci(), false));
}
Aggregations