diff --git a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/RegisterAllocationPhase.java b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/RegisterAllocationPhase.java new file mode 100644 index 000000000000..b37dea5a25ba --- /dev/null +++ b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/RegisterAllocationPhase.java @@ -0,0 +1,40 @@ +/* + * Copyright (c) 2018, 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 org.graalvm.compiler.lir.alloc; + +import org.graalvm.compiler.lir.phases.AllocationPhase; + +/** + * Marker class for register allocation phases. + */ +public abstract class RegisterAllocationPhase extends AllocationPhase { + private boolean neverSpillConstants; + + public void setNeverSpillConstants(boolean neverSpillConstants) { + this.neverSpillConstants = neverSpillConstants; + } + + public boolean getNeverSpillConstants() { + return neverSpillConstants; + } +} diff --git a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanPhase.java b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanPhase.java index e54c744ac444..8eada1c4fbe0 100644 --- a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanPhase.java +++ b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScanPhase.java @@ -23,26 +23,20 @@ package org.graalvm.compiler.lir.alloc.lsra; import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; +import org.graalvm.compiler.lir.alloc.RegisterAllocationPhase; import org.graalvm.compiler.lir.alloc.lsra.ssa.SSALinearScan; import org.graalvm.compiler.lir.gen.LIRGenerationResult; import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; -import org.graalvm.compiler.lir.phases.AllocationPhase; import jdk.vm.ci.code.TargetDescription; -public final class LinearScanPhase extends AllocationPhase { - - private boolean neverSpillConstants; - - public void setNeverSpillConstants(boolean neverSpillConstants) { - this.neverSpillConstants = neverSpillConstants; - } +public final class LinearScanPhase extends RegisterAllocationPhase { @Override protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) { MoveFactory spillMoveFactory = context.spillMoveFactory; RegisterAllocationConfig registerAllocationConfig = context.registerAllocationConfig; - final LinearScan allocator = new SSALinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, lirGenRes.getLIR().linearScanOrder(), neverSpillConstants); + final LinearScan allocator = new SSALinearScan(target, lirGenRes, spillMoveFactory, registerAllocationConfig, lirGenRes.getLIR().linearScanOrder(), getNeverSpillConstants()); allocator.allocate(target, lirGenRes, context); } } diff --git a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java index b05b8c6023f8..eb7a1d7763cb 100644 --- a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java +++ b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/trace/TraceRegisterAllocationPhase.java @@ -30,10 +30,10 @@ import org.graalvm.compiler.debug.DebugContext; import org.graalvm.compiler.debug.Indent; import org.graalvm.compiler.lir.LIR; +import org.graalvm.compiler.lir.alloc.RegisterAllocationPhase; import org.graalvm.compiler.lir.alloc.trace.TraceAllocationPhase.TraceAllocationContext; import org.graalvm.compiler.lir.gen.LIRGenerationResult; import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; -import org.graalvm.compiler.lir.phases.AllocationPhase; import org.graalvm.compiler.lir.ssa.SSAUtil; import org.graalvm.compiler.options.Option; import org.graalvm.compiler.options.OptionKey; @@ -47,7 +47,7 @@ * "Trace-based Register Allocation in a JIT * Compiler" by Josef Eisl et al. */ -public final class TraceRegisterAllocationPhase extends AllocationPhase { +public final class TraceRegisterAllocationPhase extends RegisterAllocationPhase { public static class Options { // @formatter:off @@ -67,9 +67,20 @@ public static class Options { public static final CounterKey globalStackSlots = DebugContext.counter("TraceRA[GlobalStackSlots]"); public static final CounterKey allocatedStackSlots = DebugContext.counter("TraceRA[AllocatedStackSlots]"); + private final TraceBuilderPhase traceBuilder; + private final GlobalLivenessAnalysisPhase livenessAnalysis; + + public TraceRegisterAllocationPhase() { + this.traceBuilder = new TraceBuilderPhase(); + this.livenessAnalysis = new GlobalLivenessAnalysisPhase(); + } + @Override @SuppressWarnings("try") protected void run(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) { + traceBuilder.apply(target, lirGenRes, context); + livenessAnalysis.apply(target, lirGenRes, context); + MoveFactory spillMoveFactory = context.spillMoveFactory; RegisterAllocationConfig registerAllocationConfig = context.registerAllocationConfig; LIR lir = lirGenRes.getLIR(); @@ -80,8 +91,8 @@ protected void run(TargetDescription target, LIRGenerationResult lirGenRes, Allo TraceAllocationContext traceContext = new TraceAllocationContext(spillMoveFactory, registerAllocationConfig, resultTraces, livenessInfo); AllocatableValue[] cachedStackSlots = Options.TraceRACacheStackSlots.getValue(lir.getOptions()) ? new AllocatableValue[lir.numVariables()] : null; - // currently this is not supported - boolean neverSpillConstant = false; + boolean neverSpillConstant = getNeverSpillConstants(); + assert !neverSpillConstant : "currently this is not supported"; final TraceRegisterAllocationPolicy plan = DefaultTraceRegisterAllocationPolicy.allocationPolicy(target, lirGenRes, spillMoveFactory, registerAllocationConfig, cachedStackSlots, resultTraces, neverSpillConstant, livenessInfo, lir.getOptions()); diff --git a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/AllocationStage.java b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/AllocationStage.java index 1072b3e8b92a..63360c8c06ad 100644 --- a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/AllocationStage.java +++ b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/AllocationStage.java @@ -27,8 +27,6 @@ import org.graalvm.compiler.debug.Assertions; import org.graalvm.compiler.lir.alloc.AllocationStageVerifier; import org.graalvm.compiler.lir.alloc.lsra.LinearScanPhase; -import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessAnalysisPhase; -import org.graalvm.compiler.lir.alloc.trace.TraceBuilderPhase; import org.graalvm.compiler.lir.alloc.trace.TraceRegisterAllocationPhase; import org.graalvm.compiler.lir.dfa.LocationMarkerPhase; import org.graalvm.compiler.lir.dfa.MarkBasePointersPhase; @@ -42,8 +40,6 @@ public class AllocationStage extends LIRPhaseSuite { public AllocationStage(OptionValues options) { appendPhase(new MarkBasePointersPhase()); if (TraceRA.getValue(options)) { - appendPhase(new TraceBuilderPhase()); - appendPhase(new GlobalLivenessAnalysisPhase()); appendPhase(new TraceRegisterAllocationPhase()); } else { appendPhase(new LinearScanPhase()); diff --git a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/EconomyAllocationStage.java b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/EconomyAllocationStage.java index 1a74fb46b161..31e250a040fd 100644 --- a/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/EconomyAllocationStage.java +++ b/compiler/src/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/phases/EconomyAllocationStage.java @@ -25,8 +25,6 @@ import static org.graalvm.compiler.core.common.GraalOptions.TraceRA; import org.graalvm.compiler.lir.alloc.lsra.LinearScanPhase; -import org.graalvm.compiler.lir.alloc.trace.GlobalLivenessAnalysisPhase; -import org.graalvm.compiler.lir.alloc.trace.TraceBuilderPhase; import org.graalvm.compiler.lir.alloc.trace.TraceRegisterAllocationPhase; import org.graalvm.compiler.lir.dfa.LocationMarkerPhase; import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; @@ -36,8 +34,6 @@ public class EconomyAllocationStage extends LIRPhaseSuite { public EconomyAllocationStage(OptionValues options) { if (TraceRA.getValue(options)) { - appendPhase(new TraceBuilderPhase()); - appendPhase(new GlobalLivenessAnalysisPhase()); appendPhase(new TraceRegisterAllocationPhase()); } else { appendPhase(new LinearScanPhase()); diff --git a/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/Suites.java b/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/Suites.java index 2a96d27dd088..2a1c036bb8be 100644 --- a/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/Suites.java +++ b/compiler/src/org.graalvm.compiler.phases/src/org/graalvm/compiler/phases/tiers/Suites.java @@ -22,6 +22,10 @@ */ package org.graalvm.compiler.phases.tiers; +import org.graalvm.compiler.lir.alloc.RegisterAllocationPhase; +import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; +import org.graalvm.compiler.lir.phases.LIRPhase; +import org.graalvm.compiler.lir.phases.LIRPhaseSuite; import org.graalvm.compiler.lir.phases.LIRSuites; import org.graalvm.compiler.options.OptionValues; import org.graalvm.compiler.phases.PhaseSuite; @@ -56,7 +60,25 @@ public static Suites createSuites(CompilerConfiguration config, OptionValues opt } public static LIRSuites createLIRSuites(CompilerConfiguration config, OptionValues options) { - return new LIRSuites(config.createPreAllocationOptimizationStage(options), config.createAllocationStage(options), config.createPostAllocationOptimizationStage(options)); + LIRPhaseSuite allocationStage = config.createAllocationStage(options); + assert verifyAllocationStage(allocationStage); + return new LIRSuites(config.createPreAllocationOptimizationStage(options), allocationStage, config.createPostAllocationOptimizationStage(options)); + } + + private static boolean verifyAllocationStage(LIRPhaseSuite allocationStage) { + boolean allocationPhase = false; + for (LIRPhase phase : allocationStage.getPhases()) { + if (phase instanceof RegisterAllocationPhase) { + if (allocationPhase) { + assert false : "More than one register allocation phase"; + return false; + } + allocationPhase = true; + } + + } + assert allocationPhase : "No register allocation phase"; + return allocationPhase; } public boolean isImmutable() { diff --git a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java index 410ceebbcefe..4049e4a16abe 100644 --- a/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java +++ b/substratevm/src/com.oracle.svm.hosted/src/com/oracle/svm/hosted/code/CompileQueue.java @@ -59,7 +59,7 @@ import org.graalvm.compiler.graph.Node; import org.graalvm.compiler.graph.Node.NodeIntrinsic; import org.graalvm.compiler.lir.RedundantMoveElimination; -import org.graalvm.compiler.lir.alloc.lsra.LinearScanPhase; +import org.graalvm.compiler.lir.alloc.RegisterAllocationPhase; import org.graalvm.compiler.lir.asm.CompilationResultBuilder; import org.graalvm.compiler.lir.asm.CompilationResultBuilderFactory; import org.graalvm.compiler.lir.asm.DataBuilder; @@ -983,7 +983,7 @@ protected void removeDeoptTargetOptimizations(Suites suites) { private static void removeDeoptTargetOptimizations(LIRSuites lirSuites) { lirSuites.getPostAllocationOptimizationStage().findPhase(RedundantMoveElimination.class).remove(); - lirSuites.getAllocationStage().findPhaseInstance(LinearScanPhase.class).setNeverSpillConstants(true); + lirSuites.getAllocationStage().findPhaseInstance(RegisterAllocationPhase.class).setNeverSpillConstants(true); } private static boolean verifyDeoptTarget(HostedMethod method, CompilationResult result) {