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

Side by Side Diff: src/compiler/control-reducer.cc

Issue 1123213002: [turbofan] Connect non-terminating loops via Terminate. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 5 years, 7 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
« no previous file with comments | « src/compiler/common-operator.cc ('k') | src/compiler/instruction-selector.cc » ('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 2014 the V8 project authors. All rights reserved. 1 // Copyright 2014 the V8 project authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "src/compiler/common-operator.h" 5 #include "src/compiler/common-operator.h"
6 #include "src/compiler/control-reducer.h" 6 #include "src/compiler/control-reducer.h"
7 #include "src/compiler/graph.h" 7 #include "src/compiler/graph.h"
8 #include "src/compiler/graph-reducer.h" 8 #include "src/compiler/graph-reducer.h"
9 #include "src/compiler/js-graph.h" 9 #include "src/compiler/js-graph.h"
10 #include "src/compiler/node-marker.h" 10 #include "src/compiler/node-marker.h"
(...skipping 132 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 } 143 }
144 144
145 return done; 145 return done;
146 } 146 }
147 147
148 // Connect {loop}, the header of a non-terminating loop, to the end node. 148 // Connect {loop}, the header of a non-terminating loop, to the end node.
149 Node* ConnectNTL(Node* loop) { 149 Node* ConnectNTL(Node* loop) {
150 TRACE("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic()); 150 TRACE("ConnectNTL: #%d:%s\n", loop->id(), loop->op()->mnemonic());
151 DCHECK_EQ(IrOpcode::kLoop, loop->opcode()); 151 DCHECK_EQ(IrOpcode::kLoop, loop->opcode());
152 152
153 Node* always = graph()->NewNode(common()->Always()); 153 // Collect all loop effects.
154 Node* branch = graph()->NewNode(common()->Branch(), always, loop);
155 Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
156 Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
157
158 // Insert the branch into the loop and collect all loop effects.
159 NodeVector effects(zone_); 154 NodeVector effects(zone_);
160 for (auto edge : loop->use_edges()) { 155 for (auto edge : loop->use_edges()) {
161 DCHECK_EQ(loop, edge.to()); 156 DCHECK_EQ(loop, edge.to());
162 DCHECK(NodeProperties::IsControlEdge(edge)); 157 DCHECK(NodeProperties::IsControlEdge(edge));
163 if (edge.from() == branch) continue;
164 switch (edge.from()->opcode()) { 158 switch (edge.from()->opcode()) {
165 case IrOpcode::kPhi: 159 case IrOpcode::kPhi:
166 break; 160 break;
167 case IrOpcode::kEffectPhi: 161 case IrOpcode::kEffectPhi:
168 effects.push_back(edge.from()); 162 effects.push_back(edge.from());
169 break; 163 break;
170 default: 164 default:
171 // Update all control edges (except {branch}) pointing to the {loop}.
172 edge.UpdateTo(if_true);
173 break; 165 break;
174 } 166 }
175 } 167 }
176 168
177 // Compute effects for the Return. 169 // Compute effects for the Return.
178 Node* effect = graph()->start(); 170 Node* effect = graph()->start();
179 int const effects_count = static_cast<int>(effects.size()); 171 int const effects_count = static_cast<int>(effects.size());
180 if (effects_count == 1) { 172 if (effects_count == 1) {
181 effect = effects[0]; 173 effect = effects[0];
182 } else if (effects_count > 1) { 174 } else if (effects_count > 1) {
183 effect = graph()->NewNode(common()->EffectSet(effects_count), 175 effect = graph()->NewNode(common()->EffectSet(effects_count),
184 effects_count, &effects.front()); 176 effects_count, &effects.front());
185 } 177 }
186 178
187 // Add a return to connect the NTL to the end. 179 // Add a terminate to connect the NTL to the end.
188 Node* ret = graph()->NewNode( 180 Node* terminate = graph()->NewNode(common()->Terminate(), effect, loop);
189 common()->Return(), jsgraph_->UndefinedConstant(), effect, if_false);
190 181
191 Node* end = graph()->end(); 182 Node* end = graph()->end();
192 if (end->opcode() == IrOpcode::kDead) { 183 if (end->opcode() == IrOpcode::kDead) {
193 // End is actually the dead node. Make a new end. 184 // End is actually the dead node. Make a new end.
194 end = graph()->NewNode(common()->End(), ret); 185 end = graph()->NewNode(common()->End(), terminate);
195 graph()->SetEnd(end); 186 graph()->SetEnd(end);
196 return end; 187 return end;
197 } 188 }
198 // End is not dead. 189 // End is not dead.
199 Node* merge = end->InputAt(0); 190 Node* merge = end->InputAt(0);
200 if (merge == NULL || merge->opcode() == IrOpcode::kDead) { 191 if (merge == NULL || merge->opcode() == IrOpcode::kDead) {
201 // The end node died; just connect end to {ret}. 192 // The end node died; just connect end to {terminate}.
202 end->ReplaceInput(0, ret); 193 end->ReplaceInput(0, terminate);
203 } else if (merge->opcode() != IrOpcode::kMerge) { 194 } else if (merge->opcode() != IrOpcode::kMerge) {
204 // Introduce a final merge node for {end->InputAt(0)} and {ret}. 195 // Introduce a final merge node for {end->InputAt(0)} and {terminate}.
205 merge = graph()->NewNode(common()->Merge(2), merge, ret); 196 merge = graph()->NewNode(common()->Merge(2), merge, terminate);
206 end->ReplaceInput(0, merge); 197 end->ReplaceInput(0, merge);
207 ret = merge; 198 terminate = merge;
208 } else { 199 } else {
209 // Append a new input to the final merge at the end. 200 // Append a new input to the final merge at the end.
210 merge->AppendInput(graph()->zone(), ret); 201 merge->AppendInput(graph()->zone(), terminate);
211 merge->set_op(common()->Merge(merge->InputCount())); 202 merge->set_op(common()->Merge(merge->InputCount()));
212 } 203 }
213 return ret; 204 return terminate;
214 } 205 }
215 206
216 void AddNodesReachableFromRoots(ReachabilityMarker& marked, 207 void AddNodesReachableFromRoots(ReachabilityMarker& marked,
217 NodeVector& nodes) { 208 NodeVector& nodes) {
218 jsgraph_->GetCachedNodes(&nodes); // Consider cached nodes roots. 209 jsgraph_->GetCachedNodes(&nodes); // Consider cached nodes roots.
219 Node* end = graph()->end(); 210 Node* end = graph()->end();
220 marked.SetReachableFromEnd(end); 211 marked.SetReachableFromEnd(end);
221 if (!end->IsDead()) nodes.push_back(end); // Consider end to be a root. 212 if (!end->IsDead()) nodes.push_back(end); // Consider end to be a root.
222 for (Node* node : nodes) marked.SetReachableFromEnd(node); 213 for (Node* node : nodes) marked.SetReachableFromEnd(node);
223 AddBackwardsReachableNodes(marked, nodes, 0); 214 AddBackwardsReachableNodes(marked, nodes, 0);
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after
601 case IrOpcode::kIfFalse: 592 case IrOpcode::kIfFalse:
602 return impl.ReduceIfProjection(node, kFalse); 593 return impl.ReduceIfProjection(node, kFalse);
603 default: 594 default:
604 return node; 595 return node;
605 } 596 }
606 } 597 }
607 598
608 } // namespace compiler 599 } // namespace compiler
609 } // namespace internal 600 } // namespace internal
610 } // namespace v8 601 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/common-operator.cc ('k') | src/compiler/instruction-selector.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698