changeset 13637:c07c88aca256

added mechanism for a (GPU) backend to override/supply the initial graph in the compilation pipeline
author Doug Simon <doug.simon@oracle.com>
date Wed, 15 Jan 2014 00:33:34 +0100
parents b9a5fa298461
children 1dabd01a73bd
files graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java
diffstat 3 files changed, 72 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Tue Jan 14 19:31:37 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java	Wed Jan 15 00:33:34 2014 +0100
@@ -27,6 +27,7 @@
 import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.compiler.target.*;
+import com.oracle.graal.hotspot.HotSpotReplacementsImpl.GraphProducer;
 import com.oracle.graal.hotspot.bridge.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.hotspot.stubs.*;
@@ -94,6 +95,14 @@
     }
 
     /**
+     * Gets the graph producer provided by this backend (if any). A primary use case for this is a
+     * GPU backend that may want to offload certain methods to the GPU.
+     */
+    public GraphProducer getGraphProducer() {
+        return null;
+    }
+
+    /**
      * Finds all the registers that are defined by some given LIR.
      * 
      * @param lir the LIR to examine
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Tue Jan 14 19:31:37 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java	Wed Jan 15 00:33:34 2014 +0100
@@ -26,9 +26,11 @@
 
 import java.util.*;
 
+import com.oracle.graal.api.code.*;
 import com.oracle.graal.api.meta.*;
 import com.oracle.graal.debug.*;
 import com.oracle.graal.debug.Debug.Scope;
+import com.oracle.graal.hotspot.HotSpotReplacementsImpl.*;
 import com.oracle.graal.hotspot.meta.*;
 import com.oracle.graal.nodes.spi.*;
 
@@ -55,11 +57,13 @@
         final HotSpotLoweringProvider lowerer = (HotSpotLoweringProvider) providers.getLowerer();
         foreignCalls.initialize(providers, config);
         lowerer.initialize(providers, config);
+        HotSpotReplacementsImpl replacements = (HotSpotReplacementsImpl) providers.getReplacements();
+
+        replacements.registerGraphProducers(getNonHostGraphProducers());
 
         // Install intrinsics.
         if (Intrinsify.getValue()) {
             try (Scope s = Debug.scope("RegisterReplacements", new DebugDumpScope("RegisterReplacements"))) {
-                Replacements replacements = providers.getReplacements();
                 ServiceLoader<ReplacementsProvider> sl = ServiceLoader.loadInstalled(ReplacementsProvider.class);
                 for (ReplacementsProvider replacementsProvider : sl) {
                     replacementsProvider.registerReplacements(providers.getMetaAccess(), lowerer, replacements, providers.getCodeCache().getTarget());
@@ -74,5 +78,28 @@
                 throw Debug.handle(e);
             }
         }
+
+    }
+
+    /**
+     * Gets the {@link GraphProducer}s from the non-host backends. These allow a GPU backend (for
+     * example) to offload compilation and execution of certain methods to a GPU.
+     * <p>
+     * Note that is is a very rough initial attempt at providing a hook for a GPU backend to
+     * intercept a compilation (or method inlining) for the purpose of routing execution to the GPU.
+     * Expect it to be extensively refined as experimentation with GPU offload proceeds.
+     */
+    protected GraphProducer[] getNonHostGraphProducers() {
+        List<GraphProducer> list = new ArrayList<>();
+        for (Map.Entry<Class<? extends Architecture>, HotSpotBackend> e : getRuntime().getBackends().entrySet()) {
+            HotSpotBackend value = e.getValue();
+            if (value != this) {
+                GraphProducer gp = value.getGraphProducer();
+                if (gp != null) {
+                    list.add(gp);
+                }
+            }
+        }
+        return list.toArray(new GraphProducer[list.size()]);
     }
 }
--- a/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Tue Jan 14 19:31:37 2014 +0100
+++ b/graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java	Wed Jan 15 00:33:34 2014 +0100
@@ -75,6 +75,41 @@
         return super.registerMethodSubstitution(originalMethod, substituteMethod);
     }
 
+    /**
+     * A producer of graphs for methods.
+     */
+    public interface GraphProducer {
+
+        /**
+         * @returns a graph for {@code method} or null
+         */
+        StructuredGraph getGraphFor(ResolvedJavaMethod method);
+    }
+
+    /**
+     * Registers the graph producers that will take precedence over the registered method
+     * substitutions when {@link #getMethodSubstitution(ResolvedJavaMethod)} is called.
+     */
+    public void registerGraphProducers(GraphProducer[] producers) {
+        assert this.graphProducers == UNINITIALIZED : "graph producers must be registered at most once";
+        this.graphProducers = producers.clone();
+    }
+
+    private static GraphProducer[] UNINITIALIZED = {};
+
+    private GraphProducer[] graphProducers = UNINITIALIZED;
+
+    @Override
+    public StructuredGraph getMethodSubstitution(ResolvedJavaMethod original) {
+        for (GraphProducer gp : graphProducers) {
+            StructuredGraph graph = gp.getGraphFor(original);
+            if (graph != null) {
+                return graph;
+            }
+        }
+        return super.getMethodSubstitution(original);
+    }
+
     @Override
     public Class<? extends FixedWithNextNode> getMacroSubstitution(ResolvedJavaMethod method) {
         HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;