--- old/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java 2017-03-20 17:39:46.000000000 -0700 +++ new/src/jdk.internal.vm.compiler/share/classes/org.graalvm.compiler.lir/src/org/graalvm/compiler/lir/alloc/lsra/LinearScan.java 2017-03-20 17:39:46.000000000 -0700 @@ -22,19 +22,19 @@ */ package org.graalvm.compiler.lir.alloc.lsra; -import static org.graalvm.compiler.core.common.GraalOptions.DetailedAsserts; -import static org.graalvm.compiler.lir.LIRValueUtil.isVariable; -import static org.graalvm.compiler.lir.phases.LIRPhase.Options.LIROptimization; import static jdk.vm.ci.code.CodeUtil.isEven; import static jdk.vm.ci.code.ValueUtil.asRegister; import static jdk.vm.ci.code.ValueUtil.isIllegal; import static jdk.vm.ci.code.ValueUtil.isLegal; import static jdk.vm.ci.code.ValueUtil.isRegister; +import static org.graalvm.compiler.core.common.GraalOptions.DetailedAsserts; +import static org.graalvm.compiler.lir.LIRValueUtil.isVariable; +import static org.graalvm.compiler.lir.phases.LIRPhase.Options.LIROptimization; +import java.util.ArrayList; import java.util.Arrays; import java.util.BitSet; import java.util.EnumSet; -import java.util.List; import org.graalvm.compiler.core.common.LIRKind; import org.graalvm.compiler.core.common.alloc.RegisterAllocationConfig; @@ -56,10 +56,12 @@ import org.graalvm.compiler.lir.gen.LIRGenerationResult; import org.graalvm.compiler.lir.gen.LIRGeneratorTool.MoveFactory; import org.graalvm.compiler.lir.phases.AllocationPhase.AllocationContext; -import org.graalvm.compiler.options.NestedBooleanOptionValue; +import org.graalvm.compiler.options.NestedBooleanOptionKey; import org.graalvm.compiler.options.Option; +import org.graalvm.compiler.options.OptionKey; import org.graalvm.compiler.options.OptionType; -import org.graalvm.compiler.options.OptionValue; +import org.graalvm.compiler.options.OptionValues; +import org.graalvm.util.Pair; import jdk.vm.ci.code.Register; import jdk.vm.ci.code.RegisterArray; @@ -79,7 +81,7 @@ public static class Options { // @formatter:off @Option(help = "Enable spill position optimization", type = OptionType.Debug) - public static final OptionValue LIROptLSRAOptimizeSpillPosition = new NestedBooleanOptionValue(LIROptimization, true); + public static final OptionKey LIROptLSRAOptimizeSpillPosition = new NestedBooleanOptionKey(LIROptimization, true); // @formatter:on } @@ -177,6 +179,13 @@ private int numVariables; private final boolean neverSpillConstants; + /** + * Sentinel interval to denote the end of an interval list. + */ + protected final Interval intervalEndMarker; + public final Range rangeEndMarker; + public final boolean detailedAsserts; + protected LinearScan(TargetDescription target, LIRGenerationResult res, MoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig, AbstractBlockBase[] sortedBlocks, boolean neverSpillConstants) { this.ir = res.getLIR(); @@ -191,6 +200,18 @@ this.numVariables = ir.numVariables(); this.blockData = new BlockMap<>(ir.getControlFlowGraph()); this.neverSpillConstants = neverSpillConstants; + this.rangeEndMarker = new Range(Integer.MAX_VALUE, Integer.MAX_VALUE, null); + this.intervalEndMarker = new Interval(Value.ILLEGAL, Interval.END_MARKER_OPERAND_NUMBER, null, rangeEndMarker); + this.intervalEndMarker.next = intervalEndMarker; + this.detailedAsserts = DetailedAsserts.getValue(ir.getOptions()); + } + + public Interval intervalEndMarker() { + return intervalEndMarker; + } + + public OptionValues getOptions() { + return ir.getOptions(); } public int getFirstLirInstructionId(AbstractBlockBase block) { @@ -200,7 +221,7 @@ } public int getLastLirInstructionId(AbstractBlockBase block) { - List instructions = ir.getLIRforBlock(block); + ArrayList instructions = ir.getLIRforBlock(block); int result = instructions.get(instructions.size() - 1).id(); assert result >= 0; return result; @@ -326,7 +347,7 @@ Interval createInterval(AllocatableValue operand) { assert isLegal(operand); int operandNumber = operandNumber(operand); - Interval interval = new Interval(operand, operandNumber); + Interval interval = new Interval(operand, operandNumber, intervalEndMarker, rangeEndMarker); assert operandNumber < intervalsSize; assert intervals[operandNumber] == null; intervals[operandNumber] = interval; @@ -502,11 +523,11 @@ return newFirst; } - Interval.Pair createUnhandledLists(IntervalPredicate isList1, IntervalPredicate isList2) { + Pair createUnhandledLists(IntervalPredicate isList1, IntervalPredicate isList2) { assert isSorted(sortedIntervals) : "interval list is not sorted"; - Interval list1 = Interval.EndMarker; - Interval list2 = Interval.EndMarker; + Interval list1 = intervalEndMarker; + Interval list2 = intervalEndMarker; Interval list1Prev = null; Interval list2Prev = null; @@ -529,16 +550,16 @@ } if (list1Prev != null) { - list1Prev.next = Interval.EndMarker; + list1Prev.next = intervalEndMarker; } if (list2Prev != null) { - list2Prev.next = Interval.EndMarker; + list2Prev.next = intervalEndMarker; } - assert list1Prev == null || list1Prev.next == Interval.EndMarker : "linear list ends not with sentinel"; - assert list2Prev == null || list2Prev.next == Interval.EndMarker : "linear list ends not with sentinel"; + assert list1Prev == null || list1Prev.next.isEndMarker() : "linear list ends not with sentinel"; + assert list2Prev == null || list2Prev.next.isEndMarker() : "linear list ends not with sentinel"; - return new Interval.Pair(list1, list2); + return Pair.create(list1, list2); } protected void sortIntervalsBeforeAllocation() { @@ -648,13 +669,11 @@ } @SuppressWarnings("try") - protected void allocate(TargetDescription target, LIRGenerationResult lirGenRes, MoveFactory spillMoveFactory, RegisterAllocationConfig registerAllocationConfig) { - + protected void allocate(TargetDescription target, LIRGenerationResult lirGenRes, AllocationContext context) { /* * This is the point to enable debug logging for the whole register allocation. */ try (Indent indent = Debug.logAndIndent("LinearScan allocate")) { - AllocationContext context = new AllocationContext(spillMoveFactory, registerAllocationConfig); createLifetimeAnalysisPhase().apply(target, lirGenRes, context); @@ -663,21 +682,21 @@ createRegisterAllocationPhase().apply(target, lirGenRes, context); - if (LinearScan.Options.LIROptLSRAOptimizeSpillPosition.getValue()) { + if (LinearScan.Options.LIROptLSRAOptimizeSpillPosition.getValue(getOptions())) { createOptimizeSpillPositionPhase().apply(target, lirGenRes, context); } createResolveDataFlowPhase().apply(target, lirGenRes, context); sortIntervalsAfterAllocation(); - if (DetailedAsserts.getValue()) { + if (detailedAsserts) { verify(); } beforeSpillMoveElimination(); createSpillMoveEliminationPhase().apply(target, lirGenRes, context); createAssignLocationsPhase().apply(target, lirGenRes, context); - if (DetailedAsserts.getValue()) { + if (detailedAsserts) { verifyIntervals(); } } catch (Throwable e) { @@ -789,13 +808,13 @@ throw new GraalError(""); } - if (i1.first() == Range.EndMarker) { + if (i1.first().isEndMarker()) { Debug.log("Interval %d has no Range", i1.operandNumber); Debug.log(i1.logString(this)); throw new GraalError(""); } - for (Range r = i1.first(); r != Range.EndMarker; r = r.next) { + for (Range r = i1.first(); !r.isEndMarker(); r = r.next) { if (r.from >= r.to) { Debug.log("Interval %d has zero length range", i1.operandNumber); Debug.log(i1.logString(this)); @@ -850,15 +869,15 @@ Interval fixedIntervals; Interval otherIntervals; - fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).first; + fixedIntervals = createUnhandledLists(IS_PRECOLORED_INTERVAL, null).getLeft(); // to ensure a walking until the last instruction id, add a dummy interval // with a high operation id - otherIntervals = new Interval(Value.ILLEGAL, -1); + otherIntervals = new Interval(Value.ILLEGAL, -1, intervalEndMarker, rangeEndMarker); otherIntervals.addRange(Integer.MAX_VALUE - 2, Integer.MAX_VALUE - 1); IntervalWalker iw = new IntervalWalker(this, fixedIntervals, otherIntervals); for (AbstractBlockBase block : sortedBlocks) { - List instructions = ir.getLIRforBlock(block); + ArrayList instructions = ir.getLIRforBlock(block); for (int j = 0; j < instructions.size(); j++) { LIRInstruction op = instructions.get(j); @@ -872,7 +891,7 @@ * can't handle that correctly. */ if (checkLive) { - for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); interval != Interval.EndMarker; interval = interval.next) { + for (Interval interval = iw.activeLists.get(RegisterBinding.Fixed); !interval.isEndMarker(); interval = interval.next) { if (interval.currentTo() > op.id() + 1) { /* * This interval is live out of this op so make sure that this