| 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 |