Mercurial > hg > truffle
comparison graal/com.oracle.graal.lir/src/com/oracle/graal/lir/alloc/lsra/LinearScan.java @ 19212:95a7954ea155
Add LinearScanPhase.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Fri, 06 Feb 2015 20:25:14 +0100 |
parents | 39e99cf01468 |
children | 1cf73c50e3dc 4d70d150944f |
comparison
equal
deleted
inserted
replaced
19211:6081b30fe164 | 19212:95a7954ea155 |
---|---|
54 * An implementation of the linear scan register allocator algorithm described in <a | 54 * An implementation of the linear scan register allocator algorithm described in <a |
55 * href="http://doi.acm.org/10.1145/1064979.1064998" | 55 * href="http://doi.acm.org/10.1145/1064979.1064998" |
56 * >"Optimized Interval Splitting in a Linear Scan Register Allocator"</a> by Christian Wimmer and | 56 * >"Optimized Interval Splitting in a Linear Scan Register Allocator"</a> by Christian Wimmer and |
57 * Hanspeter Moessenboeck. | 57 * Hanspeter Moessenboeck. |
58 */ | 58 */ |
59 public final class LinearScan { | 59 final class LinearScan { |
60 | 60 |
61 final TargetDescription target; | 61 final TargetDescription target; |
62 final LIRGenerationResult res; | 62 final LIRGenerationResult res; |
63 final LIR ir; | 63 final LIR ir; |
64 final FrameMapBuilder frameMapBuilder; | 64 final FrameMapBuilder frameMapBuilder; |
107 * an operand is its {@linkplain LinearScan#operandNumber(Value) operand number}. | 107 * an operand is its {@linkplain LinearScan#operandNumber(Value) operand number}. |
108 */ | 108 */ |
109 public BitSet liveKill; | 109 public BitSet liveKill; |
110 } | 110 } |
111 | 111 |
112 public final BlockMap<BlockData> blockData; | 112 final BlockMap<BlockData> blockData; |
113 | 113 |
114 /** | 114 /** |
115 * List of blocks in linear-scan order. This is only correct as long as the CFG does not change. | 115 * List of blocks in linear-scan order. This is only correct as long as the CFG does not change. |
116 */ | 116 */ |
117 final List<? extends AbstractBlock<?>> sortedBlocks; | 117 final List<? extends AbstractBlock<?>> sortedBlocks; |
159 /** | 159 /** |
160 * The {@linkplain #operandNumber(Value) number} of the first variable operand allocated. | 160 * The {@linkplain #operandNumber(Value) number} of the first variable operand allocated. |
161 */ | 161 */ |
162 private final int firstVariableNumber; | 162 private final int firstVariableNumber; |
163 | 163 |
164 public LinearScan(TargetDescription target, LIRGenerationResult res) { | 164 LinearScan(TargetDescription target, LIRGenerationResult res) { |
165 this.target = target; | 165 this.target = target; |
166 this.res = res; | 166 this.res = res; |
167 this.ir = res.getLIR(); | 167 this.ir = res.getLIR(); |
168 this.frameMapBuilder = res.getFrameMapBuilder(); | 168 this.frameMapBuilder = res.getFrameMapBuilder(); |
169 this.sortedBlocks = ir.linearScanOrder(); | 169 this.sortedBlocks = ir.linearScanOrder(); |
176 // If all allocatable registers are caller saved, then no registers are live across a call | 176 // If all allocatable registers are caller saved, then no registers are live across a call |
177 // site. The register allocator can save time not trying to find a register at a call site. | 177 // site. The register allocator can save time not trying to find a register at a call site. |
178 this.callKillsRegisters = this.frameMapBuilder.getRegisterConfig().areAllAllocatableRegistersCallerSaved(); | 178 this.callKillsRegisters = this.frameMapBuilder.getRegisterConfig().areAllAllocatableRegistersCallerSaved(); |
179 } | 179 } |
180 | 180 |
181 public int getFirstLirInstructionId(AbstractBlock<?> block) { | 181 int getFirstLirInstructionId(AbstractBlock<?> block) { |
182 int result = ir.getLIRforBlock(block).get(0).id(); | 182 int result = ir.getLIRforBlock(block).get(0).id(); |
183 assert result >= 0; | 183 assert result >= 0; |
184 return result; | 184 return result; |
185 } | 185 } |
186 | 186 |
187 public int getLastLirInstructionId(AbstractBlock<?> block) { | 187 int getLastLirInstructionId(AbstractBlock<?> block) { |
188 List<LIRInstruction> instructions = ir.getLIRforBlock(block); | 188 List<LIRInstruction> instructions = ir.getLIRforBlock(block); |
189 int result = instructions.get(instructions.size() - 1).id(); | 189 int result = instructions.get(instructions.size() - 1).id(); |
190 assert result >= 0; | 190 assert result >= 0; |
191 return result; | 191 return result; |
192 } | 192 } |
218 } | 218 } |
219 | 219 |
220 /** | 220 /** |
221 * Gets the highest operand number for a register operand. This value will never change. | 221 * Gets the highest operand number for a register operand. This value will never change. |
222 */ | 222 */ |
223 public int maxRegisterNumber() { | 223 int maxRegisterNumber() { |
224 return firstVariableNumber - 1; | 224 return firstVariableNumber - 1; |
225 } | 225 } |
226 | 226 |
227 static final IntervalPredicate IS_PRECOLORED_INTERVAL = new IntervalPredicate() { | 227 static final IntervalPredicate IS_PRECOLORED_INTERVAL = new IntervalPredicate() { |
228 | 228 |
1372 } | 1372 } |
1373 | 1373 |
1374 sortedIntervals = combinedList; | 1374 sortedIntervals = combinedList; |
1375 } | 1375 } |
1376 | 1376 |
1377 public void allocateRegisters() { | 1377 void allocateRegisters() { |
1378 try (Indent indent = Debug.logAndIndent("allocate registers")) { | 1378 try (Indent indent = Debug.logAndIndent("allocate registers")) { |
1379 Interval precoloredIntervals; | 1379 Interval precoloredIntervals; |
1380 Interval notPrecoloredIntervals; | 1380 Interval notPrecoloredIntervals; |
1381 | 1381 |
1382 Interval.Pair result = createUnhandledLists(IS_PRECOLORED_INTERVAL, IS_VARIABLE_INTERVAL); | 1382 Interval.Pair result = createUnhandledLists(IS_PRECOLORED_INTERVAL, IS_VARIABLE_INTERVAL); |
1729 } | 1729 } |
1730 } | 1730 } |
1731 } | 1731 } |
1732 } | 1732 } |
1733 | 1733 |
1734 public static void allocate(TargetDescription target, LIRGenerationResult res) { | 1734 void allocate() { |
1735 new LinearScan(target, res).allocate(); | |
1736 } | |
1737 | |
1738 private void allocate() { | |
1739 | 1735 |
1740 /* | 1736 /* |
1741 * This is the point to enable debug logging for the whole register allocation. | 1737 * This is the point to enable debug logging for the whole register allocation. |
1742 */ | 1738 */ |
1743 try (Indent indent = Debug.logAndIndent("LinearScan allocate")) { | 1739 try (Indent indent = Debug.logAndIndent("LinearScan allocate")) { |