Mercurial > hg > truffle
annotate graal/com.oracle.graal.lir/src/com/oracle/graal/lir/constopt/ConstantLoadOptimization.java @ 19214:e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
author | Josef Eisl <josef.eisl@jku.at> |
---|---|
date | Mon, 09 Feb 2015 09:10:44 +0100 |
parents | ecb9d0cedbab |
children | edd93c34d015 |
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 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
30 import com.oracle.graal.api.code.*; |
16952 | 31 import com.oracle.graal.api.meta.*; |
32 import com.oracle.graal.compiler.common.cfg.*; | |
33 import com.oracle.graal.debug.*; | |
34 import com.oracle.graal.debug.Debug.Scope; | |
35 import com.oracle.graal.lir.*; | |
17283
e8b80721524d
Remove InstructionValueConsumer.visitValue(LIRInstruction, Value).
Josef Eisl <josef.eisl@jku.at>
parents:
17277
diff
changeset
|
36 import com.oracle.graal.lir.LIRInstruction.OperandFlag; |
e8b80721524d
Remove InstructionValueConsumer.visitValue(LIRInstruction, Value).
Josef Eisl <josef.eisl@jku.at>
parents:
17277
diff
changeset
|
37 import com.oracle.graal.lir.LIRInstruction.OperandMode; |
16952 | 38 import com.oracle.graal.lir.StandardOp.MoveOp; |
39 import com.oracle.graal.lir.constopt.ConstantTree.Flags; | |
40 import com.oracle.graal.lir.constopt.ConstantTree.NodeCost; | |
41 import com.oracle.graal.lir.gen.*; | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
42 import com.oracle.graal.lir.phases.*; |
16952 | 43 import com.oracle.graal.options.*; |
44 | |
45 /** | |
46 * This optimization tries to improve the handling of constants by replacing a single definition of | |
47 * a constant, which is potentially scheduled into a block with high probability, with one or more | |
48 * definitions in blocks with a lower probability. | |
49 */ | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
50 public final class ConstantLoadOptimization extends LowLevelHighTierPhase { |
16952 | 51 |
52 public static class Options { | |
53 // @formatter:off | |
18674
ecb9d0cedbab
First draft of option classification.
Thomas Wuerthinger <thomas.wuerthinger@oracle.com>
parents:
18187
diff
changeset
|
54 @Option(help = "Enable constant load optimization.", type = OptionType.Debug) |
16952 | 55 public static final OptionValue<Boolean> ConstantLoadOptimization = new OptionValue<>(true); |
56 // @formatter:on | |
57 } | |
58 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
59 @Override |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
60 protected void run(TargetDescription target, LIRGenerationResult lirGenRes, LIRGeneratorTool lirGen) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
61 new Optimization(lirGenRes.getLIR(), lirGen).apply(); |
16952 | 62 } |
63 | |
17212
26d07b31c4a8
ConstantLoadOptimization: make debug meters final.
Josef Eisl <josef.eisl@jku.at>
parents:
17068
diff
changeset
|
64 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
|
65 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
|
66 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
|
67 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
|
68 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
|
69 private static final DebugMetric constantsOptimized = Debug.metric("ConstantLoadOptimization[optimized]"); |
16952 | 70 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
71 private static final class Optimization { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
72 private final LIR lir; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
73 private final LIRGeneratorTool lirGen; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
74 private final VariableMap<DefUseTree> map; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
75 private final BitSet phiConstants; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
76 private final BitSet defined; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
77 private final BlockMap<List<UseEntry>> blockMap; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
78 private final BlockMap<LIRInsertionBuffer> insertionBuffers; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
79 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
80 private Optimization(LIR lir, LIRGeneratorTool lirGen) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
81 this.lir = lir; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
82 this.lirGen = lirGen; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
83 this.map = new VariableMap<>(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
84 this.phiConstants = new BitSet(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
85 this.defined = new BitSet(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
86 this.insertionBuffers = new BlockMap<>(lir.getControlFlowGraph()); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
87 this.blockMap = new BlockMap<>(lir.getControlFlowGraph()); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
88 } |
16952 | 89 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
90 private void apply() { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
91 try (Indent indent = Debug.logAndIndent("ConstantLoadOptimization")) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
92 try (Scope s = Debug.scope("BuildDefUseTree")) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
93 // build DefUseTree |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
94 lir.getControlFlowGraph().getBlocks().forEach(this::analyzeBlock); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
95 // remove all with only one use |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
96 map.filter(t -> { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
97 if (t.usageCount() > 1) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
98 return true; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
99 } else { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
100 singleUsageConstantsSkipped.increment(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
101 return false; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
102 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
103 }); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
104 // collect block map |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
105 map.forEach(tree -> tree.forEach(this::addUsageToBlockMap)); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
106 } catch (Throwable e) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
107 throw Debug.handle(e); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
108 } |
16952 | 109 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
110 try (Scope s = Debug.scope("BuildConstantTree")) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
111 // create ConstantTree |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
112 map.forEach(this::createConstantTree); |
16952 | 113 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
114 // insert moves, delete null instructions and reset instruction ids |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
115 lir.getControlFlowGraph().getBlocks().forEach(this::rewriteBlock); |
17068
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
116 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
117 assert verifyStates(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
118 } catch (Throwable e) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
119 throw Debug.handle(e); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
120 } |
16952 | 121 } |
122 } | |
123 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
124 private boolean verifyStates() { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
125 map.forEach(this::verifyStateUsage); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
126 return true; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
127 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
128 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
129 private void verifyStateUsage(DefUseTree tree) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
130 Variable var = tree.getVariable(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
131 ValueConsumer stateConsumer = new ValueConsumer() { |
17068
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
132 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
133 @Override |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
134 public void visitValue(Value operand, OperandMode mode, EnumSet<OperandFlag> flags) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
135 assert !operand.equals(var) : "constant usage through variable in frame state " + var; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
136 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
137 }; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
138 for (AbstractBlock<?> block : lir.getControlFlowGraph().getBlocks()) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
139 for (LIRInstruction inst : lir.getLIRforBlock(block)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
140 // set instruction id to the index in the lir instruction list |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
141 inst.visitEachState(stateConsumer); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
142 } |
17068
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
143 } |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
144 } |
8456194ca311
Unproxy constant usages in FrameState
Tom Rodriguez <tom.rodriguez@oracle.com>
parents:
16953
diff
changeset
|
145 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
146 private static boolean isConstantLoad(LIRInstruction inst) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
147 if (!(inst instanceof MoveOp)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
148 return false; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
149 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
150 MoveOp move = (MoveOp) inst; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
151 return isConstant(move.getInput()) && isVariable(move.getResult()); |
16952 | 152 } |
153 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
154 private void addUsageToBlockMap(UseEntry entry) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
155 AbstractBlock<?> block = entry.getBlock(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
156 List<UseEntry> list = blockMap.get(block); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
157 if (list == null) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
158 list = new ArrayList<>(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
159 blockMap.put(block, list); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
160 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
161 list.add(entry); |
16952 | 162 } |
163 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
164 /** |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
165 * Collects def-use information for a {@code block}. |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
166 */ |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
167 private void analyzeBlock(AbstractBlock<?> block) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
168 try (Indent indent = Debug.logAndIndent("Block: %s", block)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
169 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
170 InstructionValueConsumer loadConsumer = (instruction, value, mode, flags) -> { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
171 if (isVariable(value)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
172 Variable var = (Variable) value; |
16952 | 173 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
174 if (!phiConstants.get(var.index)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
175 if (!defined.get(var.index)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
176 defined.set(var.index); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
177 if (isConstantLoad(instruction)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
178 Debug.log("constant load: %s", instruction); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
179 map.put(var, new DefUseTree(instruction, block)); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
180 constantsTotal.increment(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
181 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
182 } else { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
183 // Variable is redefined, this only happens for constant loads |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
184 // introduced by phi resolution -> ignore. |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
185 DefUseTree removed = map.remove(var); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
186 if (removed != null) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
187 phiConstantsSkipped.increment(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
188 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
189 phiConstants.set(var.index); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
190 Debug.log(3, "Removing phi variable: %s", var); |
16952 | 191 } |
192 } else { | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
193 assert defined.get(var.index) : "phi but not defined? " + var; |
16952 | 194 } |
195 } | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
196 }; |
16952 | 197 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
198 ValuePositionProcedure useProcedure = (instruction, position) -> { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
199 Value value = position.get(instruction); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
200 if (isVariable(value)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
201 Variable var = (Variable) value; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
202 if (!phiConstants.get(var.index)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
203 DefUseTree tree = map.get(var); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
204 if (tree != null) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
205 tree.addUsage(block, instruction, position); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
206 Debug.log("usage of %s : %s", var, instruction); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
207 } |
16952 | 208 } |
209 } | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
210 }; |
16952 | 211 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
212 int opId = 0; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
213 for (LIRInstruction inst : lir.getLIRforBlock(block)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
214 // set instruction id to the index in the lir instruction list |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
215 inst.setId(opId++); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
216 inst.visitEachOutput(loadConsumer); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
217 inst.forEachInputPos(useProcedure); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
218 inst.forEachAlivePos(useProcedure); |
16952 | 219 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
220 } |
16952 | 221 } |
222 } | |
223 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
224 /** |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
225 * Creates the dominator tree and searches for an solution. |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
226 */ |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
227 private void createConstantTree(DefUseTree tree) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
228 ConstantTree constTree = new ConstantTree(lir.getControlFlowGraph(), tree); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
229 constTree.set(Flags.SUBTREE, tree.getBlock()); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
230 tree.forEach(u -> constTree.set(Flags.USAGE, u.getBlock())); |
16952 | 231 |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
232 if (constTree.get(Flags.USAGE, tree.getBlock())) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
233 // usage in the definition block -> no optimization |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
234 usageAtDefinitionSkipped.increment(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
235 return; |
16952 | 236 } |
237 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
238 constTree.markBlocks(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
239 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
240 NodeCost cost = ConstantTreeAnalyzer.analyze(constTree, tree.getBlock()); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
241 int usageCount = cost.getUsages().size(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
242 assert usageCount == tree.usageCount() : "Usage count differs: " + usageCount + " vs. " + tree.usageCount(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
243 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
244 if (Debug.isLogEnabled()) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
245 try (Indent i = Debug.logAndIndent("Variable: %s, Block: %s, prob.: %f", tree.getVariable(), tree.getBlock(), tree.getBlock().probability())) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
246 Debug.log("Usages result: %s", cost); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
247 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
248 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
249 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
250 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
251 if (cost.getNumMaterializations() > 1 || cost.getBestCost() < tree.getBlock().probability()) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
252 try (Scope s = Debug.scope("CLOmodify", constTree); Indent i = Debug.logAndIndent("Replacing %s = %s", tree.getVariable(), tree.getConstant().toValueString())) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
253 // mark original load for removal |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
254 deleteInstruction(tree); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
255 constantsOptimized.increment(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
256 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
257 // collect result |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
258 createLoads(tree, constTree, tree.getBlock()); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
259 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
260 } catch (Throwable e) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
261 throw Debug.handle(e); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
262 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
263 } else { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
264 // no better solution found |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
265 materializeAtDefinitionSkipped.increment(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
266 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
267 Debug.dump(constTree, "ConstantTree for " + tree.getVariable()); |
16952 | 268 } |
269 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
270 private void createLoads(DefUseTree tree, ConstantTree constTree, AbstractBlock<?> startBlock) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
271 Deque<AbstractBlock<?>> worklist = new ArrayDeque<>(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
272 worklist.add(startBlock); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
273 while (!worklist.isEmpty()) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
274 AbstractBlock<?> block = worklist.pollLast(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
275 if (constTree.get(Flags.CANDIDATE, block)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
276 constTree.set(Flags.MATERIALIZE, block); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
277 // create and insert load |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
278 insertLoad(tree.getConstant(), tree.getVariable().getLIRKind(), block, constTree.getCost(block).getUsages()); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
279 } else { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
280 for (AbstractBlock<?> dominated : block.getDominated()) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
281 if (constTree.isMarked(dominated)) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
282 worklist.addLast(dominated); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
283 } |
16952 | 284 } |
285 } | |
286 } | |
287 } | |
288 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
289 private void insertLoad(JavaConstant constant, LIRKind kind, AbstractBlock<?> block, List<UseEntry> usages) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
290 assert usages != null && usages.size() > 0 : String.format("No usages %s %s %s", constant, block, usages); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
291 // create variable |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
292 Variable variable = lirGen.newVariable(kind); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
293 // create move |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
294 LIRInstruction move = lir.getSpillMoveFactory().createMove(variable, constant); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
295 // insert instruction |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
296 getInsertionBuffer(block).append(1, move); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
297 Debug.log("new move (%s) and inserted in block %s", move, block); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
298 // update usages |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
299 for (UseEntry u : usages) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
300 u.getPosition().set(u.getInstruction(), variable); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
301 Debug.log("patched instruction %s", u.getInstruction()); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
302 } |
16952 | 303 } |
304 | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
305 /** |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
306 * Inserts the constant loads created in {@link #createConstantTree} and deletes the |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
307 * original definition. |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
308 */ |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
309 private void rewriteBlock(AbstractBlock<?> block) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
310 // insert moves |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
311 LIRInsertionBuffer buffer = insertionBuffers.get(block); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
312 if (buffer != null) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
313 assert buffer.initialized() : "not initialized?"; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
314 buffer.finish(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
315 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
316 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
317 // delete instructions |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
318 List<LIRInstruction> instructions = lir.getLIRforBlock(block); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
319 boolean hasDead = false; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
320 for (LIRInstruction inst : instructions) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
321 if (inst == null) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
322 hasDead = true; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
323 } else { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
324 inst.setId(-1); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
325 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
326 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
327 if (hasDead) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
328 // Remove null values from the list. |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
329 instructions.removeAll(Collections.singleton(null)); |
16952 | 330 } |
331 } | |
19214
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
332 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
333 private void deleteInstruction(DefUseTree tree) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
334 AbstractBlock<?> block = tree.getBlock(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
335 LIRInstruction instruction = tree.getInstruction(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
336 Debug.log("deleting instruction %s from block %s", instruction, block); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
337 lir.getLIRforBlock(block).set(instruction.id(), null); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
338 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
339 |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
340 private LIRInsertionBuffer getInsertionBuffer(AbstractBlock<?> block) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
341 LIRInsertionBuffer insertionBuffer = insertionBuffers.get(block); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
342 if (insertionBuffer == null) { |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
343 insertionBuffer = new LIRInsertionBuffer(); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
344 insertionBuffers.put(block, insertionBuffer); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
345 assert !insertionBuffer.initialized() : "already initialized?"; |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
346 List<LIRInstruction> instructions = lir.getLIRforBlock(block); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
347 insertionBuffer.init(instructions); |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
348 } |
e1f63e69dc6c
Make ConstantLoadOptimization a LowLevelHighTierPhase.
Josef Eisl <josef.eisl@jku.at>
parents:
18674
diff
changeset
|
349 return insertionBuffer; |
16952 | 350 } |
351 } | |
352 } |