# HG changeset patch # User Doug Simon # Date 1389742414 -3600 # Node ID c07c88aca256e23047dda85782b680fed31fc482 # Parent b9a5fa29846124a20ea7910b1002c0a530157631 added mechanism for a (GPU) backend to override/supply the initial graph in the compilation pipeline diff -r b9a5fa298461 -r c07c88aca256 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotBackend.java --- 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 diff -r b9a5fa298461 -r c07c88aca256 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotHostBackend.java --- 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 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. + *

+ * 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 list = new ArrayList<>(); + for (Map.Entry, 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()]); } } diff -r b9a5fa298461 -r c07c88aca256 graal/com.oracle.graal.hotspot/src/com/oracle/graal/hotspot/HotSpotReplacementsImpl.java --- 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 getMacroSubstitution(ResolvedJavaMethod method) { HotSpotResolvedJavaMethod hsMethod = (HotSpotResolvedJavaMethod) method;