use of org.graalvm.compiler.nodes.Invoke in project graal by oracle.
the class ProfileCompiledMethodsPhase method run.
@Override
protected void run(StructuredGraph graph) {
SchedulePhase schedule = new SchedulePhase(graph.getOptions());
schedule.apply(graph, false);
ControlFlowGraph cfg = ControlFlowGraph.compute(graph, true, true, true, true);
for (Loop<Block> loop : cfg.getLoops()) {
double loopProbability = cfg.blockFor(loop.getHeader().getBeginNode()).probability();
if (loopProbability > (1D / Integer.MAX_VALUE)) {
addSectionCounters(loop.getHeader().getBeginNode(), loop.getBlocks(), loop.getChildren(), graph.getLastSchedule(), cfg);
}
}
// don't put the counter increase directly after the start (problems with OSR)
FixedWithNextNode current = graph.start();
while (current.next() instanceof FixedWithNextNode) {
current = (FixedWithNextNode) current.next();
}
addSectionCounters(current, Arrays.asList(cfg.getBlocks()), cfg.getLoops(), graph.getLastSchedule(), cfg);
if (WITH_INVOKES) {
for (Node node : graph.getNodes()) {
if (node instanceof Invoke) {
Invoke invoke = (Invoke) node;
DynamicCounterNode.addCounterBefore(GROUP_NAME_INVOKES, invoke.callTarget().targetName(), 1, true, invoke.asNode());
}
}
}
}
use of org.graalvm.compiler.nodes.Invoke 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.Invoke in project graal by oracle.
the class MultiTypeGuardInlineInfo method inlineMultipleMethods.
private EconomicSet<Node> inlineMultipleMethods(StructuredGraph graph, Providers providers) {
int numberOfMethods = concretes.size();
FixedNode continuation = invoke.next();
// setup merge and phi nodes for results and exceptions
AbstractMergeNode returnMerge = graph.add(new MergeNode());
returnMerge.setStateAfter(invoke.stateAfter());
PhiNode returnValuePhi = null;
if (invoke.asNode().getStackKind() != JavaKind.Void) {
returnValuePhi = graph.addWithoutUnique(new ValuePhiNode(invoke.asNode().stamp(NodeView.DEFAULT).unrestricted(), returnMerge));
}
AbstractMergeNode exceptionMerge = null;
PhiNode exceptionObjectPhi = null;
if (invoke instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invokeWithException = (InvokeWithExceptionNode) invoke;
ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithException.exceptionEdge();
exceptionMerge = graph.add(new MergeNode());
FixedNode exceptionSux = exceptionEdge.next();
graph.addBeforeFixed(exceptionSux, exceptionMerge);
exceptionObjectPhi = graph.addWithoutUnique(new ValuePhiNode(StampFactory.forKind(JavaKind.Object), exceptionMerge));
exceptionMerge.setStateAfter(exceptionEdge.stateAfter().duplicateModified(invoke.stateAfter().bci, true, JavaKind.Object, new JavaKind[] { JavaKind.Object }, new ValueNode[] { exceptionObjectPhi }));
}
// create one separate block for each invoked method
AbstractBeginNode[] successors = new AbstractBeginNode[numberOfMethods + 1];
for (int i = 0; i < numberOfMethods; i++) {
successors[i] = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, true);
}
// create the successor for an unknown type
FixedNode unknownTypeSux;
if (shouldFallbackToInvoke()) {
unknownTypeSux = createInvocationBlock(graph, invoke, returnMerge, returnValuePhi, exceptionMerge, exceptionObjectPhi, false);
} else {
unknownTypeSux = graph.add(new DeoptimizeNode(DeoptimizationAction.InvalidateReprofile, DeoptimizationReason.TypeCheckedInliningViolated));
}
successors[successors.length - 1] = BeginNode.begin(unknownTypeSux);
// replace the invoke exception edge
if (invoke instanceof InvokeWithExceptionNode) {
InvokeWithExceptionNode invokeWithExceptionNode = (InvokeWithExceptionNode) invoke;
ExceptionObjectNode exceptionEdge = (ExceptionObjectNode) invokeWithExceptionNode.exceptionEdge();
exceptionEdge.replaceAtUsages(exceptionObjectPhi);
exceptionEdge.setNext(null);
GraphUtil.killCFG(invokeWithExceptionNode.exceptionEdge());
}
assert invoke.asNode().isAlive();
// replace the invoke with a switch on the type of the actual receiver
boolean methodDispatch = createDispatchOnTypeBeforeInvoke(graph, successors, false, providers.getStampProvider(), providers.getConstantReflection());
assert invoke.next() == continuation;
invoke.setNext(null);
returnMerge.setNext(continuation);
if (returnValuePhi != null) {
invoke.asNode().replaceAtUsages(returnValuePhi);
}
invoke.asNode().safeDelete();
ArrayList<PiNode> replacementNodes = new ArrayList<>();
// prepare the anchors for the invokes
for (int i = 0; i < numberOfMethods; i++) {
AbstractBeginNode node = successors[i];
Invoke invokeForInlining = (Invoke) node.next();
ResolvedJavaType commonType;
if (methodDispatch) {
commonType = concretes.get(i).getDeclaringClass();
} else {
commonType = getLeastCommonType(i);
}
ValueNode receiver = ((MethodCallTargetNode) invokeForInlining.callTarget()).receiver();
boolean exact = (getTypeCount(i) == 1 && !methodDispatch);
PiNode anchoredReceiver = InliningUtil.createAnchoredReceiver(graph, node, commonType, receiver, exact);
invokeForInlining.callTarget().replaceFirstInput(receiver, anchoredReceiver);
assert !anchoredReceiver.isDeleted() : anchoredReceiver;
replacementNodes.add(anchoredReceiver);
}
if (shouldFallbackToInvoke()) {
replacementNodes.add(null);
}
EconomicSet<Node> canonicalizeNodes = EconomicSet.create(Equivalence.DEFAULT);
// do the actual inlining for every invoke
for (int i = 0; i < numberOfMethods; i++) {
Invoke invokeForInlining = (Invoke) successors[i].next();
canonicalizeNodes.addAll(doInline(i, invokeForInlining));
}
if (returnValuePhi != null) {
canonicalizeNodes.add(returnValuePhi);
}
return canonicalizeNodes;
}
use of org.graalvm.compiler.nodes.Invoke in project graal by oracle.
the class MacroStateSplitNode method replaceSnippetInvokes.
protected void replaceSnippetInvokes(StructuredGraph snippetGraph) {
for (MethodCallTargetNode call : snippetGraph.getNodes(MethodCallTargetNode.TYPE)) {
Invoke invoke = call.invoke();
if (!call.targetMethod().equals(getTargetMethod())) {
throw new GraalError("unexpected invoke %s in snippet", getClass().getSimpleName());
}
assert invoke.stateAfter().bci == BytecodeFrame.AFTER_BCI;
// Here we need to fix the bci of the invoke
InvokeNode newInvoke = snippetGraph.add(new InvokeNode(invoke.callTarget(), bci()));
newInvoke.setStateAfter(invoke.stateAfter());
snippetGraph.replaceFixedWithFixed((InvokeNode) invoke.asNode(), newInvoke);
}
}
use of org.graalvm.compiler.nodes.Invoke in project graal by oracle.
the class RuntimeStrengthenStampsPhase method registerDeoptEntries.
private static void registerDeoptEntries(CallTreeNode node) {
for (FrameState frameState : node.graph.getNodes(FrameState.TYPE)) {
if (node.level > 0 && frameState.usages().count() == 1 && frameState.usages().first() == node.graph.start()) {
/*
* During method inlining, the FrameState associated with the StartNode disappears.
* Therefore, this frame state cannot be a deoptimization target.
*/
continue;
}
/*
* We need to make sure that all inlined caller frames are available for deoptimization
* too.
*/
for (FrameState inlineState = frameState; inlineState != null; inlineState = inlineState.outerFrameState()) {
if (inlineState.bci >= 0) {
CompilationInfoSupport.singleton().registerDeoptEntry(inlineState.getMethod(), inlineState.bci, inlineState.duringCall(), inlineState.rethrowException());
}
}
}
for (Node n : node.graph.getNodes()) {
/*
* graph.getInvokes() only iterates invokes that have a MethodCallTarget, so by using it
* we would miss invocations that are already intrinsified to an indirect call.
*/
if (n instanceof Invoke) {
Invoke invoke = (Invoke) n;
/*
* The FrameState for the invoke (which is visited by the above loop) is the state
* after the call (where deoptimization that happens after the call has returned
* will continue execution). We also need to register the state during the call
* (where deoptimization while the call is on the stack will continue execution).
*
* Note that the bci of the Invoke and the bci of the FrameState of the Invoke are
* different: the Invoke has the bci of the invocation bytecode, the FrameState has
* the bci of the next bytecode after the invoke.
*/
CompilationInfoSupport.singleton().registerDeoptEntry(invoke.stateAfter().getMethod(), invoke.bci(), true, false);
}
}
}
Aggregations