OLD | NEW |
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/compiler-source-position-table.h" |
9 #include "src/compiler/js-graph.h" | 10 #include "src/compiler/js-graph.h" |
10 #include "src/compiler/linkage.h" | 11 #include "src/compiler/linkage.h" |
11 #include "src/compiler/node-matchers.h" | 12 #include "src/compiler/node-matchers.h" |
12 #include "src/compiler/node-properties.h" | 13 #include "src/compiler/node-properties.h" |
13 #include "src/compiler/node.h" | 14 #include "src/compiler/node.h" |
14 #include "src/compiler/schedule.h" | 15 #include "src/compiler/schedule.h" |
15 | 16 |
16 namespace v8 { | 17 namespace v8 { |
17 namespace internal { | 18 namespace internal { |
18 namespace compiler { | 19 namespace compiler { |
19 | 20 |
20 EffectControlLinearizer::EffectControlLinearizer(JSGraph* js_graph, | 21 EffectControlLinearizer::EffectControlLinearizer( |
21 Schedule* schedule, | 22 JSGraph* js_graph, Schedule* schedule, Zone* temp_zone, |
22 Zone* temp_zone) | 23 SourcePositionTable* source_positions) |
23 : js_graph_(js_graph), schedule_(schedule), temp_zone_(temp_zone) {} | 24 : js_graph_(js_graph), |
| 25 schedule_(schedule), |
| 26 temp_zone_(temp_zone), |
| 27 source_positions_(source_positions) {} |
24 | 28 |
25 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); } | 29 Graph* EffectControlLinearizer::graph() const { return js_graph_->graph(); } |
26 CommonOperatorBuilder* EffectControlLinearizer::common() const { | 30 CommonOperatorBuilder* EffectControlLinearizer::common() const { |
27 return js_graph_->common(); | 31 return js_graph_->common(); |
28 } | 32 } |
29 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const { | 33 SimplifiedOperatorBuilder* EffectControlLinearizer::simplified() const { |
30 return js_graph_->simplified(); | 34 return js_graph_->simplified(); |
31 } | 35 } |
32 MachineOperatorBuilder* EffectControlLinearizer::machine() const { | 36 MachineOperatorBuilder* EffectControlLinearizer::machine() const { |
33 return js_graph_->machine(); | 37 return js_graph_->machine(); |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
137 DCHECK(!NodeProperties::IsControlEdge(edge)); | 141 DCHECK(!NodeProperties::IsControlEdge(edge)); |
138 DCHECK(!NodeProperties::IsFrameStateEdge(edge)); | 142 DCHECK(!NodeProperties::IsFrameStateEdge(edge)); |
139 edge.UpdateTo(node->InputAt(0)); | 143 edge.UpdateTo(node->InputAt(0)); |
140 } | 144 } |
141 } | 145 } |
142 node->Kill(); | 146 node->Kill(); |
143 } | 147 } |
144 | 148 |
145 void TryCloneBranch(Node* node, BasicBlock* block, Graph* graph, | 149 void TryCloneBranch(Node* node, BasicBlock* block, Graph* graph, |
146 CommonOperatorBuilder* common, | 150 CommonOperatorBuilder* common, |
147 BlockEffectControlMap* block_effects) { | 151 BlockEffectControlMap* block_effects, |
| 152 SourcePositionTable* source_positions) { |
148 DCHECK_EQ(IrOpcode::kBranch, node->opcode()); | 153 DCHECK_EQ(IrOpcode::kBranch, node->opcode()); |
149 | 154 |
150 // This optimization is a special case of (super)block cloning. It takes an | 155 // This optimization is a special case of (super)block cloning. It takes an |
151 // input graph as shown below and clones the Branch node for every predecessor | 156 // input graph as shown below and clones the Branch node for every predecessor |
152 // to the Merge, essentially removing the Merge completely. This avoids | 157 // to the Merge, essentially removing the Merge completely. This avoids |
153 // materializing the bit for the Phi and may offer potential for further | 158 // materializing the bit for the Phi and may offer potential for further |
154 // branch folding optimizations (i.e. because one or more inputs to the Phi is | 159 // branch folding optimizations (i.e. because one or more inputs to the Phi is |
155 // a constant). Note that there may be more Phi nodes hanging off the Merge, | 160 // a constant). Note that there may be more Phi nodes hanging off the Merge, |
156 // but we can only a certain subset of them currently (actually only Phi and | 161 // but we can only a certain subset of them currently (actually only Phi and |
157 // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control | 162 // EffectPhi nodes whose uses have either the IfTrue or IfFalse as control |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
189 // IfTrue IfFalse ... IfTrue IfFalse | 194 // IfTrue IfFalse ... IfTrue IfFalse |
190 // ^ ^ ^ ^ | 195 // ^ ^ ^ ^ |
191 // | | | | | 196 // | | | | |
192 // +--+ +-------------+ | | 197 // +--+ +-------------+ | |
193 // | | +--------------+ +--+ | 198 // | | +--------------+ +--+ |
194 // | | | | | 199 // | | | | |
195 // Merge Merge | 200 // Merge Merge |
196 // ^ ^ | 201 // ^ ^ |
197 // | | | 202 // | | |
198 | 203 |
| 204 SourcePositionTable::Scope scope(source_positions, |
| 205 source_positions->GetSourcePosition(node)); |
199 Node* branch = node; | 206 Node* branch = node; |
200 Node* cond = NodeProperties::GetValueInput(branch, 0); | 207 Node* cond = NodeProperties::GetValueInput(branch, 0); |
201 if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return; | 208 if (!cond->OwnedBy(branch) || cond->opcode() != IrOpcode::kPhi) return; |
202 Node* merge = NodeProperties::GetControlInput(branch); | 209 Node* merge = NodeProperties::GetControlInput(branch); |
203 if (merge->opcode() != IrOpcode::kMerge || | 210 if (merge->opcode() != IrOpcode::kMerge || |
204 NodeProperties::GetControlInput(cond) != merge) { | 211 NodeProperties::GetControlInput(cond) != merge) { |
205 return; | 212 return; |
206 } | 213 } |
207 // Grab the IfTrue/IfFalse projections of the Branch. | 214 // Grab the IfTrue/IfFalse projections of the Branch. |
208 BranchMatcher matcher(branch); | 215 BranchMatcher matcher(branch); |
(...skipping 232 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
441 case BasicBlock::kSwitch: | 448 case BasicBlock::kSwitch: |
442 case BasicBlock::kReturn: | 449 case BasicBlock::kReturn: |
443 case BasicBlock::kDeoptimize: | 450 case BasicBlock::kDeoptimize: |
444 case BasicBlock::kThrow: | 451 case BasicBlock::kThrow: |
445 ProcessNode(block->control_input(), &frame_state, &effect, &control); | 452 ProcessNode(block->control_input(), &frame_state, &effect, &control); |
446 break; | 453 break; |
447 | 454 |
448 case BasicBlock::kBranch: | 455 case BasicBlock::kBranch: |
449 ProcessNode(block->control_input(), &frame_state, &effect, &control); | 456 ProcessNode(block->control_input(), &frame_state, &effect, &control); |
450 TryCloneBranch(block->control_input(), block, graph(), common(), | 457 TryCloneBranch(block->control_input(), block, graph(), common(), |
451 &block_effects); | 458 &block_effects, source_positions_); |
452 break; | 459 break; |
453 } | 460 } |
454 | 461 |
455 // Store the effect, control and frame state for later use. | 462 // Store the effect, control and frame state for later use. |
456 for (BasicBlock* successor : block->successors()) { | 463 for (BasicBlock* successor : block->successors()) { |
457 BlockEffectControlData* data = &block_effects.For(block, successor); | 464 BlockEffectControlData* data = &block_effects.For(block, successor); |
458 if (data->current_effect == nullptr) { | 465 if (data->current_effect == nullptr) { |
459 data->current_effect = effect; | 466 data->current_effect = effect; |
460 } | 467 } |
461 if (data->current_control == nullptr) { | 468 if (data->current_control == nullptr) { |
(...skipping 25 matching lines...) Expand all Loading... |
487 *control = edge.from(); | 494 *control = edge.from(); |
488 } | 495 } |
489 } | 496 } |
490 } | 497 } |
491 } | 498 } |
492 | 499 |
493 } // namespace | 500 } // namespace |
494 | 501 |
495 void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state, | 502 void EffectControlLinearizer::ProcessNode(Node* node, Node** frame_state, |
496 Node** effect, Node** control) { | 503 Node** effect, Node** control) { |
| 504 SourcePositionTable::Scope scope(source_positions_, |
| 505 source_positions_->GetSourcePosition(node)); |
| 506 |
497 // If the node needs to be wired into the effect/control chain, do this | 507 // If the node needs to be wired into the effect/control chain, do this |
498 // here. Pass current frame state for lowering to eager deoptimization. | 508 // here. Pass current frame state for lowering to eager deoptimization. |
499 if (TryWireInStateEffect(node, *frame_state, effect, control)) { | 509 if (TryWireInStateEffect(node, *frame_state, effect, control)) { |
500 return; | 510 return; |
501 } | 511 } |
502 | 512 |
503 // If the node has a visible effect, then there must be a checkpoint in the | 513 // If the node has a visible effect, then there must be a checkpoint in the |
504 // effect chain before we are allowed to place another eager deoptimization | 514 // effect chain before we are allowed to place another eager deoptimization |
505 // point. We zap the frame state to ensure this invariant is maintained. | 515 // point. We zap the frame state to ensure this invariant is maintained. |
506 if (region_observability_ == RegionObservability::kObservable && | 516 if (region_observability_ == RegionObservability::kObservable && |
(...skipping 3247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3754 isolate(), graph()->zone(), callable.descriptor(), 0, flags, | 3764 isolate(), graph()->zone(), callable.descriptor(), 0, flags, |
3755 Operator::kEliminatable); | 3765 Operator::kEliminatable); |
3756 to_number_operator_.set(common()->Call(desc)); | 3766 to_number_operator_.set(common()->Call(desc)); |
3757 } | 3767 } |
3758 return to_number_operator_.get(); | 3768 return to_number_operator_.get(); |
3759 } | 3769 } |
3760 | 3770 |
3761 } // namespace compiler | 3771 } // namespace compiler |
3762 } // namespace internal | 3772 } // namespace internal |
3763 } // namespace v8 | 3773 } // namespace v8 |
OLD | NEW |