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

Side by Side Diff: src/compiler/effect-control-linearizer.cc

Issue 2139593002: [turbofan] Move TryCloneBranch in the EffectControlLinearizer pass. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Update Created 4 years, 5 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
OLDNEW
1 // Copyright 2015 the V8 project authors. All rights reserved. 1 // Copyright 2015 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/effect-control-linearizer.h" 5 #include "src/compiler/effect-control-linearizer.h"
6 6
7 #include "src/code-factory.h" 7 #include "src/code-factory.h"
8 #include "src/compiler/access-builder.h" 8 #include "src/compiler/access-builder.h"
9 #include "src/compiler/js-graph.h" 9 #include "src/compiler/js-graph.h"
10 #include "src/compiler/linkage.h" 10 #include "src/compiler/linkage.h"
11 #include "src/compiler/node-matchers.h"
11 #include "src/compiler/node-properties.h" 12 #include "src/compiler/node-properties.h"
12 #include "src/compiler/node.h" 13 #include "src/compiler/node.h"
13 #include "src/compiler/schedule.h" 14 #include "src/compiler/schedule.h"
14 15
15 namespace v8 { 16 namespace v8 {
16 namespace internal { 17 namespace internal {
17 namespace compiler { 18 namespace compiler {
18 19
19 EffectControlLinearizer::EffectControlLinearizer(JSGraph* js_graph, 20 EffectControlLinearizer::EffectControlLinearizer(JSGraph* js_graph,
20 Schedule* schedule, 21 Schedule* schedule,
21 Zone* temp_zone) 22 Zone* temp_zone)
22 : js_graph_(js_graph), schedule_(schedule), temp_zone_(temp_zone) {} 23 : js_graph_(js_graph), schedule_(schedule), temp_zone_(temp_zone) {}
23 24
24 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); } 25 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); }
25 CommonOperatorBuilder* EffectControlLinearizer::common() const { 26 CommonOperatorBuilder* EffectControlLinearizer::common() const {
26 return js_graph_->common(); 27 return js_graph_->common();
27 } 28 }
28 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const { 29 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const {
29 return js_graph_->simplified(); 30 return js_graph_->simplified();
30 } 31 }
31 MachineOperatorBuilder* EffectControlLinearizer::machine() const { 32 MachineOperatorBuilder* EffectControlLinearizer::machine() const {
32 return js_graph_->machine(); 33 return js_graph_->machine();
33 } 34 }
34 35
35 namespace { 36 namespace {
36 37
37 struct BlockEffectControlData { 38 struct BlockEffectControlData {
38 Node* current_effect = nullptr; // New effect. 39 Node* current_effect = nullptr; // New effect.
39 Node* current_control = nullptr; // New control. 40 Node* current_control = nullptr; // New control.
40 Node* current_frame_state = nullptr; // New frame state. 41 Node* current_frame_state = nullptr; // New frame state.
41 }; 42 };
42 43
44 struct BlockDataKey {
45 BasicBlock* from;
Benedikt Meurer 2016/07/12 03:16:14 How about using the rpo numbers as keys instead of
epertoso 2016/07/12 10:14:44 Done.
46 BasicBlock* to;
47
48 BlockDataKey(BasicBlock* from, BasicBlock* to) : from(from), to(to) {}
49 };
50
51 struct BlockDataKeyComparator {
52 bool operator()(const BlockDataKey& lhs, const BlockDataKey& rhs) const {
53 return lhs.from == rhs.from ? lhs.to < rhs.to : lhs.from < rhs.from;
54 }
55 };
56
57 using BlockEffectControlMap =
58 ZoneMap<BlockDataKey, BlockEffectControlData, BlockDataKeyComparator>;
59
43 // Effect phis that need to be updated after the first pass. 60 // Effect phis that need to be updated after the first pass.
44 struct PendingEffectPhi { 61 struct PendingEffectPhi {
45 Node* effect_phi; 62 Node* effect_phi;
46 BasicBlock* block; 63 BasicBlock* block;
47 64
48 PendingEffectPhi(Node* effect_phi, BasicBlock* block) 65 PendingEffectPhi(Node* effect_phi, BasicBlock* block)
49 : effect_phi(effect_phi), block(block) {} 66 : effect_phi(effect_phi), block(block) {}
50 }; 67 };
51 68
52 void UpdateEffectPhi(Node* node, BasicBlock* block, 69 void UpdateEffectPhi(Node* node, BasicBlock* block,
53 ZoneVector<BlockEffectControlData>* block_effects) { 70 BlockEffectControlMap* block_effects) {
54 // Update all inputs to an effect phi with the effects from the given 71 // Update all inputs to an effect phi with the effects from the given
55 // block->effect map. 72 // block->effect map.
56 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode()); 73 DCHECK_EQ(IrOpcode::kEffectPhi, node->opcode());
57 DCHECK_EQ(node->op()->EffectInputCount(), block->PredecessorCount()); 74 DCHECK_EQ(node->op()->EffectInputCount(), block->PredecessorCount());
58 for (int i = 0; i < node->op()->EffectInputCount(); i++) { 75 for (int i = 0; i < node->op()->EffectInputCount(); i++) {
59 Node* input = node->InputAt(i); 76 Node* input = node->InputAt(i);
60 BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i)); 77 BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
61 Node* input_effect = 78 BlockEffectControlMap::iterator it =
62 (*block_effects)[predecessor->rpo_number()].current_effect; 79 block_effects->find({predecessor, block});
Benedikt Meurer 2016/07/12 03:16:14 This kind of uniform initialization is not support
epertoso 2016/07/12 10:14:44 Explicitly using the constructor now.
80 Node* input_effect = it->second.current_effect;
63 if (input != input_effect) { 81 if (input != input_effect) {
64 node->ReplaceInput(i, input_effect); 82 node->ReplaceInput(i, input_effect);
65 } 83 }
66 } 84 }
67 } 85 }
68 86
69 void UpdateBlockControl(BasicBlock* block, 87 void UpdateBlockControl(BasicBlock* block,
70 ZoneVector<BlockEffectControlData>* block_effects) { 88 BlockEffectControlMap* block_effects) {
71 Node* control = block->NodeAt(0); 89 Node* control = block->NodeAt(0);
72 DCHECK(NodeProperties::IsControl(control)); 90 DCHECK(NodeProperties::IsControl(control));
73 91
74 // Do not rewire the end node. 92 // Do not rewire the end node.
75 if (control->opcode() == IrOpcode::kEnd) return; 93 if (control->opcode() == IrOpcode::kEnd) return;
76 94
77 // Update all inputs to the given control node with the correct control. 95 // Update all inputs to the given control node with the correct control.
78 DCHECK_EQ(control->op()->ControlInputCount(), block->PredecessorCount()); 96 DCHECK(control->opcode() == IrOpcode::kMerge ||
97 control->op()->ControlInputCount() == block->PredecessorCount());
98 if (control->op()->ControlInputCount() != block->PredecessorCount())
99 return; // We already wired stuff.
Benedikt Meurer 2016/07/12 03:16:15 Nit: Add { } around the return
epertoso 2016/07/12 10:14:44 Done.
79 for (int i = 0; i < control->op()->ControlInputCount(); i++) { 100 for (int i = 0; i < control->op()->ControlInputCount(); i++) {
80 Node* input = NodeProperties::GetControlInput(control, i); 101 Node* input = NodeProperties::GetControlInput(control, i);
81 BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i)); 102 BasicBlock* predecessor = block->PredecessorAt(static_cast<size_t>(i));
82 Node* input_control = 103 BlockEffectControlMap::iterator it =
83 (*block_effects)[predecessor->rpo_number()].current_control; 104 block_effects->find({predecessor, block});
105 Node* input_control = it->second.current_control;
84 if (input != input_control) { 106 if (input != input_control) {
85 NodeProperties::ReplaceControlInput(control, input_control, i); 107 NodeProperties::ReplaceControlInput(control, input_control, i);
86 } 108 }
87 } 109 }
88 } 110 }
89 111
90 bool HasIncomingBackEdges(BasicBlock* block) { 112 bool HasIncomingBackEdges(BasicBlock* block) {
91 for (BasicBlock* pred : block->predecessors()) { 113 for (BasicBlock* pred : block->predecessors()) {
92 if (pred->rpo_number() >= block->rpo_number()) { 114 if (pred->rpo_number() >= block->rpo_number()) {
93 return true; 115 return true;
(...skipping 13 matching lines...) Expand all
107 edge.UpdateTo(NodeProperties::GetEffectInput(node)); 129 edge.UpdateTo(NodeProperties::GetEffectInput(node));
108 } else { 130 } else {
109 DCHECK(!NodeProperties::IsControlEdge(edge)); 131 DCHECK(!NodeProperties::IsControlEdge(edge));
110 DCHECK(!NodeProperties::IsFrameStateEdge(edge)); 132 DCHECK(!NodeProperties::IsFrameStateEdge(edge));
111 edge.UpdateTo(node->InputAt(0)); 133 edge.UpdateTo(node->InputAt(0));
112 } 134 }
113 } 135 }
114 node->Kill(); 136 node->Kill();
115 } 137 }
116 138
139 void TryCloneBranch(Node* node, BasicBlock* block, Graph* graph,
140 CommonOperatorBuilder* common,
141 BlockEffectControlMap* block_effects) {
142 DCHECK_EQ(IrOpcode::kBranch, node->opcode());
143
144 // This optimization is a special case of (super)block cloning. It takes an
145 // input graph as shown below and clones the Branch node for every predecessor
146 // to the Merge, essentially removing the Merge completely. This avoids
147 // materializing the bit for the Phi and may offer potential for further
148 // branch folding optimizations (i.e. because one or more inputs to the Phi is
149 // a constant). Note that there may be more Phi nodes hanging off the Merge,
150 // but we can only a certain subset of them currently (actually only Phi and
151 // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control
152 // input).
153
154 // Control1 ... ControlN
155 // ^ ^
156 // | | Cond1 ... CondN
157 // +----+ +----+ ^ ^
158 // | | | |
159 // | | +----+ |
160 // Merge<--+ | +------------+
161 // ^ \|/
162 // | Phi
163 // | |
164 // Branch----+
165 // ^
166 // |
167 // +-----+-----+
168 // | |
169 // IfTrue IfFalse
170 // ^ ^
171 // | |
172
173 // The resulting graph (modulo the Phi and EffectPhi nodes) looks like this:
174
175 // Control1 Cond1 ... ControlN CondN
176 // ^ ^ ^ ^
177 // \ / \ /
178 // Branch ... Branch
179 // ^ ^
180 // | |
181 // +---+---+ +---+----+
182 // | | | |
183 // IfTrue IfFalse ... IfTrue IfFalse
184 // ^ ^ ^ ^
185 // | | | |
186 // +--+ +-------------+ |
187 // | | +--------------+ +--+
188 // | | | |
189 // Merge Merge
190 // ^ ^
191 // | |
192
193 Node* branch = node;
194 Node* cond = NodeProperties::GetValueInput(branch, 0);
195 if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return;
196 Node* merge = NodeProperties::GetControlInput(branch);
197 if (merge->opcode() != IrOpcode::kMerge ||
198 NodeProperties::GetControlInput(cond) != merge) {
199 return;
200 }
201 // Grab the IfTrue/IfFalse projections of the Branch.
202 BranchMatcher matcher(branch);
203 // Check/collect other Phi/EffectPhi nodes hanging off the Merge.
204 NodeVector phis(graph->zone());
205 for (Node* const use : merge->uses()) {
206 if (use == branch || use == cond) continue;
207 // We cannot currently deal with non-Phi/EffectPhi nodes hanging off the
208 // Merge. Ideally, we would just clone the nodes (and everything that
209 // depends on it to some distant join point), but that requires knowledge
210 // about dominance/post-dominance.
211 if (!NodeProperties::IsPhi(use)) return;
212 for (Edge edge : use->use_edges()) {
213 // Right now we can only handle Phi/EffectPhi nodes whose uses are
214 // directly control-dependend on either the IfTrue or the IfFalse
215 // successor, because we know exactly how to update those uses.
216 if (edge.from()->op()->ControlInputCount() != 1) return;
217 Node* control = NodeProperties::GetControlInput(edge.from());
218 if (NodeProperties::IsPhi(edge.from())) {
219 control = NodeProperties::GetControlInput(control, edge.index());
220 }
221 if (control != matcher.IfTrue() && control != matcher.IfFalse()) return;
222 }
223 phis.push_back(use);
224 }
225 BranchHint const hint = BranchHintOf(branch->op());
226 int const input_count = merge->op()->ControlInputCount();
227 DCHECK_LE(1, input_count);
228 Node** const inputs = graph->zone()->NewArray<Node*>(2 * input_count);
229 Node** const merge_true_inputs = &inputs[0];
230 Node** const merge_false_inputs = &inputs[input_count];
231 for (int index = 0; index < input_count; ++index) {
232 Node* cond1 = NodeProperties::GetValueInput(cond, index);
233 Node* control1 = NodeProperties::GetControlInput(merge, index);
234 Node* branch1 = graph->NewNode(common->Branch(hint), cond1, control1);
235 merge_true_inputs[index] = graph->NewNode(common->IfTrue(), branch1);
236 merge_false_inputs[index] = graph->NewNode(common->IfFalse(), branch1);
237 }
238 Node* const merge_true = matcher.IfTrue();
239 Node* const merge_false = matcher.IfFalse();
240 merge_true->TrimInputCount(0);
241 merge_false->TrimInputCount(0);
242 for (int i = 0; i < input_count; ++i) {
243 merge_true->AppendInput(graph->zone(), merge_true_inputs[i]);
244 merge_false->AppendInput(graph->zone(), merge_false_inputs[i]);
245 }
246 DCHECK_EQ(2, block->SuccessorCount());
247 NodeProperties::ChangeOp(matcher.IfTrue(), common->Merge(input_count));
248 NodeProperties::ChangeOp(matcher.IfFalse(), common->Merge(input_count));
249 int const true_index =
250 block->SuccessorAt(0)->NodeAt(0) == matcher.IfTrue() ? 0 : 1;
251 BlockEffectControlData* true_block_data =
252 &(*block_effects)[{block, block->SuccessorAt(true_index)}];
253 BlockEffectControlData* false_block_data =
254 &(*block_effects)[{block, block->SuccessorAt(true_index ^ 1)}];
255 for (Node* const phi : phis) {
256 for (int index = 0; index < input_count; ++index) {
257 inputs[index] = phi->InputAt(index);
258 }
259 inputs[input_count] = merge_true;
260 Node* phi_true = graph->NewNode(phi->op(), input_count + 1, inputs);
261 inputs[input_count] = merge_false;
262 Node* phi_false = graph->NewNode(phi->op(), input_count + 1, inputs);
263 if (phi->UseCount() == 0) {
264 DCHECK_EQ(phi->opcode(), IrOpcode::kEffectPhi);
265 DCHECK_EQ(input_count, block->SuccessorCount());
266 } else {
267 for (Edge edge : phi->use_edges()) {
268 Node* control = NodeProperties::GetControlInput(edge.from());
269 if (NodeProperties::IsPhi(edge.from())) {
270 control = NodeProperties::GetControlInput(control, edge.index());
271 }
272 DCHECK(control == matcher.IfTrue() || control == matcher.IfFalse());
273 edge.UpdateTo((control == matcher.IfTrue()) ? phi_true : phi_false);
274 }
275 }
276 true_block_data->current_effect = phi_true;
277 false_block_data->current_effect = phi_false;
278 phi->Kill();
279 }
280 // Fix up IfTrue and IfFalse and kill all dead nodes.
281 if (branch == block->control_input()) {
282 true_block_data->current_control = merge_true;
283 false_block_data->current_control = merge_false;
284 }
285 branch->Kill();
286 cond->Kill();
287 merge->Kill();
288 }
117 } // namespace 289 } // namespace
118 290
119 void EffectControlLinearizer::Run() { 291 void EffectControlLinearizer::Run() {
120 ZoneVector<BlockEffectControlData> block_effects(temp_zone()); 292 BlockEffectControlMap block_effects(temp_zone());
121 ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone()); 293 ZoneVector<PendingEffectPhi> pending_effect_phis(temp_zone());
122 ZoneVector<BasicBlock*> pending_block_controls(temp_zone()); 294 ZoneVector<BasicBlock*> pending_block_controls(temp_zone());
123 block_effects.resize(schedule()->RpoBlockCount());
124 NodeVector inputs_buffer(temp_zone()); 295 NodeVector inputs_buffer(temp_zone());
125 296
126 for (BasicBlock* block : *(schedule()->rpo_order())) { 297 for (BasicBlock* block : *(schedule()->rpo_order())) {
298 for (BasicBlock* successor : block->successors()) {
299 block_effects[{block, successor}] = BlockEffectControlData();
300 }
127 size_t instr = 0; 301 size_t instr = 0;
128 302
129 // The control node should be the first. 303 // The control node should be the first.
130 Node* control = block->NodeAt(instr); 304 Node* control = block->NodeAt(instr);
131 DCHECK(NodeProperties::IsControl(control)); 305 DCHECK(NodeProperties::IsControl(control));
132 // Update the control inputs. 306 // Update the control inputs.
133 if (HasIncomingBackEdges(block)) { 307 if (HasIncomingBackEdges(block)) {
134 // If there are back edges, we need to update later because we have not 308 // If there are back edges, we need to update later because we have not
135 // computed the control yet. This should only happen for loops. 309 // computed the control yet. This should only happen for loops.
136 DCHECK_EQ(IrOpcode::kLoop, control->opcode()); 310 DCHECK_EQ(IrOpcode::kLoop, control->opcode());
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after
179 if (block == schedule()->start()) { 353 if (block == schedule()->start()) {
180 // Start block => effect is start. 354 // Start block => effect is start.
181 DCHECK_EQ(graph()->start(), control); 355 DCHECK_EQ(graph()->start(), control);
182 effect = graph()->start(); 356 effect = graph()->start();
183 } else if (control->opcode() == IrOpcode::kEnd) { 357 } else if (control->opcode() == IrOpcode::kEnd) {
184 // End block is just a dummy, no effect needed. 358 // End block is just a dummy, no effect needed.
185 DCHECK_EQ(BasicBlock::kNone, block->control()); 359 DCHECK_EQ(BasicBlock::kNone, block->control());
186 DCHECK_EQ(1u, block->size()); 360 DCHECK_EQ(1u, block->size());
187 effect = nullptr; 361 effect = nullptr;
188 } else { 362 } else {
189 // If all the predecessors have the same effect, we can use it 363 // If all the predecessors have the same effect, we can use it as our
190 // as our current effect. 364 // current effect.
191 int rpo_number = block->PredecessorAt(0)->rpo_number(); 365 effect = block_effects[{block->PredecessorAt(0), block}].current_effect;
192 effect = block_effects[rpo_number].current_effect; 366 for (size_t i = 1; i < block->PredecessorCount(); ++i) {
193 for (size_t i = 1; i < block->PredecessorCount(); i++) { 367 if (block_effects[{block->PredecessorAt(i), block}].current_effect !=
194 int rpo_number = block->PredecessorAt(i)->rpo_number(); 368 effect) {
195 if (block_effects[rpo_number].current_effect != effect) {
196 effect = nullptr; 369 effect = nullptr;
197 break; 370 break;
198 } 371 }
199 } 372 }
200 if (effect == nullptr) { 373 if (effect == nullptr) {
201 DCHECK_NE(IrOpcode::kIfException, control->opcode()); 374 DCHECK_NE(IrOpcode::kIfException, control->opcode());
202 // The input blocks do not have the same effect. We have 375 // The input blocks do not have the same effect. We have
203 // to create an effect phi node. 376 // to create an effect phi node.
204 inputs_buffer.clear(); 377 inputs_buffer.clear();
205 inputs_buffer.resize(block->PredecessorCount(), graph()->start()); 378 inputs_buffer.resize(block->PredecessorCount(), graph()->start());
(...skipping 19 matching lines...) Expand all
225 398
226 // The frame state at block entry is determined by the frame states leaving 399 // The frame state at block entry is determined by the frame states leaving
227 // all predecessors. In case there is no frame state dominating this block, 400 // all predecessors. In case there is no frame state dominating this block,
228 // we can rely on a checkpoint being present before the next deoptimization. 401 // we can rely on a checkpoint being present before the next deoptimization.
229 // TODO(mstarzinger): Eventually we will need to go hunt for a frame state 402 // TODO(mstarzinger): Eventually we will need to go hunt for a frame state
230 // once deoptimizing nodes roam freely through the schedule. 403 // once deoptimizing nodes roam freely through the schedule.
231 Node* frame_state = nullptr; 404 Node* frame_state = nullptr;
232 if (block != schedule()->start()) { 405 if (block != schedule()->start()) {
233 // If all the predecessors have the same effect, we can use it 406 // If all the predecessors have the same effect, we can use it
234 // as our current effect. 407 // as our current effect.
235 int rpo_number = block->PredecessorAt(0)->rpo_number(); 408 frame_state =
236 frame_state = block_effects[rpo_number].current_frame_state; 409 block_effects[{block->PredecessorAt(0), block}].current_frame_state;
237 for (size_t i = 1; i < block->PredecessorCount(); i++) { 410 for (size_t i = 1; i < block->PredecessorCount(); i++) {
238 int rpo_number = block->PredecessorAt(i)->rpo_number(); 411 if (block_effects[{block->PredecessorAt(i), block}]
239 if (block_effects[rpo_number].current_frame_state != frame_state) { 412 .current_frame_state != frame_state) {
240 frame_state = nullptr; 413 frame_state = nullptr;
241 break; 414 break;
242 } 415 }
243 } 416 }
244 } 417 }
245 418
246 // Process the ordinary instructions. 419 // Process the ordinary instructions.
247 for (; instr < block->NodeCount(); instr++) { 420 for (; instr < block->NodeCount(); instr++) {
248 Node* node = block->NodeAt(instr); 421 Node* node = block->NodeAt(instr);
249 ProcessNode(node, &frame_state, &effect, &control); 422 ProcessNode(node, &frame_state, &effect, &control);
250 } 423 }
251 424
252 switch (block->control()) { 425 switch (block->control()) {
253 case BasicBlock::kGoto: 426 case BasicBlock::kGoto:
254 case BasicBlock::kNone: 427 case BasicBlock::kNone:
255 break; 428 break;
256 429
257 case BasicBlock::kCall: 430 case BasicBlock::kCall:
258 case BasicBlock::kTailCall: 431 case BasicBlock::kTailCall:
259 case BasicBlock::kBranch: 432 case BasicBlock::kBranch:
260 case BasicBlock::kSwitch: 433 case BasicBlock::kSwitch:
261 case BasicBlock::kReturn: 434 case BasicBlock::kReturn:
262 case BasicBlock::kDeoptimize: 435 case BasicBlock::kDeoptimize:
263 case BasicBlock::kThrow: 436 case BasicBlock::kThrow: {
264 ProcessNode(block->control_input(), &frame_state, &effect, &control); 437 ProcessNode(block->control_input(), &frame_state, &effect, &control);
265 break; 438 if (block->control() == BasicBlock::kBranch) {
439 TryCloneBranch(block->control_input(), block, graph(), common(),
440 &block_effects);
441 }
442 } break;
266 } 443 }
267 444
268 // Store the effect for later use. 445 // Store the effect, control and frame state for later use.
269 block_effects[block->rpo_number()].current_effect = effect; 446 for (BasicBlock* successor : block->successors()) {
270 block_effects[block->rpo_number()].current_control = control; 447 BlockEffectControlData& data = block_effects[{block, successor}];
271 block_effects[block->rpo_number()].current_frame_state = frame_state; 448 if (data.current_effect == nullptr) {
449 data.current_effect = effect;
450 }
451 if (data.current_control == nullptr) {
452 data.current_control = control;
453 }
454 data.current_frame_state = frame_state;
455 }
272 } 456 }
273 457
274 // Update the incoming edges of the effect phis that could not be processed 458 // Update the incoming edges of the effect phis that could not be processed
275 // during the first pass (because they could have incoming back edges). 459 // during the first pass (because they could have incoming back edges).
276 for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) { 460 for (const PendingEffectPhi& pending_effect_phi : pending_effect_phis) {
277 UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block, 461 UpdateEffectPhi(pending_effect_phi.effect_phi, pending_effect_phi.block,
278 &block_effects); 462 &block_effects);
279 } 463 }
280 for (BasicBlock* pending_block_control : pending_block_controls) { 464 for (BasicBlock* pending_block_control : pending_block_controls) {
281 UpdateBlockControl(pending_block_control, &block_effects); 465 UpdateBlockControl(pending_block_control, &block_effects);
(...skipping 1586 matching lines...) Expand 10 before | Expand all | Expand 10 after
1868 isolate(), graph()->zone(), callable.descriptor(), 0, flags, 2052 isolate(), graph()->zone(), callable.descriptor(), 0, flags,
1869 Operator::kNoThrow); 2053 Operator::kNoThrow);
1870 to_number_operator_.set(common()->Call(desc)); 2054 to_number_operator_.set(common()->Call(desc));
1871 } 2055 }
1872 return to_number_operator_.get(); 2056 return to_number_operator_.get();
1873 } 2057 }
1874 2058
1875 } // namespace compiler 2059 } // namespace compiler
1876 } // namespace internal 2060 } // namespace internal
1877 } // namespace v8 2061 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/control-flow-optimizer.cc ('k') | test/unittests/compiler/control-flow-optimizer-unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698