changeset 20835:a2cd0e7072e2

added MethodSubstitutionPlugin as (eventual) replacement for @MethodSubstitution mechanism
author Doug Simon <doug.simon@oracle.com>
date Tue, 07 Apr 2015 17:32:26 +0200
parents e807c6f675de
children 63e4f33dce84
files graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/MethodSubstitutionPlugin.java graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java graal/com.oracle.graal.replacements.sparc/src/com/oracle/graal/replacements/sparc/SPARCGraphBuilderPlugins.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntrinsicGraphBuilder.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java mx/suite.py
diffstat 14 files changed, 246 insertions(+), 31 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/GraphBuilderContext.java	Tue Apr 07 17:32:26 2015 +0200
@@ -168,6 +168,16 @@
      */
     void handleReplacedInvoke(InvokeKind invokeKind, ResolvedJavaMethod targetMethod, ValueNode[] args);
 
+    /**
+     * Intrinsifies an invocation of a given method by inlining the bytecodes of a given
+     * substitution method.
+     *
+     * @param targetMethod the method being intrinsified
+     * @param substitute the intrinsic implementation
+     * @param args the arguments with which to inline the invocation
+     */
+    void intrinsify(ResolvedJavaMethod targetMethod, ResolvedJavaMethod substitute, ValueNode[] args);
+
     StampProvider getStampProvider();
 
     MetaAccessProvider getMetaAccess();
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugin.java	Tue Apr 07 17:32:26 2015 +0200
@@ -97,10 +97,6 @@
         return defaultHandler(b, targetMethod, receiver, arg1, arg2, arg3, arg4, arg5);
     }
 
