# HG changeset patch # User Stefan Anzinger # Date 1401798696 -7200 # Node ID fcac781d35927950b56022f9c18d55ec66696d75 # Parent a4bd33d52985c707a612d53469dbafdb0de8fd3b# Parent 2e1957c8ccb8a378b657292c7c0eec155c24c330 Merge diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/GraalOptions.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/UnsafeAccess.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/AbstractObjectStamp.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/FloatStamp.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IllegalStamp.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/IntegerStamp.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/ObjectStamp.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/PrimitiveStamp.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampFactory.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/StampProvider.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/type/VoidStamp.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java --- a/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Jun 03 14:29:40 2014 +0200 +++ b/graal/com.oracle.graal.compiler.test/src/com/oracle/graal/compiler/test/GraalCompilerTest.java Tue Jun 03 14:31:36 2014 +0200 @@ -53,6 +53,7 @@ import com.oracle.graal.nodes.spi.*; import com.oracle.graal.nodes.virtual.*; import com.oracle.graal.phases.*; +import com.oracle.graal.phases.common.*; import com.oracle.graal.phases.common.inlining.*; import com.oracle.graal.phases.schedule.*; import com.oracle.graal.phases.tiers.*; @@ -124,7 +125,9 @@ protected Suites createSuites() { Suites ret = backend.getSuites().createSuites(); - ret.getHighTier().findPhase(InliningPhase.class).add(new Phase("ComputeLoopFrequenciesPhase") { + ListIterator> iter = ret.getHighTier().findPhase(InliningPhase.class); + PhaseSuite.findNextPhase(iter, CanonicalizerPhase.class); + iter.add(new Phase("ComputeLoopFrequenciesPhase") { @Override protected void run(StructuredGraph graph) { diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/DefaultHotSpotLoweringProvider.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/replacements/MethodHandleNode.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMConstant.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMField.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMFlag.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.hotspotvmconfig/src/com/oracle/graal/hotspotvmconfig/HotSpotVMType.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/BinaryOpLogicNode.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java --- a/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Jun 03 14:29:40 2014 +0200 +++ b/graal/com.oracle.graal.nodes/src/com/oracle/graal/nodes/java/MethodCallTargetNode.java Tue Jun 03 14:31:36 2014 +0200 @@ -42,8 +42,6 @@ private ResolvedJavaMethod targetMethod; private InvokeKind invokeKind; - private transient Stamp lastCanonicalizedReceiverStamp; - /** * @param arguments */ @@ -140,17 +138,12 @@ } // check if the type of the receiver can narrow the result - Stamp receiverStamp = receiver().stamp(); - if (receiverStamp.equals(lastCanonicalizedReceiverStamp)) { - return this; - } - lastCanonicalizedReceiverStamp = receiverStamp; - - ResolvedJavaType type = StampTool.typeOrNull(receiverStamp); + ValueNode receiver = receiver(); + ResolvedJavaType type = StampTool.typeOrNull(receiver); if (type != null && (invoke().stateAfter() != null || invoke().stateDuring() != null)) { // either the holder class is exact, or the receiver object has an exact type ResolvedJavaMethod resolvedMethod = type.resolveMethod(targetMethod, invoke().getContextType()); - if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiverStamp))) { + if (resolvedMethod != null && (resolvedMethod.canBeStaticallyBound() || StampTool.isExactType(receiver))) { invokeKind = InvokeKind.Special; targetMethod = resolvedMethod; return this; diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningPhase.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/InliningUtil.java diff -r a4bd33d52985 -r fcac781d3592 graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java --- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Tue Jun 03 14:29:40 2014 +0200 +++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java Tue Jun 03 14:31:36 2014 +0200 @@ -42,48 +42,48 @@ private final StructuredGraph graph; public InlineableGraph(final ResolvedJavaMethod method, final Invoke invoke, final HighTierContext context, CanonicalizerPhase canonicalizer) { - this.graph = buildGraph(method, invoke, context, canonicalizer); + StructuredGraph original = getOriginalGraph(method, context, canonicalizer); + // TODO copying the graph is only necessary if it is modified or if it contains any invokes + this.graph = original.copy(); + specializeGraphToArguments(invoke, context, canonicalizer); } /** - * @return a (possibly cached) graph. The caller is responsible for cloning before modification. + * This method looks up in a cache the graph for the argument, if not found bytecode is parsed. + * The graph thus obtained is returned, ie the caller is responsible for cloning before + * modification. */ - private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context) { - StructuredGraph intrinsicGraph = InliningUtil.getIntrinsicGraph(context.getReplacements(), method); - if (intrinsicGraph != null) { - return intrinsicGraph; + private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context, CanonicalizerPhase canonicalizer) { + StructuredGraph result = InliningUtil.getIntrinsicGraph(context.getReplacements(), method); + if (result != null) { + return result; } - StructuredGraph cachedGraph = getCachedGraph(method, context); - if (cachedGraph != null) { - return cachedGraph; + result = getCachedGraph(method, context); + if (result != null) { + return result; } - return null; + return parseBytecodes(method, context, canonicalizer); } - private static StructuredGraph buildGraph(final ResolvedJavaMethod method, final Invoke invoke, final HighTierContext context, CanonicalizerPhase canonicalizer) { - StructuredGraph newGraph = getOriginalGraph(method, context); - if (newGraph == null) { - newGraph = new StructuredGraph(method); - parseBytecodes(newGraph, context, canonicalizer); - } - newGraph = newGraph.copy(); + /** + * @return true iff one or more parameters newGraph were specialized to account for + * a constant argument, or an argument with a more specific stamp. + */ + private boolean specializeGraphToArguments(final Invoke invoke, final HighTierContext context, CanonicalizerPhase canonicalizer) { + try (Debug.Scope s = Debug.scope("InlineGraph", graph)) { - // TODO (chaeubl): copying the graph is only necessary if it is modified or if it contains - // any invokes - - try (Debug.Scope s = Debug.scope("InlineGraph", newGraph)) { - - ArrayList parameterUsages = replaceParamsWithMoreInformativeArguments(invoke, newGraph, context); + ArrayList parameterUsages = replaceParamsWithMoreInformativeArguments(invoke, context); if (parameterUsages != null && OptCanonicalizer.getValue()) { assert !parameterUsages.isEmpty() : "The caller didn't have more information about arguments after all"; - canonicalizer.applyIncremental(newGraph, context, parameterUsages); + canonicalizer.applyIncremental(graph, context, parameterUsages); + return true; } else { // TODO (chaeubl): if args are not more concrete, inlining should be avoided // in most cases or we could at least use the previous graph size + invoke // probability to check the inlining + return false; } - return newGraph; } catch (Throwable e) { throw Debug.handle(e); } @@ -119,17 +119,26 @@ * @return null if no incremental canonicalization is need, a list of nodes for such * canonicalization otherwise. */ - private static ArrayList replaceParamsWithMoreInformativeArguments(final Invoke invoke, final StructuredGraph newGraph, final HighTierContext context) { + private ArrayList replaceParamsWithMoreInformativeArguments(final Invoke invoke, final HighTierContext context) { NodeInputList args = invoke.callTarget().arguments(); ArrayList parameterUsages = null; - for (ParameterNode param : newGraph.getNodes(ParameterNode.class).snapshot()) { + List params = graph.getNodes(ParameterNode.class).snapshot(); + assert params.size() <= args.size(); + /* + * param-nodes that aren't used (eg, as a result of canonicalization) don't occur in + * `params`. Thus, in general, the sizes of `params` and `args` don't always match. Still, + * it's always possible to pair a param-node with its corresponding arg-node using + * param.index() as index into `args`. + */ + for (ParameterNode param : params) { if (param.usages().isNotEmpty()) { ValueNode arg = args.get(param.index()); if (arg.isConstant()) { Constant constant = arg.asConstant(); parameterUsages = trackParameterUsages(param, parameterUsages); // collect param usages before replacing the param - newGraph.replaceFloating(param, ConstantNode.forConstant(constant, context.getMetaAccess(), newGraph)); + graph.replaceFloating(param, ConstantNode.forConstant(constant, context.getMetaAccess(), graph)); + // param-node gone, leaving a gap in the sequence given by param.index() } else { Stamp joinedStamp = param.stamp().join(arg.stamp()); if (joinedStamp != null && !joinedStamp.equals(param.stamp())) { @@ -141,6 +150,7 @@ } } } + assert (parameterUsages == null) || (!parameterUsages.isEmpty()); return parameterUsages; } @@ -161,11 +171,12 @@ } /** - * This method builds the IR nodes for newGraph and canonicalizes them. Provided - * profiling info is mature, the resulting graph is cached. The caller is responsible for - * cloning before modification.

+ * This method builds the IR nodes for the given method and canonicalizes them. + * Provided profiling info is mature, the resulting graph is cached. The caller is responsible + * for cloning before modification.

*/ - private static StructuredGraph parseBytecodes(StructuredGraph newGraph, HighTierContext context, CanonicalizerPhase canonicalizer) { + private static StructuredGraph parseBytecodes(ResolvedJavaMethod method, HighTierContext context, CanonicalizerPhase canonicalizer) { + StructuredGraph newGraph = new StructuredGraph(method); try (Debug.Scope s = Debug.scope("InlineGraph", newGraph)) { if (context.getGraphBuilderSuite() != null) { context.getGraphBuilderSuite().apply(newGraph, context); diff -r a4bd33d52985 -r fcac781d3592 test/whitelist_baseline.txt