use of org.graalvm.compiler.graph.Graph.Mark in project graal by oracle.
the class LoweringPhase method checkPostLowering.
/**
* Checks that second lowering of a given graph did not introduce any new nodes.
*
* @param graph a graph that was just {@linkplain #lower lowered}
* @throws AssertionError if the check fails
*/
private boolean checkPostLowering(StructuredGraph graph, PhaseContext context) {
Mark expectedMark = graph.getMark();
lower(graph, context, LoweringMode.VERIFY_LOWERING);
Mark mark = graph.getMark();
assert mark.equals(expectedMark) : graph + ": a second round in the current lowering phase introduced these new nodes: " + graph.getNewNodes(expectedMark).snapshot();
return true;
}
use of org.graalvm.compiler.graph.Graph.Mark in project graal by oracle.
the class SnippetTemplate method inlineSnippet.
private UnmodifiableEconomicMap<Node, Node> inlineSnippet(Node replacee, DebugContext debug, StructuredGraph replaceeGraph, EconomicMap<Node, Node> replacements) {
Mark mark = replaceeGraph.getMark();
try (InliningLog.UpdateScope scope = replaceeGraph.getInliningLog().openUpdateScope((oldNode, newNode) -> {
InliningLog log = replaceeGraph.getInliningLog();
if (oldNode == null) {
log.trackNewCallsite(newNode);
}
})) {
UnmodifiableEconomicMap<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements);
if (scope != null) {
replaceeGraph.getInliningLog().addLog(duplicates, snippet.getInliningLog());
}
NodeSourcePosition position = replacee.getNodeSourcePosition();
InliningUtil.updateSourcePosition(replaceeGraph, duplicates, mark, position, true);
debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
return duplicates;
}
}
use of org.graalvm.compiler.graph.Graph.Mark in project graal by oracle.
the class SnippetTemplate method explodeLoops.
public static void explodeLoops(final StructuredGraph snippetCopy, PhaseContext phaseContext) {
// Do any required loop explosion
boolean exploded = false;
do {
exploded = false;
ExplodeLoopNode explodeLoop = snippetCopy.getNodes().filter(ExplodeLoopNode.class).first();
if (explodeLoop != null) {
// Earlier canonicalization may have removed the loop
// altogether
LoopBeginNode loopBegin = explodeLoop.findLoopBegin();
if (loopBegin != null) {
LoopEx loop = new LoopsData(snippetCopy).loop(loopBegin);
Mark mark = snippetCopy.getMark();
LoopTransformations.fullUnroll(loop, phaseContext, new CanonicalizerPhase());
new CanonicalizerPhase().applyIncremental(snippetCopy, phaseContext, mark);
loop.deleteUnusedNodes();
}
GraphUtil.removeFixedWithUnusedInputs(explodeLoop);
exploded = true;
}
} while (exploded);
}
use of org.graalvm.compiler.graph.Graph.Mark in project graal by oracle.
the class BytecodeParser method guardIntrinsic.
/**
* Weaves a test of the receiver type to ensure the dispatch will select {@code targetMethod}
* and not another method that overrides it. This should only be called if there is an intrinsic
* (i.e., an {@link InvocationPlugin}) for {@code targetMethod} and the invocation is indirect.
*
* The control flow woven around the intrinsic is as follows:
*
* <pre>
* if (LoadMethod(LoadHub(receiver)) == targetMethod) {
* <intrinsic for targetMethod>
* } else {
* <virtual call to targetMethod>
* }
* </pre>
*
* The {@code else} branch is woven by {@link #afterInvocationPluginExecution}.
*
* @return {@code null} if the intrinsic cannot be used otherwise an object to be used by
* {@link #afterInvocationPluginExecution} to weave code for the non-intrinsic branch
*/
protected IntrinsicGuard guardIntrinsic(ValueNode[] args, ResolvedJavaMethod targetMethod, InvocationPluginReceiver pluginReceiver) {
ValueNode intrinsicReceiver = args[0];
ResolvedJavaType receiverType = StampTool.typeOrNull(intrinsicReceiver);
if (receiverType == null) {
// The verifier guarantees it to be at least type declaring targetMethod
receiverType = targetMethod.getDeclaringClass();
}
ResolvedJavaMethod resolvedMethod = receiverType.resolveMethod(targetMethod, method.getDeclaringClass());
if (resolvedMethod == null || resolvedMethod.equals(targetMethod)) {
assert resolvedMethod == null || targetMethod.getDeclaringClass().isAssignableFrom(resolvedMethod.getDeclaringClass());
Mark mark = graph.getMark();
FixedWithNextNode currentLastInstr = lastInstr;
ValueNode nonNullReceiver = pluginReceiver.get();
Stamp methodStamp = stampProvider.createMethodStamp();
LoadHubNode hub = graph.unique(new LoadHubNode(stampProvider, nonNullReceiver));
LoadMethodNode actual = append(new LoadMethodNode(methodStamp, targetMethod, receiverType, method.getDeclaringClass(), hub));
ConstantNode expected = graph.unique(ConstantNode.forConstant(methodStamp, targetMethod.getEncoding(), getMetaAccess()));
LogicNode compare = graph.addOrUniqueWithInputs(CompareNode.createCompareNode(constantReflection, metaAccess, options, null, CanonicalCondition.EQ, actual, expected, NodeView.DEFAULT));
JavaTypeProfile profile = null;
if (profilingInfo != null && this.optimisticOpts.useTypeCheckHints(getOptions())) {
profile = profilingInfo.getTypeProfile(bci());
if (profile != null) {
JavaTypeProfile newProfile = adjustProfileForInvocationPlugin(profile, targetMethod);
if (newProfile != profile) {
if (newProfile.getTypes().length == 0) {
// All profiled types select the intrinsic so
// emit a fixed guard instead of an if-then-else.
lastInstr = append(new FixedGuardNode(compare, TypeCheckedInliningViolated, InvalidateReprofile, false));
return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, null, null);
}
} else {
// No profiled types select the intrinsic so emit a virtual call
return null;
}
profile = newProfile;
}
}
AbstractBeginNode intrinsicBranch = graph.add(new BeginNode());
AbstractBeginNode nonIntrinsicBranch = graph.add(new BeginNode());
append(new IfNode(compare, intrinsicBranch, nonIntrinsicBranch, FAST_PATH_PROBABILITY));
lastInstr = intrinsicBranch;
return new IntrinsicGuard(currentLastInstr, intrinsicReceiver, mark, nonIntrinsicBranch, profile);
} else {
// Receiver selects an overriding method so emit a virtual call
return null;
}
}
use of org.graalvm.compiler.graph.Graph.Mark in project graal by oracle.
the class LoopTransformations method fullUnroll.
public static void fullUnroll(LoopEx loop, PhaseContext context, CanonicalizerPhase canonicalizer) {
// assert loop.isCounted(); //TODO (gd) strengthen : counted with known trip count
LoopBeginNode loopBegin = loop.loopBegin();
StructuredGraph graph = loopBegin.graph();
int initialNodeCount = graph.getNodeCount();
while (!loopBegin.isDeleted()) {
Mark mark = graph.getMark();
peel(loop);
canonicalizer.applyIncremental(graph, context, mark);
loop.invalidateFragments();
if (graph.getNodeCount() > initialNodeCount + MaximumDesiredSize.getValue(graph.getOptions()) * 2) {
throw new RetryableBailoutException("FullUnroll : Graph seems to grow out of proportion");
}
}
}
Aggregations