-    default ResolvedJavaMethod getSubstitute() {
-        return null;
-    }
-
     /**
      * Executes this plugin against a set of invocation arguments.
      *
--- a/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/InvocationPlugins.java	Tue Apr 07 17:32:26 2015 +0200
@@ -181,6 +181,18 @@
         public void register5(String name, Class<?> arg1, Class<?> arg2, Class<?> arg3, Class<?> arg4, Class<?> arg5, InvocationPlugin plugin) {
             plugins.register(plugin, declaringClass, name, arg1, arg2, arg3, arg4, arg5);
         }
+
+        /**
+         * Registers a plugin that implements a method based on the bytecode of a substitute method.
+         *
+         * @param substituteDeclaringClass the class declaring the substitute method
+         * @param name the name of both the original and substitute method
+         * @param argumentTypes the parameter types of the substitute
+         */
+        public void registerMethodSubstitution(Class<?> substituteDeclaringClass, String name, Class<?>... argumentTypes) {
+            MethodSubstitutionPlugin plugin = new MethodSubstitutionPlugin(substituteDeclaringClass, name, argumentTypes);
+            plugins.register(plugin, declaringClass, name, argumentTypes);
+        }
     }
 
     static final class MethodInfo {
@@ -404,6 +416,11 @@
         }
 
         public static boolean check(InvocationPlugins plugins, MethodInfo method, InvocationPlugin plugin) {
+            if (plugin instanceof MethodSubstitutionPlugin) {
+                MethodSubstitutionPlugin msplugin = (MethodSubstitutionPlugin) plugin;
+                msplugin.getJavaSubstitute();
+                return true;
+            }
             InvocationPlugins p = plugins;
             while (p != null) {
                 assert !p.registrations.contains(method) : "a plugin is already registered for " + method;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.graphbuilderconf/src/com/oracle/graal/graphbuilderconf/MethodSubstitutionPlugin.java	Tue Apr 07 17:32:26 2015 +0200
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.graphbuilderconf;
+
+import java.lang.reflect.*;
+
+import sun.misc.*;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.api.replacements.*;
+import com.oracle.graal.compiler.common.*;
+import com.oracle.graal.graphbuilderconf.InvocationPlugins.Receiver;
+import com.oracle.graal.nodes.*;
+
+/**
+ * An {@link InvocationPlugin} for a method where the implementation of the method is provided by a
+ * {@linkplain #getSubstitute(MetaAccessProvider) substitute} method. A substitute method must be
+ * static even if the substituted method is not.
+ */
+public class MethodSubstitutionPlugin implements InvocationPlugin {
+
+    private ResolvedJavaMethod cachedSubstitute;
+    private final Class<?> declaringClass;
+    private final String name;
+    private final Class<?>[] parameters;
+
+    /**
+     * Creates a method substitution plugin.
+     *
+     * @param declaringClass the class in which the substitute method is declared
+     * @param name the name of the substitute method
+     * @param parameters the parameter types of the substitute method. If the original method is not
+     *            static, then {@code parameters[0]} must be the {@link Class} value denoting
+     *            {@link Receiver}
+     */
+    public MethodSubstitutionPlugin(Class<?> declaringClass, String name, Class<?>... parameters) {
+        this.declaringClass = declaringClass;
+        this.name = name;
+        this.parameters = parameters;
+    }
+
+    /**
+     * Gets the substitute method, resolving it first if necessary.
+     */
+    public ResolvedJavaMethod getSubstitute(MetaAccessProvider metaAccess) {
+        if (cachedSubstitute == null) {
+            cachedSubstitute = metaAccess.lookupJavaMethod(getJavaSubstitute());
+            assert cachedSubstitute.getAnnotation(MethodSubstitution.class) != null;
+        }
+        return cachedSubstitute;
+    }
+
+    /**
+     * Gets the reflection API version of the substitution method.
+     */
+    Method getJavaSubstitute() throws GraalInternalError {
+        try {
+            Method substituteMethod = declaringClass.getDeclaredMethod(name, parameters);
+            int modifiers = substituteMethod.getModifiers();
+            if (Modifier.isAbstract(modifiers) || Modifier.isNative(modifiers)) {
+                throw new GraalInternalError("Substitution method must not be abstract or native: " + substituteMethod);
+            }
+            if (!Modifier.isStatic(modifiers)) {
+                throw new GraalInternalError("Substitution method must be static: " + substituteMethod);
+            }
+            return substituteMethod;
+        } catch (NoSuchMethodException e) {
+            throw new GraalInternalError(e);
+        }
+    }
+
+    /**
+     * Resolves a name to a class.
+     *
+     * @param className the name of the class to resolve
+     * @param optional if true, resolution failure returns null
+     * @return the resolved class or null if resolution fails and {@code optional} is true
+     */
+    public static Class<?> resolveClass(String className, boolean optional) {
+        try {
+            // Need to use launcher class path to handle classes
+            // that are not on the boot class path
+            ClassLoader cl = Launcher.getLauncher().getClassLoader();
+            return Class.forName(className, false, cl);
+        } catch (ClassNotFoundException e) {
+            if (optional) {
+                return null;
+            }
+            throw new GraalInternalError("Could not resolve type " + className);
+        }
+    }
+
+    @Override
+    public boolean execute(GraphBuilderContext b, ResolvedJavaMethod targetMethod, Receiver receiver, ValueNode[] argsIncludingReceiver) {
+        ResolvedJavaMethod subst = getSubstitute(b.getMetaAccess());
+        b.intrinsify(targetMethod, subst, argsIncludingReceiver);
+        return true;
+    }
+}
--- a/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.hotspot.sparc/src/com/oracle/graal/hotspot/sparc/SPARCHotSpotBackendFactory.java	Tue Apr 07 17:32:26 2015 +0200
@@ -33,6 +33,7 @@
 import com.oracle.graal.hotspot.word.*;
 import com.oracle.graal.nodes.spi.*;
 import com.oracle.graal.phases.util.*;
+import com.oracle.graal.replacements.sparc.*;
 import com.oracle.graal.sparc.*;
 import com.oracle.graal.sparc.SPARC.CPUFeature;
 
@@ -80,7 +81,9 @@
     protected Plugins createGraphBuilderPlugins(HotSpotGraalRuntimeProvider runtime, TargetDescription target, HotSpotMetaAccessProvider metaAccess,
                     HotSpotConstantReflectionProvider constantReflection, HotSpotForeignCallsProvider foreignCalls, HotSpotStampProvider stampProvider,
                     HotSpotSnippetReflectionProvider snippetReflection, HotSpotReplacementsImpl replacements, HotSpotWordTypes wordTypes) {
-        return HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch);
+        Plugins plugins = HotSpotGraphBuilderPlugins.create(runtime.getConfig(), wordTypes, metaAccess, constantReflection, snippetReflection, foreignCalls, stampProvider, replacements, target.arch);
+        SPARCGraphBuilderPlugins.register(plugins);
+        return plugins;
     }
 
     protected HotSpotSuitesProvider createSuites(HotSpotGraalRuntimeProvider runtime, Plugins plugins) {
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/meta/HotSpotInvocationPlugins.java	Tue Apr 07 17:32:26 2015 +0200
@@ -61,19 +61,6 @@
                 return;
             }
         }
