diff graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java @ 19776:16ad9711b44f

always inline intrinsics in the graph builder as well as any methods (recursively) called from an instrinsic replace BytecodeParser.currentDepth with BytecodeParser.parent
author Doug Simon <doug.simon@oracle.com>
date Thu, 19 Feb 2015 15:40:17 +0100
parents b828f1f74625
children 09dfba3dbfb2
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Thu Feb 19 13:25:23 2015 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotSuitesProvider.java	Thu Feb 19 15:40:17 2015 +0100
@@ -129,78 +129,88 @@
     protected PhaseSuite<HighTierContext> createGraphBuilderSuite(MetaAccessProvider metaAccess, ConstantReflectionProvider constantReflection, Replacements replacements) {
         PhaseSuite<HighTierContext> suite = new PhaseSuite<>();
         GraphBuilderConfiguration config = GraphBuilderConfiguration.getDefault();
-        if (InlineDuringParsing.getValue()) {
-            config.setLoadFieldPlugin(new LoadFieldPlugin() {
-                public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) {
+        config.setLoadFieldPlugin(new LoadFieldPlugin() {
+            public boolean apply(GraphBuilderContext builder, ValueNode receiver, ResolvedJavaField field) {
+                if (InlineDuringParsing.getValue() || builder.parsingReplacement()) {
                     if (receiver.isConstant()) {
                         JavaConstant asJavaConstant = receiver.asJavaConstant();
                         return tryConstantFold(builder, metaAccess, constantReflection, field, asJavaConstant);
                     }
-                    return false;
-                }
-
-                public boolean apply(GraphBuilderContext builder, ResolvedJavaField staticField) {
-                    return tryConstantFold(builder, metaAccess, constantReflection, staticField, null);
                 }
-            });
-            config.setInlineInvokePlugin(new InlineInvokePlugin() {
-                public ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType, int depth) {
-                    ResolvedJavaMethod subst = replacements.getMethodSubstitutionMethod(method);
-                    if (subst != null) {
-                        return subst;
+                return false;
+            }
+
+            public boolean apply(GraphBuilderContext builder, ResolvedJavaField staticField) {
+                return tryConstantFold(builder, metaAccess, constantReflection, staticField, null);
+            }
+        });
+        config.setInlineInvokePlugin(new InlineInvokePlugin() {
+            public ResolvedJavaMethod getInlinedMethod(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args, JavaType returnType) {
+                ResolvedJavaMethod subst = replacements.getMethodSubstitutionMethod(method);
+                if (subst != null) {
+                    // Forced inlining of intrinsics
+                    return subst;
+                }
+                if (builder.parsingReplacement()) {
+                    if (getIntrinsifier().getIntrinsic(method) != null) {
+                        // @NodeIntrinsic methods are handled by the AnnotatedInvocationPlugin
+                        // registered below
+                        return null;
                     }
-                    if (builder.parsingReplacement() && method.getAnnotation(NodeIntrinsic.class) == null) {
-                        return method;
-                    }
-                    if (method.hasBytecodes() && method.getCode().length <= TrivialInliningSize.getValue() && depth < InlineDuringParsingMaxDepth.getValue()) {
+                    // Force inlining when parsing replacements
+                    return method;
+                } else {
+                    assert getIntrinsifier().getIntrinsic(method) == null : String.format("@%s method %s must only be called from within a replacement%n%s", NodeIntrinsic.class.getSimpleName(),
+                                    method.format("%h.%n"), builder);
+                    if (InlineDuringParsing.getValue() && method.hasBytecodes() && method.getCode().length <= TrivialInliningSize.getValue() &&
+                                    builder.getDepth() < InlineDuringParsingMaxDepth.getValue()) {
                         return method;
                     }
-                    return null;
                 }
-            });
-            config.setAnnotatedInvocationPlugin(new AnnotatedInvocationPlugin() {
-                public boolean apply(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args) {
-                    if (builder.parsingReplacement()) {
-                        @SuppressWarnings("hiding")
-                        NodeIntrinsificationPhase intrinsifier = getIntrinsifier();
-                        NodeIntrinsic intrinsic = intrinsifier.getIntrinsic(method);
-                        if (intrinsic != null) {
-                            Signature sig = method.getSignature();
-                            Kind returnKind = sig.getReturnKind();
-                            Stamp stamp = StampFactory.forKind(returnKind);
-                            if (returnKind == Kind.Object) {
-                                JavaType returnType = sig.getReturnType(method.getDeclaringClass());
-                                if (returnType instanceof ResolvedJavaType) {
-                                    stamp = StampFactory.declared((ResolvedJavaType) returnType);
-                                }
+                return null;
+            }
+        });
+        config.setAnnotatedInvocationPlugin(new AnnotatedInvocationPlugin() {
+            public boolean apply(GraphBuilderContext builder, ResolvedJavaMethod method, ValueNode[] args) {
+                if (builder.parsingReplacement()) {
+                    NodeIntrinsificationPhase intrins = getIntrinsifier();
+                    NodeIntrinsic intrinsic = intrins.getIntrinsic(method);
+                    if (intrinsic != null) {
+                        Signature sig = method.getSignature();
+                        Kind returnKind = sig.getReturnKind();
+                        Stamp stamp = StampFactory.forKind(returnKind);
+                        if (returnKind == Kind.Object) {
+                            JavaType returnType = sig.getReturnType(method.getDeclaringClass());
+                            if (returnType instanceof ResolvedJavaType) {
+                                stamp = StampFactory.declared((ResolvedJavaType) returnType);
                             }
+                        }
 
-                            ValueNode res = intrinsifier.createIntrinsicNode(Arrays.asList(args), stamp, method, builder.getGraph(), intrinsic);
-                            res = builder.append(res);
-                            if (res.getKind().getStackKind() != Kind.Void) {
-                                builder.push(returnKind.getStackKind(), res);
+                        ValueNode res = intrins.createIntrinsicNode(Arrays.asList(args), stamp, method, builder.getGraph(), intrinsic);
+                        res = builder.append(res);
+                        if (res.getKind().getStackKind() != Kind.Void) {
+                            builder.push(returnKind.getStackKind(), res);
+                        }
+                        return true;
+                    } else if (intrins.isFoldable(method)) {
+                        ResolvedJavaType[] parameterTypes = resolveJavaTypes(method.toParameterTypes(), method.getDeclaringClass());
+                        JavaConstant constant = intrins.tryFold(Arrays.asList(args), parameterTypes, method);
+                        if (!COULD_NOT_FOLD.equals(constant)) {
+                            if (constant != null) {
+                                // Replace the invoke with the result of the call
+                                ConstantNode res = builder.append(ConstantNode.forConstant(constant, getMetaAccess()));
+                                builder.push(res.getKind().getStackKind(), builder.append(res));
+                            } else {
+                                // This must be a void invoke
+                                assert method.getSignature().getReturnKind() == Kind.Void;
                             }
                             return true;
-                        } else if (intrinsifier.isFoldable(method)) {
-                            ResolvedJavaType[] parameterTypes = resolveJavaTypes(method.toParameterTypes(), method.getDeclaringClass());
-                            JavaConstant constant = intrinsifier.tryFold(Arrays.asList(args), parameterTypes, method);
-                            if (!COULD_NOT_FOLD.equals(constant)) {
-                                if (constant != null) {
-                                    // Replace the invoke with the result of the call
-                                    ConstantNode res = builder.append(ConstantNode.forConstant(constant, getMetaAccess()));
-                                    builder.push(res.getKind().getStackKind(), builder.append(res));
-                                } else {
-                                    // This must be a void invoke
-                                    assert method.getSignature().getReturnKind() == Kind.Void;
-                                }
-                                return true;
-                            }
                         }
                     }
-                    return false;
                 }
-            });
-        }
+                return false;
+            }
+        });
         suite.appendPhase(new GraphBuilderPhase(config));
         return suite;
     }