Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(516)

Side by Side Diff: dart/frog/leg/ssa/phi_eliminator.dart

Issue 9025012: New bugfix for phi eliminator: if a loop phi is used after its update, the load of the phi must n... (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 8 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | dart/tests/language/language-leg.status » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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 }
OLDNEW
« no previous file with comments | « no previous file | dart/tests/language/language-leg.status » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698