use of org.graalvm.compiler.nodes.DeoptimizingNode in project graal by oracle.
the class SnippetTemplate method instantiate.
/**
* Replaces a given fixed node with this specialized snippet.
*
* @param metaAccess
* @param replacee the node that will be replaced
* @param replacer object that replaces the usages of {@code replacee}
* @param args the arguments to be bound to the flattened positional parameters of the snippet
* @param killReplacee is true, the replacee node is deleted
* @return the map of duplicated nodes (original -> duplicate)
*/
@SuppressWarnings("try")
public UnmodifiableEconomicMap<Node, Node> instantiate(MetaAccessProvider metaAccess, FixedNode replacee, UsageReplacer replacer, Arguments args, boolean killReplacee) {
DebugContext debug = replacee.getDebug();
assert assertSnippetKills(replacee);
try (DebugCloseable a = args.info.instantiationTimer.start(debug)) {
args.info.instantiationCounter.increment(debug);
// Inline the snippet nodes, replacing parameters with the given args in the process
StartNode entryPointNode = snippet.start();
FixedNode firstCFGNode = entryPointNode.next();
StructuredGraph replaceeGraph = replacee.graph();
EconomicMap<Node, Node> replacements = bind(replaceeGraph, metaAccess, args);
replacements.put(entryPointNode, AbstractBeginNode.prevBegin(replacee));
UnmodifiableEconomicMap<Node, Node> duplicates = inlineSnippet(replacee, debug, replaceeGraph, replacements);
// Re-wire the control flow graph around the replacee
FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
replacee.replaceAtPredecessor(firstCFGNodeDuplicate);
rewireFrameStates(replacee, duplicates);
if (replacee instanceof DeoptimizingNode) {
DeoptimizingNode replaceeDeopt = (DeoptimizingNode) replacee;
FrameState stateBefore = null;
FrameState stateDuring = null;
FrameState stateAfter = null;
if (replaceeDeopt.canDeoptimize()) {
if (replaceeDeopt instanceof DeoptimizingNode.DeoptBefore) {
stateBefore = ((DeoptimizingNode.DeoptBefore) replaceeDeopt).stateBefore();
}
if (replaceeDeopt instanceof DeoptimizingNode.DeoptDuring) {
stateDuring = ((DeoptimizingNode.DeoptDuring) replaceeDeopt).stateDuring();
}
if (replaceeDeopt instanceof DeoptimizingNode.DeoptAfter) {
stateAfter = ((DeoptimizingNode.DeoptAfter) replaceeDeopt).stateAfter();
}
}
for (DeoptimizingNode deoptNode : deoptNodes) {
DeoptimizingNode deoptDup = (DeoptimizingNode) duplicates.get(deoptNode.asNode());
if (deoptDup.canDeoptimize()) {
if (deoptDup instanceof DeoptimizingNode.DeoptBefore) {
((DeoptimizingNode.DeoptBefore) deoptDup).setStateBefore(stateBefore);
}
if (deoptDup instanceof DeoptimizingNode.DeoptDuring) {
DeoptimizingNode.DeoptDuring deoptDupDuring = (DeoptimizingNode.DeoptDuring) deoptDup;
if (stateDuring != null) {
deoptDupDuring.setStateDuring(stateDuring);
} else if (stateAfter != null) {
deoptDupDuring.computeStateDuring(stateAfter);
} else if (stateBefore != null) {
assert !deoptDupDuring.hasSideEffect() : "can't use stateBefore as stateDuring for state split " + deoptDupDuring;
deoptDupDuring.setStateDuring(stateBefore);
}
}
if (deoptDup instanceof DeoptimizingNode.DeoptAfter) {
DeoptimizingNode.DeoptAfter deoptDupAfter = (DeoptimizingNode.DeoptAfter) deoptDup;
if (stateAfter != null) {
deoptDupAfter.setStateAfter(stateAfter);
} else {
assert !deoptDupAfter.hasSideEffect() : "can't use stateBefore as stateAfter for state split " + deoptDupAfter;
deoptDupAfter.setStateAfter(stateBefore);
}
}
}
}
}
updateStamps(replacee, duplicates);
rewireMemoryGraph(replacee, duplicates);
// Replace all usages of the replacee with the value returned by the snippet
ValueNode returnValue = null;
if (returnNode != null && !(replacee instanceof ControlSinkNode)) {
ReturnNode returnDuplicate = (ReturnNode) duplicates.get(returnNode);
returnValue = returnDuplicate.result();
if (returnValue == null && replacee.usages().isNotEmpty() && replacee instanceof MemoryCheckpoint) {
replacer.replace(replacee, null);
} else {
assert returnValue != null || replacee.hasNoUsages();
replacer.replace(replacee, returnValue);
}
if (returnDuplicate.isAlive()) {
FixedNode next = null;
if (replacee instanceof FixedWithNextNode) {
FixedWithNextNode fwn = (FixedWithNextNode) replacee;
next = fwn.next();
fwn.setNext(null);
}
returnDuplicate.replaceAndDelete(next);
}
}
if (killReplacee) {
// Remove the replacee from its graph
GraphUtil.killCFG(replacee);
}
debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After lowering %s with %s", replacee, this);
return duplicates;
}
}
Aggregations