# HG changeset patch # User Josef Eisl # Date 1447258446 -3600 # Node ID 6c37ffb6887b7037e7d8489eb9c44e7029d07c5f # Parent 9e5a47e3c94c6c21409a487585cc7218df0915cb TraceRA: add option for spill move elimination. diff -r 9e5a47e3c94c -r 6c37ffb6887b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java Fri Nov 06 17:50:57 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScan.java Wed Nov 11 17:14:06 2015 +0100 @@ -45,6 +45,10 @@ import jdk.vm.ci.meta.AllocatableValue; import jdk.vm.ci.meta.LIRKind; import jdk.vm.ci.meta.Value; +import jdk.vm.ci.options.NestedBooleanOptionValue; +import jdk.vm.ci.options.Option; +import jdk.vm.ci.options.OptionType; +import jdk.vm.ci.options.OptionValue; import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig; import com.oracle.graal.compiler.common.alloc.TraceBuilder.TraceBuilderResult; @@ -64,6 +68,7 @@ import com.oracle.graal.lir.framemap.FrameMapBuilder; import com.oracle.graal.lir.gen.LIRGenerationResult; import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory; +import com.oracle.graal.lir.phases.LIRPhase; /** * An implementation of the linear scan register allocator algorithm described in LIROptTraceRAEliminateSpillMoves = new NestedBooleanOptionValue(LIRPhase.Options.LIROptimization, true); + // @formatter:on + } + private static final TraceLinearScanRegisterAllocationPhase TRACE_LINEAR_SCAN_REGISTER_ALLOCATION_PHASE = new TraceLinearScanRegisterAllocationPhase(); private static final TraceLinearScanAssignLocationsPhase TRACE_LINEAR_SCAN_ASSIGN_LOCATIONS_PHASE = new TraceLinearScanAssignLocationsPhase(); private static final TraceLinearScanEliminateSpillMovePhase TRACE_LINEAR_SCAN_ELIMINATE_SPILL_MOVE_PHASE = new TraceLinearScanEliminateSpillMovePhase(); @@ -736,8 +748,10 @@ Debug.dump(TraceRegisterAllocationPhase.TRACE_DUMP_LEVEL, sortedBlocks(), "%s", TRACE_LINEAR_SCAN_RESOLVE_DATA_FLOW_PHASE.getName()); // eliminate spill moves - TRACE_LINEAR_SCAN_ELIMINATE_SPILL_MOVE_PHASE.apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, context, false); - Debug.dump(TraceRegisterAllocationPhase.TRACE_DUMP_LEVEL, sortedBlocks(), "%s", TRACE_LINEAR_SCAN_ELIMINATE_SPILL_MOVE_PHASE.getName()); + if (Options.LIROptTraceRAEliminateSpillMoves.getValue()) { + TRACE_LINEAR_SCAN_ELIMINATE_SPILL_MOVE_PHASE.apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, context, false); + Debug.dump(TraceRegisterAllocationPhase.TRACE_DUMP_LEVEL, sortedBlocks(), "%s", TRACE_LINEAR_SCAN_ELIMINATE_SPILL_MOVE_PHASE.getName()); + } TRACE_LINEAR_SCAN_ASSIGN_LOCATIONS_PHASE.apply(target, lirGenRes, codeEmittingOrder, linearScanOrder, context, false); diff -r 9e5a47e3c94c -r 6c37ffb6887b graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java Fri Nov 06 17:50:57 2015 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceLinearScanWalker.java Wed Nov 11 17:14:06 2015 +0100 @@ -559,44 +559,48 @@ // called during register allocation private void changeSpillState(TraceInterval interval, int spillPos) { - switch (interval.spillState()) { - case NoSpillStore: { - int defLoopDepth = allocator.blockForId(interval.spillDefinitionPos()).getLoopDepth(); - int spillLoopDepth = allocator.blockForId(spillPos).getLoopDepth(); + if (TraceLinearScan.Options.LIROptTraceRAEliminateSpillMoves.getValue()) { + switch (interval.spillState()) { + case NoSpillStore: { + int defLoopDepth = allocator.blockForId(interval.spillDefinitionPos()).getLoopDepth(); + int spillLoopDepth = allocator.blockForId(spillPos).getLoopDepth(); - if (defLoopDepth < spillLoopDepth) { - /* - * The loop depth of the spilling position is higher then the loop depth at the - * definition of the interval. Move write to memory out of loop. - */ - // store at definition of the interval - interval.setSpillState(SpillState.StoreAtDefinition); - } else { - /* - * The interval is currently spilled only once, so for now there is no reason to - * store the interval at the definition. - */ - interval.setSpillState(SpillState.OneSpillStore); + if (defLoopDepth < spillLoopDepth) { + /* + * The loop depth of the spilling position is higher then the loop depth at + * the definition of the interval. Move write to memory out of loop. + */ + // store at definition of the interval + interval.setSpillState(SpillState.StoreAtDefinition); + } else { + /* + * The interval is currently spilled only once, so for now there is no + * reason to store the interval at the definition. + */ + interval.setSpillState(SpillState.OneSpillStore); + } + break; } - break; - } - case OneSpillStore: { - // It is better to store it to memory at the definition. - interval.setSpillState(SpillState.StoreAtDefinition); - break; - } + case OneSpillStore: { + // It is better to store it to memory at the definition. + interval.setSpillState(SpillState.StoreAtDefinition); + break; + } - case SpillInDominator: - case StoreAtDefinition: - case StartInMemory: - case NoOptimization: - case NoDefinitionFound: - // nothing to do - break; + case SpillInDominator: + case StoreAtDefinition: + case StartInMemory: + case NoOptimization: + case NoDefinitionFound: + // nothing to do + break; - default: - throw new BailoutException("other states not allowed at this time"); + default: + throw new BailoutException("other states not allowed at this time"); + } + } else { + interval.setSpillState(SpillState.NoOptimization); } }