Mercurial > hg > truffle
annotate graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java @ 17277:730aa0eb20e5
LIRIntrospection: rename forEach*(ValuePositionProcedure) to forEach*Pos.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Thu, 25 Sep 2014 10:27:05 +0200 |
parents | 26d07b31c4a8 |
children | e8b80721524d |
rev | line source |
---|---|
16952 | 1 /* |
2 * Copyright (c) 2014, 2014, Oracle and/or its affiliates. All rights reserved. | |
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. | |
4 * | |
5 * This code is free software; you can redistribute it and/or modify it | |
6 * under the terms of the GNU General Public License version 2 only, as | |
7 * published by the Free Software Foundation. | |
8 * | |
9 * This code is distributed in the hope that it will be useful, but WITHOUT | |
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
12 * version 2 for more details (a copy is included in the LICENSE file that | |
13 * accompanied this code). | |
14 * | |
15 * You should have received a copy of the GNU General Public License version | |
16 * 2 along with this work; if not, write to the Free Software Foundation, | |
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. | |
18 * | |
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA | |
20 * or visit www.oracle.com if you need additional information or have any | |
21 * questions. | |
22 */ | |
23 package com.oracle.graal.lir.constopt; | |
24 | |
25 import static com.oracle.graal.api.code.ValueUtil.*; | |
26 import static com.oracle.graal.lir.LIRValueUtil.*; | |
27 | |
28 import java.util.*; | |
29 | |
30 import com.oracle.graal.api.meta.*; | |
31 import com.oracle.graal.compiler.common.cfg.*; | |
32 import com.oracle.graal.debug.*; | |
33 import com.oracle.graal.debug.Debug.Scope; | |
34 import com.oracle.graal.lir.*; | |
35 import com.oracle.graal.lir.StandardOp.MoveOp; | |
36 import com.oracle.graal.lir.constopt.ConstantTree.Flags; | |
37 import com.oracle.graal.lir.constopt.ConstantTree.NodeCost; | |
38 import com.oracle.graal.lir.gen.*; | |
39 import com.oracle.graal.options.*; | |
40 | |
41 /** | |
42 * This optimization tries to improve the handling of constants by replacing a single definition of | |
43 * a constant, which is potentially scheduled into a block with high probability, with one or more | |
44 * definitions in blocks with a lower probability. | |
45 */ | |
46 public class ConstantLoadOptimization { | |
47 | |
48 public static class Options { | |
49 // @formatter:off | |
50 @Option(help = "Enable constant load optimization.") | |
51 public static final OptionValue<Boolean> ConstantLoadOptimization = new OptionValue<>(true); | |
52 // @formatter:on | |
53 } | |
54 | |
55 public static void optimize(LIR lir, LIRGeneratorTool lirGen) { | |
56 new ConstantLoadOptimization(lir, lirGen).apply(); | |
57 } | |
58 | |
59 private LIR lir; | |
60 private LIRGeneratorTool lirGen; | |
61 private VariableMap<DefUseTree> map; | |
62 private BitSet phiConstants; | |
63 private BitSet defined; | |
64 private BlockMap<List<UseEntry>> blockMap; | |
65 private BlockMap<LIRInsertionBuffer> insertionBuffers; | |
66 | |
17212
26d07b31c4a8
ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents:
17068
diff
changeset
|
67 private static final DebugMetric constantsTotal = Debug.metric("ConstantLoadOptimization[total]"); |
26d07b31c4a8
ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents:
17068
diff
changeset
|
68 private static final DebugMetric phiConstantsSkipped = Debug.metric("ConstantLoadOptimization[PhisSkipped]"); |
26d07b31c4a8
ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents:
17068
diff
changeset
|
69 private static final DebugMetric singleUsageConstantsSkipped = Debug.metric("ConstantLoadOptimization[SingleUsageSkipped]"); |
26d07b31c4a8
ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents:
17068
diff
changeset
|
70 private static final DebugMetric usageAtDefinitionSkipped = Debug.metric("ConstantLoadOptimization[UsageAtDefinitionSkipped]"); |
26d07b31c4a8
ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents:
17068
diff
changeset
|
71 private static final DebugMetric materializeAtDefinitionSkipped = Debug.metric("ConstantLoadOptimization[MaterializeAtDefinitionSkipped]"); |
26d07b31c4a8
ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents:
17068
diff
changeset
|
72 private static final DebugMetric constantsOptimized = Debug.metric("ConstantLoadOptimization[optimized]"); |
16952 | 73 |
74 private ConstantLoadOptimization(LIR lir, LIRGeneratorTool lirGen) { | |
75 this.lir = lir; | |
76 this.lirGen = lirGen; | |
77 this.map = new VariableMap<>(); | |
78 this.phiConstants = new BitSet(); | |
79 this.defined = new BitSet(); | |
80 this.insertionBuffers = new BlockMap<>(lir.getControlFlowGraph()); | |
81 this.blockMap = new BlockMap<>(lir.getControlFlowGraph()); | |
82 } | |
83 | |
84 private void apply() { | |
85 try (Indent indent = Debug.logAndIndent("ConstantLoadOptimization")) { | |
86 try (Scope s = Debug.scope("BuildDefUseTree")) { | |
87 // build DefUseTree | |
16953
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
88 lir.getControlFlowGraph().getBlocks().forEach(this::analyzeBlock); |
16952 | 89 // remove all with only one use |
90 map.filter(t -> { | |
91 if (t.usageCount() > 1) { | |
92 return true; | |
93 } else { | |
94 singleUsageConstantsSkipped.increment(); | |
95 return false; | |
96 } | |
97 }); | |
98 // collect block map | |
99 map.forEach(tree -> tree.forEach(this::addUsageToBlockMap)); | |
100 } catch (Throwable e) { | |
101 throw Debug.handle(e); | |
102 } | |
103 | |
104 try (Scope s = Debug.scope("BuildConstantTree")) { | |
105 // create ConstantTree | |
106 map.forEach(this::createConstantTree); | |
107 | |
108 // insert moves, delete null instructions and reset instruction ids | |
109 lir.getControlFlowGraph().getBlocks().forEach(this::rewriteBlock); | |
17068
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
110 |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
111 assert verifyStates(); |
16952 | 112 } catch (Throwable e) { |
113 throw Debug.handle(e); | |
114 } | |
115 } | |
116 } | |
117 | |
17068
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
118 private boolean verifyStates() { |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
119 map.forEach(this::verifyStateUsage); |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
120 return true; |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
121 } |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
122 |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
123 private void verifyStateUsage(DefUseTree tree) { |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
124 Variable var = tree.getVariable(); |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
125 ValueConsumer stateConsumer = new ValueConsumer() { |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
126 |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
127 @Override |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
128 public void visitValue(Value operand) { |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
129 assert !operand.equals(var) : "constant usage through variable in frame state " + var; |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
130 } |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
131 }; |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
132 for (AbstractBlock<?> block : lir.getControlFlowGraph().getBlocks()) { |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
133 for (LIRInstruction inst : lir.getLIRforBlock(block)) { |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
134 // set instruction id to the index in the lir instruction list |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
135 inst.visitEachState(stateConsumer); |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
136 } |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
137 } |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
138 } |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
139 |
16952 | 140 private static boolean isConstantLoad(LIRInstruction inst) { |
141 if (!(inst instanceof MoveOp)) { | |
142 return false; | |
143 } | |
144 MoveOp move = (MoveOp) inst; | |
145 return isConstant(move.getInput()) && isVariable(move.getResult()); | |
146 } | |
147 | |
148 private void addUsageToBlockMap(UseEntry entry) { | |
149 AbstractBlock<?> block = entry.getBlock(); | |
150 List<UseEntry> list = blockMap.get(block); | |
151 if (list == null) { | |
152 list = new ArrayList<>(); | |
153 blockMap.put(block, list); | |
154 } | |
155 list.add(entry); | |
156 } | |
157 | |
16953
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
158 /** |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
159 * Collects def-use information for a {@code block}. |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
160 */ |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
161 private void analyzeBlock(AbstractBlock<?> block) { |
16952 | 162 try (Indent indent = Debug.logAndIndent("Block: %s", block)) { |
163 | |
164 InstructionValueConsumer loadConsumer = new InstructionValueConsumer() { | |
165 @Override | |
166 public void visitValue(LIRInstruction instruction, Value value) { | |
167 if (isVariable(value)) { | |
168 Variable var = (Variable) value; | |
169 | |
170 if (!phiConstants.get(var.index)) { | |
171 if (!defined.get(var.index)) { | |
172 defined.set(var.index); | |
173 if (isConstantLoad(instruction)) { | |
174 Debug.log("constant load: %s", instruction); | |
175 map.put(var, new DefUseTree(instruction, block)); | |
176 constantsTotal.increment(); | |
177 } | |
178 } else { | |
179 // Variable is redefined, this only happens for constant loads | |
180 // introduced by phi resolution -> ignore. | |
181 DefUseTree removed = map.remove(var); | |
182 if (removed != null) { | |
183 phiConstantsSkipped.increment(); | |
184 } | |
185 phiConstants.set(var.index); | |
186 Debug.log(3, "Removing phi variable: %s", var); | |
187 } | |
188 } else { | |
189 assert defined.get(var.index) : "phi but not defined? " + var; | |
190 } | |
191 | |
192 } | |
193 } | |
194 | |
195 }; | |
196 | |
197 ValuePositionProcedure useProcedure = new ValuePositionProcedure() { | |
198 @Override | |
199 public void doValue(LIRInstruction instruction, ValuePosition position) { | |
200 Value value = position.get(instruction); | |
201 if (isVariable(value)) { | |
202 Variable var = (Variable) value; | |
203 if (!phiConstants.get(var.index)) { | |
204 DefUseTree tree = map.get(var); | |
205 if (tree != null) { | |
206 tree.addUsage(block, instruction, position); | |
207 Debug.log("usage of %s : %s", var, instruction); | |
208 } | |
209 } | |
210 } | |
211 } | |
212 | |
213 }; | |
214 | |
215 int opId = 0; | |
216 for (LIRInstruction inst : lir.getLIRforBlock(block)) { | |
217 // set instruction id to the index in the lir instruction list | |
218 inst.setId(opId++); | |
219 inst.visitEachOutput(loadConsumer); | |
17277
730aa0eb20e5
LIRIntrospection: rename forEach*(ValuePositionProcedure) to forEach*Pos.
Josef Eisl <josef.eisl@jku.at>
parents:
17212
diff
changeset
|
220 inst.forEachInputPos(useProcedure); |
730aa0eb20e5
LIRIntrospection: rename forEach*(ValuePositionProcedure) to forEach*Pos.
Josef Eisl <josef.eisl@jku.at>
parents:
17212
diff
changeset
|
221 inst.forEachAlivePos(useProcedure); |
16952 | 222 |
223 } | |
224 } | |
225 } | |
226 | |
16953
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
227 /** |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
228 * Creates the dominator tree and searches for an solution. |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
229 */ |
16952 | 230 private void createConstantTree(DefUseTree tree) { |
231 ConstantTree constTree = new ConstantTree(lir.getControlFlowGraph(), tree); | |
232 constTree.set(Flags.SUBTREE, tree.getBlock()); | |
233 tree.forEach(u -> constTree.set(Flags.USAGE, u.getBlock())); | |
234 | |
235 if (constTree.get(Flags.USAGE, tree.getBlock())) { | |
236 // usage in the definition block -> no optimization | |
237 usageAtDefinitionSkipped.increment(); | |
238 return; | |
239 } | |
240 | |
241 constTree.markBlocks(); | |
242 | |
243 NodeCost cost = ConstantTreeAnalyzer.analyze(constTree, tree.getBlock()); | |
244 int usageCount = cost.getUsages().size(); | |
245 assert usageCount == tree.usageCount() : "Usage count differs: " + usageCount + " vs. " + tree.usageCount(); | |
246 | |
16953
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
247 if (Debug.isLogEnabled()) { |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
248 try (Indent i = Debug.logAndIndent("Variable: %s, Block: %s, prob.: %f", tree.getVariable(), tree.getBlock(), tree.getBlock().probability())) { |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
249 Debug.log("Usages result: %s", cost); |
16952 | 250 } |
251 | |
252 } | |
253 | |
254 if (cost.getNumMaterializations() > 1 || cost.getBestCost() < tree.getBlock().probability()) { | |
255 try (Scope s = Debug.scope("CLOmodify", constTree); Indent i = Debug.logAndIndent("Replacing %s = %s", tree.getVariable(), tree.getConstant().toValueString())) { | |
256 // mark original load for removal | |
257 deleteInstruction(tree); | |
258 constantsOptimized.increment(); | |
259 | |
260 // collect result | |
261 createLoads(tree, constTree, tree.getBlock()); | |
262 | |
263 } catch (Throwable e) { | |
264 throw Debug.handle(e); | |
265 } | |
266 } else { | |
267 // no better solution found | |
268 materializeAtDefinitionSkipped.increment(); | |
269 } | |
270 Debug.dump(constTree, "ConstantTree for " + tree.getVariable()); | |
271 } | |
272 | |
273 private void createLoads(DefUseTree tree, ConstantTree constTree, AbstractBlock<?> startBlock) { | |
274 Deque<AbstractBlock<?>> worklist = new ArrayDeque<>(); | |
275 worklist.add(startBlock); | |
276 while (!worklist.isEmpty()) { | |
277 AbstractBlock<?> block = worklist.pollLast(); | |
278 if (constTree.get(Flags.CANDIDATE, block)) { | |
279 constTree.set(Flags.MATERIALIZE, block); | |
280 // create and insert load | |
281 insertLoad(tree.getConstant(), tree.getVariable().getLIRKind(), block, constTree.getCost(block).getUsages()); | |
282 } else { | |
283 for (AbstractBlock<?> dominated : block.getDominated()) { | |
284 if (constTree.isMarked(dominated)) { | |
285 worklist.addLast(dominated); | |
286 } | |
287 } | |
288 } | |
289 } | |
290 } | |
291 | |
16953
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
292 private void insertLoad(Constant constant, LIRKind kind, AbstractBlock<?> block, List<UseEntry> usages) { |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
293 assert usages != null && usages.size() > 0 : String.format("No usages %s %s %s", constant, block, usages); |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
294 // create variable |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
295 Variable variable = lirGen.newVariable(kind); |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
296 // create move |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
297 LIRInstruction move = lir.getSpillMoveFactory().createMove(variable, constant); |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
298 // insert instruction |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
299 getInsertionBuffer(block).append(1, move); |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
300 Debug.log("new move (%s) and inserted in block %s", move, block); |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
301 // update usages |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
302 for (UseEntry u : usages) { |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
303 u.getPosition().set(u.getInstruction(), variable); |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
304 Debug.log("patched instruction %s", u.getInstruction()); |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
305 } |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
306 } |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
307 |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
308 /** |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
309 * Inserts the constant loads created in {@link #createConstantTree} and deletes the original |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
310 * definition. |
85020469ed2b
ConstantLoadOptimization: minor cleanups.
Josef Eisl <josef.eisl@jku.at>
parents:
16952
diff
changeset
|
311 */ |
16952 | 312 private void rewriteBlock(AbstractBlock<?> block) { |
313 // insert moves | |
314 LIRInsertionBuffer buffer = insertionBuffers.get(block); | |
315 if (buffer != null) { | |
316 assert buffer.initialized() : "not initialized?"; | |
317 buffer.finish(); | |
318 } | |
319 | |
320 // delete instructions | |
321 List<LIRInstruction> instructions = lir.getLIRforBlock(block); | |
322 boolean hasDead = false; | |
323 for (LIRInstruction inst : instructions) { | |
324 if (inst == null) { | |
325 hasDead = true; | |
326 } else { | |
327 inst.setId(-1); | |
328 } | |
329 } | |
330 if (hasDead) { | |
331 // Remove null values from the list. | |
332 instructions.removeAll(Collections.singleton(null)); | |
333 } | |
334 } | |
335 | |
336 private void deleteInstruction(DefUseTree tree) { | |
337 AbstractBlock<?> block = tree.getBlock(); | |
338 LIRInstruction instruction = tree.getInstruction(); | |
339 Debug.log("deleting instruction %s from block %s", instruction, block); | |
340 lir.getLIRforBlock(block).set(instruction.id(), null); | |
341 } | |
342 | |
343 private LIRInsertionBuffer getInsertionBuffer(AbstractBlock<?> block) { | |
344 LIRInsertionBuffer insertionBuffer = insertionBuffers.get(block); | |
345 if (insertionBuffer == null) { | |
346 insertionBuffer = new LIRInsertionBuffer(); | |
347 insertionBuffers.put(block, insertionBuffer); | |
348 assert !insertionBuffer.initialized() : "already initialized?"; | |
349 List<LIRInstruction> instructions = lir.getLIRforBlock(block); | |
350 insertionBuffer.init(instructions); | |
351 } | |
352 return insertionBuffer; | |
353 } | |
354 } |