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 !isUsedAfterStores(stores[1], load)) { | |
kasperl
2011/12/22 15:11:54
Is stores[1] guaranteed to be the last store. I gu
ngeoffray
2011/12/22 15:15:10
On a loop phi we currently have the assumption tha
| |
131 load.setGenerateAtUseSite(); | |
132 } | |
133 } else { | |
129 load.setGenerateAtUseSite(); | 134 load.setGenerateAtUseSite(); |
130 } | 135 } |
131 } | 136 } |
132 | 137 |
138 bool isUsedAfterStores(HStore update, HLoad load) { | |
139 // [update] is the store of the loop phi for the back edge. | |
140 // [load] is the replacement of the loop phi. | |
141 for (HInstruction instruction in load.usedBy) { | |
142 if (instruction.block.id >= update.value.block.id) return true; | |
143 } | |
144 return false; | |
145 } | |
146 | |
133 bool hasLoopPhiAsInput(List<HStore> stores, List<HLoad> loads) { | 147 bool hasLoopPhiAsInput(List<HStore> stores, List<HLoad> loads) { |
134 // [stores] contains the stores of a specific phi. | 148 // [stores] contains the stores of a specific phi. |
135 // [loads] contains the phis that were converted to loads. | 149 // [loads] contains the phis that were converted to loads. |
136 assert(currentBlock.isLoopHeader()); | 150 assert(currentBlock.isLoopHeader()); |
137 for (HStore store in stores) { | 151 for (HStore store in stores) { |
138 HInstruction value = store.value; | 152 HInstruction value = store.value; |
139 if (value is HPhi && value.block == currentBlock) { | 153 if (value is HPhi && value.block == currentBlock) { |
140 return true; | 154 return true; |
141 } else if (value is HLoad && loads.indexOf(value) != -1) { | 155 } else if (value is HLoad && loads.indexOf(value) != -1) { |
142 return true; | 156 return true; |
143 } | 157 } |
144 } | 158 } |
145 return false; | 159 return false; |
146 } | 160 } |
147 } | 161 } |
OLD | NEW |