-        if (!config.useCountLeadingZerosInstruction) {
-            if (name.equals("numberOfLeadingZeros")) {
-                assert declaringClass.equals(Integer.class) || declaringClass.equals(Long.class);
-                return;
-            }
-        }
-        if (!config.useCountTrailingZerosInstruction) {
-            if (name.equals("numberOfTrailingZeros")) {
-                assert declaringClass.equals(Integer.class);
-                return;
-            }
-        }
-
         if (config.useHeapProfiler) {
             if (plugin instanceof BoxPlugin) {
                 // The heap profiler wants to see all allocations related to boxing
--- a/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.java/src/com/oracle/graal/java/GraphBuilderPhase.java	Tue Apr 07 17:32:26 2015 +0200
@@ -1265,14 +1265,18 @@
                 }
                 InlineInfo inlineInfo = plugin.getInlineInfo(this, targetMethod, args, returnType);
                 if (inlineInfo != null) {
-                    return inline(plugin, targetMethod, inlineInfo, args);
+                    return inline(plugin, targetMethod, inlineInfo.methodToInline, inlineInfo.isReplacement, inlineInfo.isIntrinsic, args);
                 }
                 return false;
             }
 
-            public boolean inline(InlineInvokePlugin plugin, ResolvedJavaMethod targetMethod, InlineInfo inlineInfo, ValueNode[] args) {
+            public void intrinsify(ResolvedJavaMethod targetMethod, ResolvedJavaMethod substitute, ValueNode[] args) {
+                boolean res = inline(null, targetMethod, substitute, true, true, args);
+                assert res : "failed to inline " + substitute;
+            }
+
+            private boolean inline(InlineInvokePlugin plugin, ResolvedJavaMethod targetMethod, ResolvedJavaMethod inlinedMethod, boolean isReplacement, boolean isIntrinsic, ValueNode[] args) {
                 int bci = bci();
-                ResolvedJavaMethod inlinedMethod = inlineInfo.methodToInline;
                 if (TraceInlineDuringParsing.getValue() || TraceParserPlugins.getValue()) {
                     if (targetMethod.equals(inlinedMethod)) {
                         traceWithContext("inlining call to %s", inlinedMethod.format("%h.%n(%p)"));
@@ -1308,9 +1312,9 @@
                         }
                     }
                 } else {
-                    if (context == null && inlineInfo.isReplacement) {
+                    if (context == null && isReplacement) {
                         assert !inlinedMethod.equals(targetMethod);
-                        if (inlineInfo.isIntrinsic) {
+                        if (isIntrinsic) {
                             context = new IntrinsicContext(targetMethod, inlinedMethod, args, bci);
                         } else {
                             context = new ReplacementContext(targetMethod, inlinedMethod);
--- a/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.phases.common/src/com/oracle/graal/phases/common/inlining/info/elem/InlineableGraph.java	Tue Apr 07 17:32:26 2015 +0200
@@ -71,6 +71,9 @@
      * modification.
      */
     private static StructuredGraph getOriginalGraph(final ResolvedJavaMethod method, final HighTierContext context, CanonicalizerPhase canonicalizer, StructuredGraph caller) {
+        if (method.getName().equals("hashCode")) {
+            System.console();
+        }
         StructuredGraph result = InliningUtil.getIntrinsicGraph(context.getReplacements(), method);
         if (result != null) {
             return result;
--- a/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.replacements.amd64/src/com/oracle/graal/replacements/amd64/AMD64GraphBuilderPlugins.java	Tue Apr 07 17:32:26 2015 +0200
@@ -29,16 +29,17 @@
 import com.oracle.graal.graphbuilderconf.InvocationPlugins.Receiver;
 import com.oracle.graal.graphbuilderconf.InvocationPlugins.Registration;
 import com.oracle.graal.nodes.*;
+import com.oracle.graal.replacements.*;
 
 public class AMD64GraphBuilderPlugins {
 
     public static void register(Plugins plugins, AMD64 arch) {
         InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
-        registerIntegerLongPlugins(invocationPlugins, Kind.Int, arch);
-        registerIntegerLongPlugins(invocationPlugins, Kind.Long, arch);
+        registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, Kind.Int, arch);
+        registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, Kind.Long, arch);
     }
 
-    private static void registerIntegerLongPlugins(InvocationPlugins plugins, Kind kind, AMD64 arch) {
+    private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, Kind kind, AMD64 arch) {
         Class<?> declaringClass = kind.toBoxedJavaClass();
         Class<?> type = kind.toJavaClass();
         Registration r = new Registration(plugins, declaringClass);
@@ -54,6 +55,8 @@
                     return true;
                 }
             });
+        } else {
+            r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
         }
         if (arch.getFlags().contains(AMD64.Flag.UseCountTrailingZerosInstruction)) {
             r.register1("numberOfTrailingZeros", type, new InvocationPlugin() {
@@ -67,6 +70,8 @@
                     return true;
                 }
             });
+        } else {
+            r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
         }
     }
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/graal/com.oracle.graal.replacements.sparc/src/com/oracle/graal/replacements/sparc/SPARCGraphBuilderPlugins.java	Tue Apr 07 17:32:26 2015 +0200
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2015, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+package com.oracle.graal.replacements.sparc;
+
+import com.oracle.graal.api.meta.*;
+import com.oracle.graal.graphbuilderconf.GraphBuilderConfiguration.Plugins;
+import com.oracle.graal.graphbuilderconf.*;
+import com.oracle.graal.graphbuilderconf.InvocationPlugins.Registration;
+import com.oracle.graal.replacements.*;
+
+public class SPARCGraphBuilderPlugins {
+
+    public static void register(Plugins plugins) {
+        InvocationPlugins invocationPlugins = plugins.getInvocationPlugins();
+        registerIntegerLongPlugins(invocationPlugins, IntegerSubstitutions.class, Kind.Int);
+        registerIntegerLongPlugins(invocationPlugins, LongSubstitutions.class, Kind.Long);
+    }
+
+    private static void registerIntegerLongPlugins(InvocationPlugins plugins, Class<?> substituteDeclaringClass, Kind kind) {
+        Class<?> declaringClass = kind.toBoxedJavaClass();
+        Class<?> type = kind.toJavaClass();
+        Registration r = new Registration(plugins, declaringClass);
+        r.registerMethodSubstitution(substituteDeclaringClass, "numberOfLeadingZeros", type);
+        r.registerMethodSubstitution(substituteDeclaringClass, "numberOfTrailingZeros", type);
+    }
+}
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntrinsicGraphBuilder.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/IntrinsicGraphBuilder.java	Tue Apr 07 17:32:26 2015 +0200
@@ -207,4 +207,8 @@
         }
         return null;
     }
