OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 class SsaPhiEliminator extends HGraphVisitor { | 5 class SsaPhiEliminator extends HGraphVisitor { |
6 HBasicBlock entry; | 6 HBasicBlock entry; |
7 HBasicBlock currentBlock; | 7 HBasicBlock currentBlock; |
8 | 8 |
9 visitGraph(HGraph graph) { | 9 visitGraph(HGraph graph) { |
10 entry = graph.entry; | 10 entry = graph.entry; |
(...skipping 107 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
118 // We propagate the type of the phi to the load instruction rather | 118 // We propagate the type of the phi to the load instruction rather |
119 // than the local because we may end up sharing a single local | 119 // than the local because we may end up sharing a single local |
120 // between different phis of different types. | 120 // between different phis of different types. |
121 HLoad load = new HLoad(local, phi.type); | 121 HLoad load = new HLoad(local, phi.type); |
122 loads.add(load); | 122 loads.add(load); |
123 | 123 |
124 currentBlock.addAtEntry(load); | 124 currentBlock.addAtEntry(load); |
125 currentBlock.rewrite(phi, load); | 125 currentBlock.rewrite(phi, load); |
126 currentBlock.removePhi(phi); | 126 currentBlock.removePhi(phi); |
127 | 127 |
128 if (!currentBlock.isLoopHeader() || !hasLoopPhiAsInput(stores, loads)) { | 128 if (currentBlock.isLoopHeader()) { |
129 if (!hasLoopPhiAsInput(stores, loads) && | |
130 !isPhiUsedInLoop(stores, load)) { | |
131 load.setGenerateAtUseSite(); | |
132 } | |
133 } else { | |
129 load.setGenerateAtUseSite(); | 134 load.setGenerateAtUseSite(); |
130 } | 135 } |
131 } | 136 } |
132 | 137 |
138 bool isPhiUsedInLoop(List<HStore> stores, HLoad load) { | |
139 // [stores] contains the stores of a specific phi. | |
140 // [load] is the replacement of the loop phi. | |
141 // We assume a loop header only has two predecessors: the entry | |
142 // and the backedge. | |
143 assert(stores.length == 2); | |
144 HStore update = stores[1]; | |
145 for (HInstruction instruction in load.usedBy) { | |
146 if (instruction.block.parentLoopHeader != update.block.parentLoopHeader) { | |
floitsch
2011/12/22 16:30:56
What about nested loops? Then the parentLoopHeader
| |
147 continue; | |
148 } | |
149 if (instruction.block.id > update.block.id) return true; | |
150 if (instruction.block == update.block && isBefore(update, instruction)) { | |
151 return true; | |
152 } | |
153 } | |
154 return false; | |
155 } | |
156 | |
157 bool isBefore(HInstruction first, HInstruction second) { | |
158 assert(first.block == second.block); | |
159 HInstruction current = first.block.first; | |
160 while (current != null) { | |
161 if (current == first) return true; | |
162 if (current == second) return false; | |
163 current = current.next; | |
164 } | |
165 // In case the instructions are out of the block. | |
166 return false; | |
167 } | |
168 | |
133 bool hasLoopPhiAsInput(List<HStore> stores, List<HLoad> loads) { | 169 bool hasLoopPhiAsInput(List<HStore> stores, List<HLoad> loads) { |
134 // [stores] contains the stores of a specific phi. | 170 // [stores] contains the stores of a specific phi. |
135 // [loads] contains the phis that were converted to loads. | 171 // [loads] contains the phis that were converted to loads. |
136 assert(currentBlock.isLoopHeader()); | 172 assert(currentBlock.isLoopHeader()); |
137 for (HStore store in stores) { | 173 for (HStore store in stores) { |
138 HInstruction value = store.value; | 174 HInstruction value = store.value; |
139 if (value is HPhi && value.block == currentBlock) { | 175 if (value is HPhi && value.block == currentBlock) { |
140 return true; | 176 return true; |
141 } else if (value is HLoad && loads.indexOf(value) != -1) { | 177 } else if (value is HLoad && loads.indexOf(value) != -1) { |
142 return true; | 178 return true; |
143 } | 179 } |
144 } | 180 } |
145 return false; | 181 return false; |
146 } | 182 } |
147 } | 183 } |
OLD | NEW |