OLD | NEW |
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/instruction-selector.h" | 5 #include "src/compiler/instruction-selector.h" |
6 | 6 |
7 #include <limits> | 7 #include <limits> |
8 | 8 |
9 #include "src/base/adapters.h" | 9 #include "src/base/adapters.h" |
10 #include "src/compiler/compiler-source-position-table.h" | 10 #include "src/compiler/compiler-source-position-table.h" |
(...skipping 810 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
821 bool InstructionSelector::IsSourcePositionUsed(Node* node) { | 821 bool InstructionSelector::IsSourcePositionUsed(Node* node) { |
822 return (source_position_mode_ == kAllSourcePositions || | 822 return (source_position_mode_ == kAllSourcePositions || |
823 node->opcode() == IrOpcode::kCall || | 823 node->opcode() == IrOpcode::kCall || |
824 node->opcode() == IrOpcode::kTrapIf || | 824 node->opcode() == IrOpcode::kTrapIf || |
825 node->opcode() == IrOpcode::kTrapUnless); | 825 node->opcode() == IrOpcode::kTrapUnless); |
826 } | 826 } |
827 | 827 |
828 void InstructionSelector::VisitBlock(BasicBlock* block) { | 828 void InstructionSelector::VisitBlock(BasicBlock* block) { |
829 DCHECK(!current_block_); | 829 DCHECK(!current_block_); |
830 current_block_ = block; | 830 current_block_ = block; |
831 int current_block_end = static_cast<int>(instructions_.size()); | 831 auto current_num_instructions = [&] { |
| 832 DCHECK_GE(kMaxInt, instructions_.size()); |
| 833 return static_cast<int>(instructions_.size()); |
| 834 }; |
| 835 int current_block_end = current_num_instructions(); |
832 | 836 |
833 int effect_level = 0; | 837 int effect_level = 0; |
834 for (Node* const node : *block) { | 838 for (Node* const node : *block) { |
835 if (node->opcode() == IrOpcode::kStore || | 839 if (node->opcode() == IrOpcode::kStore || |
836 node->opcode() == IrOpcode::kUnalignedStore || | 840 node->opcode() == IrOpcode::kUnalignedStore || |
837 node->opcode() == IrOpcode::kCheckedStore || | 841 node->opcode() == IrOpcode::kCheckedStore || |
838 node->opcode() == IrOpcode::kCall) { | 842 node->opcode() == IrOpcode::kCall) { |
839 ++effect_level; | 843 ++effect_level; |
840 } | 844 } |
841 SetEffectLevel(node, effect_level); | 845 SetEffectLevel(node, effect_level); |
842 } | 846 } |
843 | 847 |
844 // We visit the control first, then the nodes in the block, so the block's | 848 // We visit the control first, then the nodes in the block, so the block's |
845 // control input should be on the same effect level as the last node. | 849 // control input should be on the same effect level as the last node. |
846 if (block->control_input() != nullptr) { | 850 if (block->control_input() != nullptr) { |
847 SetEffectLevel(block->control_input(), effect_level); | 851 SetEffectLevel(block->control_input(), effect_level); |
848 } | 852 } |
849 | 853 |
| 854 auto FinishEmittedInstructions = [&](Node* node, int instruction_start) { |
| 855 if (instruction_selection_failed()) return false; |
| 856 if (current_num_instructions() == instruction_start) return true; |
| 857 std::reverse(instructions_.begin() + instruction_start, |
| 858 instructions_.end()); |
| 859 if (!node) return true; |
| 860 SourcePosition source_position = source_positions_->GetSourcePosition(node); |
| 861 if (source_position.IsKnown() && IsSourcePositionUsed(node)) { |
| 862 sequence()->SetSourcePosition(instructions_[instruction_start], |
| 863 source_position); |
| 864 } |
| 865 return true; |
| 866 }; |
| 867 |
850 // Generate code for the block control "top down", but schedule the code | 868 // Generate code for the block control "top down", but schedule the code |
851 // "bottom up". | 869 // "bottom up". |
852 VisitControl(block); | 870 VisitControl(block); |
853 std::reverse(instructions_.begin() + current_block_end, instructions_.end()); | 871 if (!FinishEmittedInstructions(block->control_input(), current_block_end)) |
| 872 return; |
854 | 873 |
855 // Visit code in reverse control flow order, because architecture-specific | 874 // Visit code in reverse control flow order, because architecture-specific |
856 // matching may cover more than one node at a time. | 875 // matching may cover more than one node at a time. |
857 for (auto node : base::Reversed(*block)) { | 876 for (auto node : base::Reversed(*block)) { |
858 // Skip nodes that are unused or already defined. | 877 // Skip nodes that are unused or already defined. |
859 if (!IsUsed(node) || IsDefined(node)) continue; | 878 if (!IsUsed(node) || IsDefined(node)) continue; |
860 // Generate code for this node "top down", but schedule the code "bottom | 879 // Generate code for this node "top down", but schedule the code "bottom |
861 // up". | 880 // up". |
862 size_t current_node_end = instructions_.size(); | 881 int current_node_end = current_num_instructions(); |
863 VisitNode(node); | 882 VisitNode(node); |
864 if (instruction_selection_failed()) return; | 883 if (!FinishEmittedInstructions(node, current_node_end)) return; |
865 std::reverse(instructions_.begin() + current_node_end, instructions_.end()); | |
866 if (instructions_.size() == current_node_end) continue; | |
867 // Mark source position on first instruction emitted. | |
868 SourcePosition source_position = source_positions_->GetSourcePosition(node); | |
869 if (source_position.IsKnown() && IsSourcePositionUsed(node)) { | |
870 sequence()->SetSourcePosition(instructions_[current_node_end], | |
871 source_position); | |
872 } | |
873 } | 884 } |
874 | 885 |
875 // We're done with the block. | 886 // We're done with the block. |
876 InstructionBlock* instruction_block = | 887 InstructionBlock* instruction_block = |
877 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); | 888 sequence()->InstructionBlockAt(RpoNumber::FromInt(block->rpo_number())); |
878 instruction_block->set_code_start(static_cast<int>(instructions_.size())); | 889 instruction_block->set_code_start(static_cast<int>(instructions_.size())); |
879 instruction_block->set_code_end(current_block_end); | 890 instruction_block->set_code_end(current_block_end); |
880 | 891 |
881 current_block_ = nullptr; | 892 current_block_ = nullptr; |
882 } | 893 } |
(...skipping 1277 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2160 return new (instruction_zone()) FrameStateDescriptor( | 2171 return new (instruction_zone()) FrameStateDescriptor( |
2161 instruction_zone(), state_info.type(), state_info.bailout_id(), | 2172 instruction_zone(), state_info.type(), state_info.bailout_id(), |
2162 state_info.state_combine(), parameters, locals, stack, | 2173 state_info.state_combine(), parameters, locals, stack, |
2163 state_info.shared_info(), outer_state); | 2174 state_info.shared_info(), outer_state); |
2164 } | 2175 } |
2165 | 2176 |
2166 | 2177 |
2167 } // namespace compiler | 2178 } // namespace compiler |
2168 } // namespace internal | 2179 } // namespace internal |
2169 } // namespace v8 | 2180 } // namespace v8 |
OLD | NEW |