--- a/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java Fri Mar 16 11:26:05 2018 +0000
+++ b/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.replacements/src/org/graalvm/compiler/replacements/SnippetTemplate.java Fri Mar 16 22:59:32 2018 -0700
@@ -47,27 +47,15 @@
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
-import jdk.vm.ci.code.TargetDescription;
-import jdk.vm.ci.meta.Constant;
-import jdk.vm.ci.meta.JavaConstant;
-import jdk.vm.ci.meta.JavaKind;
-import jdk.vm.ci.meta.Local;
-import jdk.vm.ci.meta.LocalVariableTable;
-import jdk.vm.ci.meta.MetaAccessProvider;
-import jdk.vm.ci.meta.ResolvedJavaMethod;
-import jdk.vm.ci.meta.ResolvedJavaType;
-import jdk.vm.ci.meta.Signature;
-import jdk.vm.ci.meta.ResolvedJavaMethod.Parameter;
-
import org.graalvm.collections.EconomicMap;
import org.graalvm.collections.EconomicSet;
import org.graalvm.collections.Equivalence;
import org.graalvm.collections.UnmodifiableEconomicMap;
import org.graalvm.compiler.api.replacements.Snippet;
-import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.api.replacements.Snippet.ConstantParameter;
import org.graalvm.compiler.api.replacements.Snippet.NonNullParameter;
import org.graalvm.compiler.api.replacements.Snippet.VarargsParameter;
+import org.graalvm.compiler.api.replacements.SnippetReflectionProvider;
import org.graalvm.compiler.core.common.GraalOptions;
import org.graalvm.compiler.core.common.type.Stamp;
import org.graalvm.compiler.core.common.type.StampFactory;
@@ -76,14 +64,15 @@
import org.graalvm.compiler.debug.CounterKey;
import org.graalvm.compiler.debug.DebugCloseable;
import org.graalvm.compiler.debug.DebugContext;
+import org.graalvm.compiler.debug.DebugContext.Description;
import org.graalvm.compiler.debug.DebugHandlersFactory;
import org.graalvm.compiler.debug.GraalError;
import org.graalvm.compiler.debug.TimerKey;
-import org.graalvm.compiler.debug.DebugContext.Description;
+import org.graalvm.compiler.graph.Graph.Mark;
import org.graalvm.compiler.graph.Node;
import org.graalvm.compiler.graph.NodeClass;
+import org.graalvm.compiler.graph.NodeSourcePosition;
import org.graalvm.compiler.graph.Position;
-import org.graalvm.compiler.graph.Graph.Mark;
import org.graalvm.compiler.loop.LoopEx;
import org.graalvm.compiler.loop.LoopsData;
import org.graalvm.compiler.loop.phases.LoopTransformations;
@@ -97,20 +86,21 @@
import org.graalvm.compiler.nodes.FixedNode;
import org.graalvm.compiler.nodes.FixedWithNextNode;
import org.graalvm.compiler.nodes.FrameState;
+import org.graalvm.compiler.nodes.InliningLog;
import org.graalvm.compiler.nodes.LoopBeginNode;
import org.graalvm.compiler.nodes.MergeNode;
import org.graalvm.compiler.nodes.NodeView;
import org.graalvm.compiler.nodes.ParameterNode;
import org.graalvm.compiler.nodes.PhiNode;
+import org.graalvm.compiler.nodes.PiNode.Placeholder;
+import org.graalvm.compiler.nodes.PiNode.PlaceholderStamp;
import org.graalvm.compiler.nodes.ReturnNode;
import org.graalvm.compiler.nodes.StartNode;
import org.graalvm.compiler.nodes.StateSplit;
import org.graalvm.compiler.nodes.StructuredGraph;
+import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
import org.graalvm.compiler.nodes.ValueNode;
import org.graalvm.compiler.nodes.ValueNodeUtil;
-import org.graalvm.compiler.nodes.PiNode.Placeholder;
-import org.graalvm.compiler.nodes.PiNode.PlaceholderStamp;
-import org.graalvm.compiler.nodes.StructuredGraph.GuardsStage;
import org.graalvm.compiler.nodes.calc.FloatingNode;
import org.graalvm.compiler.nodes.java.LoadIndexedNode;
import org.graalvm.compiler.nodes.java.StoreIndexedNode;
@@ -131,10 +121,10 @@
import org.graalvm.compiler.phases.common.CanonicalizerPhase;
import org.graalvm.compiler.phases.common.DeadCodeEliminationPhase;
import org.graalvm.compiler.phases.common.FloatingReadPhase;
+import org.graalvm.compiler.phases.common.FloatingReadPhase.MemoryMapImpl;
import org.graalvm.compiler.phases.common.GuardLoweringPhase;
import org.graalvm.compiler.phases.common.LoweringPhase;
import org.graalvm.compiler.phases.common.RemoveValueProxyPhase;
-import org.graalvm.compiler.phases.common.FloatingReadPhase.MemoryMapImpl;
import org.graalvm.compiler.phases.common.inlining.InliningUtil;
import org.graalvm.compiler.phases.tiers.PhaseContext;
import org.graalvm.compiler.phases.util.Providers;
@@ -144,6 +134,18 @@
import org.graalvm.word.LocationIdentity;
import org.graalvm.word.WordBase;
+import jdk.vm.ci.code.TargetDescription;
+import jdk.vm.ci.meta.Constant;
+import jdk.vm.ci.meta.JavaConstant;
+import jdk.vm.ci.meta.JavaKind;
+import jdk.vm.ci.meta.Local;
+import jdk.vm.ci.meta.LocalVariableTable;
+import jdk.vm.ci.meta.MetaAccessProvider;
+import jdk.vm.ci.meta.ResolvedJavaMethod;
+import jdk.vm.ci.meta.ResolvedJavaMethod.Parameter;
+import jdk.vm.ci.meta.ResolvedJavaType;
+import jdk.vm.ci.meta.Signature;
+
/**
* A snippet template is a graph created by parsing a snippet method and then specialized by binding
* constants to the snippet's {@link ConstantParameter} parameters.
@@ -565,7 +567,7 @@
static class Options {
@Option(help = "Use a LRU cache for snippet templates.")//
- static final OptionKey<Boolean> UseSnippetTemplateCache = new OptionKey<>(true);
+ public static final OptionKey<Boolean> UseSnippetTemplateCache = new OptionKey<>(true);
@Option(help = "")//
static final OptionKey<Integer> MaxTemplatesPerSnippet = new OptionKey<>(50);
@@ -618,7 +620,7 @@
assert method.getAnnotation(Snippet.class) != null : method + " must be annotated with @" + Snippet.class.getSimpleName();
assert findMethod(declaringClass, methodName, method) == null : "found more than one method named " + methodName + " in " + declaringClass;
ResolvedJavaMethod javaMethod = providers.getMetaAccess().lookupJavaMethod(method);
- providers.getReplacements().registerSnippet(javaMethod);
+ providers.getReplacements().registerSnippet(javaMethod, GraalOptions.TrackNodeSourcePosition.getValue(options));
LocationIdentity[] privateLocations = GraalOptions.SnippetCounters.getValue(options) ? SnippetCounterNode.addSnippetCounters(initialPrivateLocations) : initialPrivateLocations;
if (GraalOptions.EagerSnippets.getValue(options)) {
return new EagerSnippetInfo(javaMethod, privateLocations);
@@ -641,13 +643,15 @@
* Gets a template for a given key, creating it first if necessary.
*/
@SuppressWarnings("try")
- protected SnippetTemplate template(DebugContext outer, final Arguments args) {
+ protected SnippetTemplate template(ValueNode replacee, final Arguments args) {
+ StructuredGraph graph = replacee.graph();
+ DebugContext outer = graph.getDebug();
SnippetTemplate template = Options.UseSnippetTemplateCache.getValue(options) && args.cacheable ? templates.get(args.cacheKey) : null;
- if (template == null) {
+ if (template == null || (graph.trackNodeSourcePosition() && !template.snippet.trackNodeSourcePosition())) {
try (DebugContext debug = openDebugContext(outer, args)) {
try (DebugCloseable a = SnippetTemplateCreationTime.start(debug); DebugContext.Scope s = debug.scope("SnippetSpecialization", args.info.method)) {
SnippetTemplates.increment(debug);
- template = new SnippetTemplate(options, debug, providers, snippetReflection, args);
+ template = new SnippetTemplate(options, debug, providers, snippetReflection, args, graph.trackNodeSourcePosition(), replacee);
if (Options.UseSnippetTemplateCache.getValue(options) && args.cacheable) {
templates.put(args.cacheKey, template);
}
@@ -697,12 +701,13 @@
* Creates a snippet template.
*/
@SuppressWarnings("try")
- protected SnippetTemplate(OptionValues options, DebugContext debug, final Providers providers, SnippetReflectionProvider snippetReflection, Arguments args) {
+ protected SnippetTemplate(OptionValues options, DebugContext debug, final Providers providers, SnippetReflectionProvider snippetReflection, Arguments args, boolean trackNodeSourcePosition,
+ Node replacee) {
this.snippetReflection = snippetReflection;
this.info = args.info;
Object[] constantArgs = getConstantArgs(args);
- StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method, args.info.original, constantArgs);
+ StructuredGraph snippetGraph = providers.getReplacements().getSnippet(args.info.method, args.info.original, constantArgs, trackNodeSourcePosition, replacee.getNodeSourcePosition());
ResolvedJavaMethod method = snippetGraph.method();
Signature signature = method.getSignature();
@@ -710,8 +715,12 @@
PhaseContext phaseContext = new PhaseContext(providers);
// Copy snippet graph, replacing constant parameters with given arguments
- final StructuredGraph snippetCopy = new StructuredGraph.Builder(options, debug).name(snippetGraph.name).method(snippetGraph.method()).build();
-
+ final StructuredGraph snippetCopy = new StructuredGraph.Builder(options, debug).name(snippetGraph.name).method(snippetGraph.method()).trackNodeSourcePosition(
+ snippetGraph.trackNodeSourcePosition()).build();
+ assert !GraalOptions.TrackNodeSourcePosition.getValue(options) || snippetCopy.trackNodeSourcePosition();
+ if (providers.getCodeCache() != null && providers.getCodeCache().shouldDebugNonSafepoints()) {
+ snippetCopy.setTrackNodeSourcePosition();
+ }
try (DebugContext.Scope scope = debug.scope("SpecializeSnippet", snippetCopy)) {
if (!snippetGraph.isUnsafeAccessTrackingEnabled()) {
snippetCopy.disableUnsafeAccessTracking();
@@ -755,7 +764,12 @@
}
}
}
- snippetCopy.addDuplicates(snippetGraph.getNodes(), snippetGraph, snippetGraph.getNodeCount(), nodeReplacements);
+ try (InliningLog.UpdateScope updateScope = snippetCopy.getInliningLog().openDefaultUpdateScope()) {
+ UnmodifiableEconomicMap<Node, Node> duplicates = snippetCopy.addDuplicates(snippetGraph.getNodes(), snippetGraph, snippetGraph.getNodeCount(), nodeReplacements);
+ if (updateScope != null) {
+ snippetCopy.getInliningLog().replaceLog(duplicates, snippetGraph.getInliningLog());
+ }
+ }
debug.dump(DebugContext.INFO_LEVEL, snippetCopy, "Before specialization");
@@ -1396,8 +1410,7 @@
StructuredGraph replaceeGraph = replacee.graph();
EconomicMap<Node, Node> replacements = bind(replaceeGraph, metaAccess, args);
replacements.put(entryPointNode, AbstractBeginNode.prevBegin(replacee));
- UnmodifiableEconomicMap<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements);
- debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
+ UnmodifiableEconomicMap<Node, Node> duplicates = inlineSnippet(replacee, debug, replaceeGraph, replacements);
// Re-wire the control flow graph around the replacee
FixedNode firstCFGNodeDuplicate = (FixedNode) duplicates.get(firstCFGNode);
@@ -1490,6 +1503,27 @@
}
}
+ 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();
+ if (position != null) {
+ InliningUtil.updateSourcePosition(replaceeGraph, duplicates, mark, position, true);
+ }
+ debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
+ return duplicates;
+ }
+ }
+
private void propagateStamp(Node node) {
if (node instanceof PhiNode) {
PhiNode phi = (PhiNode) node;
@@ -1549,8 +1583,7 @@
StructuredGraph replaceeGraph = replacee.graph();
EconomicMap<Node, Node> replacements = bind(replaceeGraph, metaAccess, args);
replacements.put(entryPointNode, tool.getCurrentGuardAnchor().asNode());
- UnmodifiableEconomicMap<Node, Node> duplicates = replaceeGraph.addDuplicates(nodes, snippet, snippet.getNodeCount(), replacements);
- debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
+ UnmodifiableEconomicMap<Node, Node> duplicates = inlineSnippet(replacee, debug, replaceeGraph, replacements);
FixedWithNextNode lastFixedNode = tool.lastFixedNode();
assert lastFixedNode != null && lastFixedNode.isAlive() : replaceeGraph + " lastFixed=" + lastFixedNode;
@@ -1611,8 +1644,7 @@
floatingNodes.add(n);
}
}
- UnmodifiableEconomicMap<Node, Node> duplicates = replaceeGraph.addDuplicates(floatingNodes, snippet, floatingNodes.size(), replacements);
- debug.dump(DebugContext.DETAILED_LEVEL, replaceeGraph, "After inlining snippet %s", snippet.method());
+ UnmodifiableEconomicMap<Node, Node> duplicates = inlineSnippet(replacee, debug, replaceeGraph, replacements);
rewireFrameStates(replacee, duplicates);
updateStamps(replacee, duplicates);