# HG changeset patch # User Josef Eisl # Date 1453287512 -3600 # Node ID 859766efc59e1c8f85b6a108a958f18c8a6505f6 # Parent da555eeb09af039a69676de501bd2eae218b3aba TraceRA: introduce Trace class. diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/Trace.java --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/Trace.java Wed Jan 20 11:58:32 2016 +0100 @@ -0,0 +1,57 @@ +/* + * Copyright (c) 2016, 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 com.oracle.graal.compiler.common.alloc; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; + +import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; + +/** + * Represents a list of sequentially executed {@code AbstractBlockBase blocks}. + */ +public class Trace> { + private final List blocks; + + public Trace(Collection blocks) { + this.blocks = new ArrayList<>(blocks); + } + + public Trace(List blocks) { + this.blocks = blocks; + } + + public List getBlocks() { + return blocks; + } + + public int size() { + return getBlocks().size(); + } + + @Override + public String toString() { + return "Trace" + blocks; + } +} diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceBuilder.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceBuilder.java Tue Jan 19 18:46:15 2016 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceBuilder.java Wed Jan 20 11:58:32 2016 +0100 @@ -74,13 +74,13 @@ @SuppressWarnings("try") private TraceBuilderResult build(T startBlock) { try (Indent indent = Debug.logAndIndent("start trace building: " + startBlock)) { - ArrayList> traces = buildTraces(startBlock); + ArrayList> traces = buildTraces(startBlock); return new TraceBuilderResult<>(traces, blockToTrace); } } - protected ArrayList> buildTraces(T startBlock) { - ArrayList> traces = new ArrayList<>(); + protected ArrayList> buildTraces(T startBlock) { + ArrayList> traces = new ArrayList<>(); // add start block worklist.add(startBlock); // process worklist @@ -88,7 +88,7 @@ T block = worklist.poll(); assert block != null; if (!processed(block)) { - traces.add(startTrace(block, traces.size())); + traces.add(new Trace<>(startTrace(block, traces.size()))); } } return traces; diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceBuilderResult.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceBuilderResult.java Tue Jan 19 18:46:15 2016 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceBuilderResult.java Wed Jan 20 11:58:32 2016 +0100 @@ -23,15 +23,16 @@ package com.oracle.graal.compiler.common.alloc; import java.util.BitSet; +import java.util.Iterator; import java.util.List; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; public final class TraceBuilderResult> { - private final List> traces; + private final List> traces; private final int[] blockToTrace; - TraceBuilderResult(List> traces, int[] blockToTrace) { + TraceBuilderResult(List> traces, int[] blockToTrace) { this.traces = traces; this.blockToTrace = blockToTrace; } @@ -40,26 +41,28 @@ return blockToTrace[block.getId()]; } - public List> getTraces() { + public List> getTraces() { return traces; } public boolean incomingEdges(int traceNr) { - List trace = getTraces().get(traceNr); - return incomingEdges(traceNr, trace); + Iterator traceIt = getTraces().get(traceNr).getBlocks().iterator(); + return incomingEdges(traceNr, traceIt); } public boolean incomingSideEdges(int traceNr) { - List trace = getTraces().get(traceNr); - if (trace.size() <= 1) { + Iterator traceIt = getTraces().get(traceNr).getBlocks().iterator(); + if (!traceIt.hasNext()) { return false; } - return incomingEdges(traceNr, trace.subList(1, trace.size())); + traceIt.next(); + return incomingEdges(traceNr, traceIt); } - private boolean incomingEdges(int traceNr, List trace) { + private boolean incomingEdges(int traceNr, Iterator trace) { /* TODO (je): not efficient. find better solution. */ - for (T block : trace) { + while (trace.hasNext()) { + T block = trace.next(); for (T pred : block.getPredecessors()) { if (getTraceForBlock(pred) != traceNr) { return true; @@ -70,11 +73,11 @@ } public static > boolean verify(TraceBuilderResult traceBuilderResult, int expectedLength) { - List> traces = traceBuilderResult.getTraces(); + List> traces = traceBuilderResult.getTraces(); assert verifyAllBlocksScheduled(traceBuilderResult, expectedLength) : "Not all blocks assigned to traces!"; - for (List trace : traces) { + for (Trace trace : traces) { T last = null; - for (T current : trace) { + for (T current : trace.getBlocks()) { assert last == null || current.getPredecessors().contains(last); last = current; } @@ -83,10 +86,10 @@ } private static > boolean verifyAllBlocksScheduled(TraceBuilderResult traceBuilderResult, int expectedLength) { - List> traces = traceBuilderResult.getTraces(); + List> traces = traceBuilderResult.getTraces(); BitSet handled = new BitSet(expectedLength); - for (List trace : traces) { - for (T block : trace) { + for (Trace trace : traces) { + for (T block : trace.getBlocks()) { handled.set(block.getId()); } } diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceStatisticsPrinter.java --- a/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceStatisticsPrinter.java Tue Jan 19 18:46:15 2016 +0100 +++ b/graal/com.oracle.graal.compiler.common/src/com/oracle/graal/compiler/common/alloc/TraceStatisticsPrinter.java Wed Jan 20 11:58:32 2016 +0100 @@ -46,7 +46,7 @@ @SuppressWarnings("try") protected static > void print(TraceBuilderResult result, String compilationUnitName) { - List> traces = result.getTraces(); + List> traces = result.getTraces(); int numTraces = traces.size(); try (Indent indent0 = Debug.logAndIndent(TRACE_DUMP_LEVEL, "")) { @@ -54,7 +54,7 @@ try (Indent indent1 = Debug.logAndIndent(TRACE_DUMP_LEVEL, "")) { printRawLine("tracenumber", "total", "min", "max", "numBlocks"); for (int i = 0; i < numTraces; i++) { - List t = traces.get(i); + List t = traces.get(i).getBlocks(); double total = 0; double max = Double.NEGATIVE_INFINITY; double min = Double.POSITIVE_INFINITY; diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceAllocationPhase.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceAllocationPhase.java Tue Jan 19 18:46:15 2016 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceAllocationPhase.java Wed Jan 20 11:58:32 2016 +0100 @@ -22,11 +22,18 @@ */ package com.oracle.graal.lir.alloc.trace; +import java.util.List; + import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig; +import com.oracle.graal.compiler.common.alloc.Trace; import com.oracle.graal.compiler.common.alloc.TraceBuilderResult; +import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; +import com.oracle.graal.lir.gen.LIRGenerationResult; import com.oracle.graal.lir.gen.LIRGeneratorTool.MoveFactory; import com.oracle.graal.lir.phases.LIRPhase; +import jdk.vm.ci.code.TargetDescription; + public abstract class TraceAllocationPhase extends LIRPhase { public static final class TraceAllocationContext { @@ -41,4 +48,26 @@ } } + public final > void apply(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, Trace trace, TraceAllocationContext context, + boolean dumpLIR) { + apply(target, lirGenRes, codeEmittingOrder, trace.getBlocks(), context, dumpLIR); + } + + public final > void apply(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, Trace trace, TraceAllocationContext context) { + apply(target, lirGenRes, codeEmittingOrder, trace.getBlocks(), context); + } + + @Override + protected final > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List sortedBlocks, TraceAllocationContext context) { + TraceBuilderResult resultTraces = getTraceBuilderResult(context); + Trace trace = resultTraces.getTraces().get(resultTraces.getTraceForBlock(sortedBlocks.get(0))); + run(target, lirGenRes, codeEmittingOrder, trace, context); + } + + @SuppressWarnings("unchecked") + private static > TraceBuilderResult getTraceBuilderResult(TraceAllocationContext context) { + return (TraceBuilderResult) context.resultTraces; + } + + protected abstract > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, Trace trace, TraceAllocationContext context); } diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java Tue Jan 19 18:46:15 2016 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceGlobalMoveResolutionPhase.java Wed Jan 20 11:58:32 2016 +0100 @@ -31,12 +31,7 @@ import java.util.List; -import jdk.vm.ci.code.Architecture; -import jdk.vm.ci.code.RegisterValue; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.Value; - +import com.oracle.graal.compiler.common.alloc.Trace; import com.oracle.graal.compiler.common.alloc.TraceBuilderResult; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; import com.oracle.graal.debug.Debug; @@ -48,6 +43,12 @@ import com.oracle.graal.lir.ssa.SSAUtil.PhiValueVisitor; import com.oracle.graal.lir.ssi.SSIUtil; +import jdk.vm.ci.code.Architecture; +import jdk.vm.ci.code.RegisterValue; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.Value; + public final class TraceGlobalMoveResolutionPhase extends TraceAllocationPhase { /** @@ -58,7 +59,7 @@ } @Override - protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List linearScanOrder, TraceAllocationContext context) { + protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, Trace trace, TraceAllocationContext context) { MoveFactory spillMoveFactory = context.spillMoveFactory; resolveGlobalDataFlow(context.resultTraces, lirGenRes, spillMoveFactory, target.arch); } @@ -75,8 +76,8 @@ }; try (Indent indent = Debug.logAndIndent("Trace global move resolution")) { - for (List trace : resultTraces.getTraces()) { - for (AbstractBlockBase fromBlock : trace) { + for (Trace trace : resultTraces.getTraces()) { + for (AbstractBlockBase fromBlock : trace.getBlocks()) { for (AbstractBlockBase toBlock : fromBlock.getSuccessors()) { if (resultTraces.getTraceForBlock(fromBlock) != resultTraces.getTraceForBlock(toBlock)) { try (Indent indent0 = Debug.logAndIndent("Handle trace edge from %s (Trace%d) to %s (Trace%d)", fromBlock, resultTraces.getTraceForBlock(fromBlock), toBlock, diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java Tue Jan 19 18:46:15 2016 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceRegisterAllocationPhase.java Wed Jan 20 11:58:32 2016 +0100 @@ -22,9 +22,11 @@ */ package com.oracle.graal.lir.alloc.trace; +import java.util.Collection; import java.util.List; import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig; +import com.oracle.graal.compiler.common.alloc.Trace; import com.oracle.graal.compiler.common.alloc.TraceBuilderResult; import com.oracle.graal.compiler.common.alloc.TraceStatisticsPrinter; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; @@ -92,7 +94,7 @@ Debug.dump(lir, "Before TraceRegisterAllocation"); int traceNumber = 0; - for (List trace : resultTraces.getTraces()) { + for (Trace trace : resultTraces.getTraces()) { try (Indent i = Debug.logAndIndent("Allocating Trace%d: %s", traceNumber, trace); Scope s = Debug.scope("AllocateTrace", trace)) { tracesMetric.increment(); if (trivialTracesMetric.isEnabled() && isTrivialTrace(lir, trace)) { @@ -110,7 +112,7 @@ } catch (Throwable e) { throw Debug.handle(e); } - unnumberInstructions(trace, lir); + unnumberInstructions(trace.getBlocks(), lir); } Debug.dump(lir, "After trace allocation"); @@ -127,9 +129,9 @@ assert TraceBuilderResult.verify(resultTraces, lirGenRes.getLIR().getControlFlowGraph().getBlocks().size()); if (Debug.isLogEnabled(TRACE_LOG_LEVEL)) { - List> traces = resultTraces.getTraces(); + List> traces = resultTraces.getTraces(); for (int i = 0; i < traces.size(); i++) { - List trace = traces.get(i); + Trace trace = traces.get(i); Debug.log(TRACE_LOG_LEVEL, "Trace %5d: %s", i, trace); } } @@ -158,11 +160,11 @@ } } - static boolean isTrivialTrace(LIR lir, List> trace) { + static boolean isTrivialTrace(LIR lir, Trace> trace) { if (trace.size() != 1) { return false; } - List instructions = lir.getLIRforBlock(trace.iterator().next()); + List instructions = lir.getLIRforBlock(trace.getBlocks().iterator().next()); if (instructions.size() != 2) { return false; } @@ -174,7 +176,7 @@ return instructions.get(1) instanceof JumpOp; } - private static void unnumberInstructions(List> trace, LIR lir) { + private static void unnumberInstructions(Collection> trace, LIR lir) { for (AbstractBlockBase block : trace) { for (LIRInstruction op : lir.getLIRforBlock(block)) { op.setId(-1); diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceTrivialAllocator.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceTrivialAllocator.java Tue Jan 19 18:46:15 2016 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/TraceTrivialAllocator.java Wed Jan 20 11:58:32 2016 +0100 @@ -28,9 +28,7 @@ import java.util.List; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.meta.Value; - +import com.oracle.graal.compiler.common.alloc.Trace; import com.oracle.graal.compiler.common.alloc.TraceBuilderResult; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; import com.oracle.graal.lir.LIR; @@ -44,6 +42,9 @@ import com.oracle.graal.lir.ssi.SSIUtil; import com.oracle.graal.lir.util.VariableVirtualStackValueMap; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.meta.Value; + /** * Allocates a trivial trace i.e. a trace consisting of a single block with no instructions other * than the {@link LabelOp} and the {@link JumpOp}. @@ -51,11 +52,11 @@ final class TraceTrivialAllocator extends TraceAllocationPhase { @Override - protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, List trace, TraceAllocationContext context) { + protected > void run(TargetDescription target, LIRGenerationResult lirGenRes, List codeEmittingOrder, Trace trace, TraceAllocationContext context) { LIR lir = lirGenRes.getLIR(); TraceBuilderResult resultTraces = context.resultTraces; assert isTrivialTrace(lir, trace) : "Not a trivial trace! " + trace; - B block = trace.iterator().next(); + B block = trace.getBlocks().iterator().next(); AbstractBlockBase pred = TraceUtil.getBestTraceInterPredecessor(resultTraces, block); diff -r da555eeb09af -r 859766efc59e graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/lsra/TraceLinearScan.java --- a/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/lsra/TraceLinearScan.java Tue Jan 19 18:46:15 2016 +0100 +++ b/graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/trace/lsra/TraceLinearScan.java Wed Jan 20 11:58:32 2016 +0100 @@ -36,17 +36,8 @@ import java.util.EnumSet; import java.util.List; -import jdk.vm.ci.code.BailoutException; -import jdk.vm.ci.code.Register; -import jdk.vm.ci.code.RegisterAttributes; -import jdk.vm.ci.code.RegisterValue; -import jdk.vm.ci.code.TargetDescription; -import jdk.vm.ci.common.JVMCIError; -import jdk.vm.ci.meta.AllocatableValue; -import jdk.vm.ci.meta.LIRKind; -import jdk.vm.ci.meta.Value; - import com.oracle.graal.compiler.common.alloc.RegisterAllocationConfig; +import com.oracle.graal.compiler.common.alloc.Trace; import com.oracle.graal.compiler.common.alloc.TraceBuilderResult; import com.oracle.graal.compiler.common.cfg.AbstractBlockBase; import com.oracle.graal.compiler.common.cfg.BlockMap; @@ -72,10 +63,20 @@ import com.oracle.graal.options.OptionType; import com.oracle.graal.options.OptionValue; +import jdk.vm.ci.code.BailoutException; +import jdk.vm.ci.code.Register; +import jdk.vm.ci.code.RegisterAttributes; +import jdk.vm.ci.code.RegisterValue; +import jdk.vm.ci.code.TargetDescription; +import jdk.vm.ci.common.JVMCIError; +import jdk.vm.ci.meta.AllocatableValue; +import jdk.vm.ci.meta.LIRKind; +import jdk.vm.ci.meta.Value; + /** * An implementation of the linear scan register allocator algorithm described in "Optimized Interval Splitting in a Linear Scan Register Allocator" by Christian Wimmer and + * href="http://doi.acm.org/10.1145/1064979.1064998" > + * "Optimized Interval Splitting in a Linear Scan Register Allocator" by Christian Wimmer and * Hanspeter Moessenboeck. */ public final class TraceLinearScan { @@ -186,12 +187,12 @@ protected final TraceBuilderResult traceBuilderResult; private final boolean neverSpillConstants; - public TraceLinearScan(TargetDescription target, LIRGenerationResult res, MoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig, List> sortedBlocks, + public TraceLinearScan(TargetDescription target, LIRGenerationResult res, MoveFactory spillMoveFactory, RegisterAllocationConfig regAllocConfig, Trace> trace, TraceBuilderResult traceBuilderResult, boolean neverSpillConstants) { this.ir = res.getLIR(); this.moveFactory = spillMoveFactory; this.frameMapBuilder = res.getFrameMapBuilder(); - this.sortedBlocks = sortedBlocks; + this.sortedBlocks = trace.getBlocks(); this.registerAttributes = regAllocConfig.getRegisterConfig().getAttributesMap(); this.regAllocConfig = regAllocConfig;