+
+    public void intrinsify(ResolvedJavaMethod targetMethod, ResolvedJavaMethod substitute, ValueNode[] args) {
+        throw GraalInternalError.shouldNotReachHere();
+    }
 }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/ReplacementsImpl.java	Tue Apr 07 17:32:26 2015 +0200
@@ -337,17 +337,23 @@
 
     @Override
     public StructuredGraph getSubstitution(ResolvedJavaMethod original, boolean fromBytecodeOnly) {
+        ResolvedJavaMethod substitute = null;
         if (!fromBytecodeOnly) {
             InvocationPlugin plugin = graphBuilderPlugins.getInvocationPlugins().lookupInvocation(original);
-            if (plugin != null) {
+            if (plugin instanceof MethodSubstitutionPlugin) {
+                MethodSubstitutionPlugin msplugin = (MethodSubstitutionPlugin) plugin;
+                substitute = msplugin.getSubstitute(providers.getMetaAccess());
+            } else if (plugin != null) {
                 StructuredGraph graph = new IntrinsicGraphBuilder(providers, snippetReflection, original).buildGraph(plugin);
                 if (graph != null) {
                     return graph;
                 }
             }
         }
-        ClassReplacements cr = getClassReplacements(original.getDeclaringClass().getName());
-        ResolvedJavaMethod substitute = cr == null ? null : cr.methodSubstitutions.get(original);
+        if (substitute == null) {
+            ClassReplacements cr = getClassReplacements(original.getDeclaringClass().getName());
+            substitute = cr == null ? null : cr.methodSubstitutions.get(original);
+        }
         if (substitute == null) {
             return null;
         }
--- a/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Mon Apr 06 13:14:01 2015 +0200
+++ b/graal/com.oracle.graal.replacements/src/com/oracle/graal/replacements/StandardGraphBuilderPlugins.java	Tue Apr 07 17:32:26 2015 +0200
@@ -645,7 +645,7 @@
         String[] names = {"org.openjdk.jmh.infra.Blackhole", "org.openjdk.jmh.logic.BlackHole"};
         for (String name : names) {
             Class<?> blackholeClass;
-            blackholeClass = ReplacementsImpl.resolveClass(name, true);
+            blackholeClass = MethodSubstitutionPlugin.resolveClass(name, true);
             if (blackholeClass != null) {
                 Registration r = new Registration(plugins, blackholeClass);
                 for (Kind kind : Kind.values()) {
--- a/mx/suite.py	Mon Apr 06 13:14:01 2015 +0200
+++ b/mx/suite.py	Tue Apr 07 17:32:26 2015 +0200
@@ -389,7 +389,10 @@
     "com.oracle.graal.hotspot.sparc" : {
       "subDir" : "graal",
       "sourceDirs" : ["src"],
-      "dependencies" : ["com.oracle.graal.compiler.sparc"],
+      "dependencies" : [
+        "com.oracle.graal.compiler.sparc",
+        "com.oracle.graal.replacements.sparc",
+      ],
       "checkstyle" : "com.oracle.graal.graph",
       "annotationProcessors" : ["com.oracle.graal.service.processor"],
       "javaCompliance" : "1.8",
@@ -602,6 +605,18 @@
       "workingSets" : "Graal,Replacements,AMD64",
     },
 
+    "com.oracle.graal.replacements.sparc" : {
+      "subDir" : "graal",
+      "sourceDirs" : ["src"],
+      "dependencies" : [
+          "com.oracle.graal.replacements",
+          "com.oracle.graal.sparc",
+          ],
+      "checkstyle" : "com.oracle.graal.graph",
+      "javaCompliance" : "1.8",
+      "workingSets" : "Graal,Replacements,SPARC",
+    },
+
     "com.oracle.graal.replacements.test" : {
       "subDir" : "graal",
       "sourceDirs" : ["src"],