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

Side by Side Diff: src/compiler/instruction-scheduler.cc

Issue 2916143003: handle WASM trap in the instruction scheduler. (Closed)
Patch Set: Created 3 years, 6 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/instruction-scheduler.h ('k') | src/compiler/x64/instruction-scheduler-x64.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 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/instruction-scheduler.h" 5 #include "src/compiler/instruction-scheduler.h"
6 6
7 #include "src/base/adapters.h" 7 #include "src/base/adapters.h"
8 #include "src/base/utils/random-number-generator.h" 8 #include "src/base/utils/random-number-generator.h"
9 9
10 namespace v8 { 10 namespace v8 {
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 start_cycle_(-1) { 70 start_cycle_(-1) {
71 } 71 }
72 72
73 73
74 void InstructionScheduler::ScheduleGraphNode::AddSuccessor( 74 void InstructionScheduler::ScheduleGraphNode::AddSuccessor(
75 ScheduleGraphNode* node) { 75 ScheduleGraphNode* node) {
76 successors_.push_back(node); 76 successors_.push_back(node);
77 node->unscheduled_predecessors_count_++; 77 node->unscheduled_predecessors_count_++;
78 } 78 }
79 79
80
81 InstructionScheduler::InstructionScheduler(Zone* zone, 80 InstructionScheduler::InstructionScheduler(Zone* zone,
82 InstructionSequence* sequence) 81 InstructionSequence* sequence)
83 : zone_(zone), 82 : zone_(zone),
84 sequence_(sequence), 83 sequence_(sequence),
85 graph_(zone), 84 graph_(zone),
86 last_side_effect_instr_(nullptr), 85 last_side_effect_instr_(nullptr),
87 pending_loads_(zone), 86 pending_loads_(zone),
88 last_live_in_reg_marker_(nullptr), 87 last_live_in_reg_marker_(nullptr),
89 last_deopt_(nullptr), 88 last_deopt_or_trap_(nullptr),
90 operands_map_(zone) {} 89 operands_map_(zone) {}
91 90
92
93 void InstructionScheduler::StartBlock(RpoNumber rpo) { 91 void InstructionScheduler::StartBlock(RpoNumber rpo) {
94 DCHECK(graph_.empty()); 92 DCHECK(graph_.empty());
95 DCHECK(last_side_effect_instr_ == nullptr); 93 DCHECK(last_side_effect_instr_ == nullptr);
96 DCHECK(pending_loads_.empty()); 94 DCHECK(pending_loads_.empty());
97 DCHECK(last_live_in_reg_marker_ == nullptr); 95 DCHECK(last_live_in_reg_marker_ == nullptr);
98 DCHECK(last_deopt_ == nullptr); 96 DCHECK(last_deopt_or_trap_ == nullptr);
99 DCHECK(operands_map_.empty()); 97 DCHECK(operands_map_.empty());
100 sequence()->StartBlock(rpo); 98 sequence()->StartBlock(rpo);
101 } 99 }
102 100
103 101
104 void InstructionScheduler::EndBlock(RpoNumber rpo) { 102 void InstructionScheduler::EndBlock(RpoNumber rpo) {
105 if (FLAG_turbo_stress_instruction_scheduling) { 103 if (FLAG_turbo_stress_instruction_scheduling) {
106 ScheduleBlock<StressSchedulerQueue>(); 104 ScheduleBlock<StressSchedulerQueue>();
107 } else { 105 } else {
108 ScheduleBlock<CriticalPathFirstQueue>(); 106 ScheduleBlock<CriticalPathFirstQueue>();
109 } 107 }
110 sequence()->EndBlock(rpo); 108 sequence()->EndBlock(rpo);
111 graph_.clear(); 109 graph_.clear();
112 last_side_effect_instr_ = nullptr; 110 last_side_effect_instr_ = nullptr;
113 pending_loads_.clear(); 111 pending_loads_.clear();
114 last_live_in_reg_marker_ = nullptr; 112 last_live_in_reg_marker_ = nullptr;
115 last_deopt_ = nullptr; 113 last_deopt_or_trap_ = nullptr;
116 operands_map_.clear(); 114 operands_map_.clear();
117 } 115 }
118 116
119 117
120 void InstructionScheduler::AddInstruction(Instruction* instr) { 118 void InstructionScheduler::AddInstruction(Instruction* instr) {
121 ScheduleGraphNode* new_node = new (zone()) ScheduleGraphNode(zone(), instr); 119 ScheduleGraphNode* new_node = new (zone()) ScheduleGraphNode(zone(), instr);
122 120
123 if (IsBlockTerminator(instr)) { 121 if (IsBlockTerminator(instr)) {
124 // Make sure that basic block terminators are not moved by adding them 122 // Make sure that basic block terminators are not moved by adding them
125 // as successor of every instruction. 123 // as successor of every instruction.
126 for (ScheduleGraphNode* node : graph_) { 124 for (ScheduleGraphNode* node : graph_) {
127 node->AddSuccessor(new_node); 125 node->AddSuccessor(new_node);
128 } 126 }
129 } else if (IsFixedRegisterParameter(instr)) { 127 } else if (IsFixedRegisterParameter(instr)) {
130 if (last_live_in_reg_marker_ != nullptr) { 128 if (last_live_in_reg_marker_ != nullptr) {
131 last_live_in_reg_marker_->AddSuccessor(new_node); 129 last_live_in_reg_marker_->AddSuccessor(new_node);
132 } 130 }
133 last_live_in_reg_marker_ = new_node; 131 last_live_in_reg_marker_ = new_node;
134 } else { 132 } else {
135 if (last_live_in_reg_marker_ != nullptr) { 133 if (last_live_in_reg_marker_ != nullptr) {
136 last_live_in_reg_marker_->AddSuccessor(new_node); 134 last_live_in_reg_marker_->AddSuccessor(new_node);
137 } 135 }
138 136
139 // Make sure that instructions are not scheduled before the last 137 // Make sure that instructions are not scheduled before the last
140 // deoptimization point when they depend on it. 138 // deoptimization or trap point when they depend on it.
141 if ((last_deopt_ != nullptr) && DependsOnDeoptimization(instr)) { 139 if ((last_deopt_or_trap_ != nullptr) && DependsOnDeoptOrTrap(instr)) {
142 last_deopt_->AddSuccessor(new_node); 140 last_deopt_or_trap_->AddSuccessor(new_node);
143 } 141 }
144 142
145 // Instructions with side effects and memory operations can't be 143 // Instructions with side effects and memory operations can't be
146 // reordered with respect to each other. 144 // reordered with respect to each other.
147 if (HasSideEffect(instr)) { 145 if (HasSideEffect(instr)) {
148 if (last_side_effect_instr_ != nullptr) { 146 if (last_side_effect_instr_ != nullptr) {
149 last_side_effect_instr_->AddSuccessor(new_node); 147 last_side_effect_instr_->AddSuccessor(new_node);
150 } 148 }
151 for (ScheduleGraphNode* load : pending_loads_) { 149 for (ScheduleGraphNode* load : pending_loads_) {
152 load->AddSuccessor(new_node); 150 load->AddSuccessor(new_node);
153 } 151 }
154 pending_loads_.clear(); 152 pending_loads_.clear();
155 last_side_effect_instr_ = new_node; 153 last_side_effect_instr_ = new_node;
156 } else if (IsLoadOperation(instr)) { 154 } else if (IsLoadOperation(instr)) {
157 // Load operations can't be reordered with side effects instructions but 155 // Load operations can't be reordered with side effects instructions but
158 // independent loads can be reordered with respect to each other. 156 // independent loads can be reordered with respect to each other.
159 if (last_side_effect_instr_ != nullptr) { 157 if (last_side_effect_instr_ != nullptr) {
160 last_side_effect_instr_->AddSuccessor(new_node); 158 last_side_effect_instr_->AddSuccessor(new_node);
161 } 159 }
162 pending_loads_.push_back(new_node); 160 pending_loads_.push_back(new_node);
163 } else if (instr->IsDeoptimizeCall()) { 161 } else if (instr->IsDeoptimizeCall() || instr->IsTrap()) {
164 // Ensure that deopts are not reordered with respect to side-effect 162 // Ensure that deopts or traps are not reordered with respect to
165 // instructions. 163 // side-effect instructions.
166 if (last_side_effect_instr_ != nullptr) { 164 if (last_side_effect_instr_ != nullptr) {
167 last_side_effect_instr_->AddSuccessor(new_node); 165 last_side_effect_instr_->AddSuccessor(new_node);
168 } 166 }
169 last_deopt_ = new_node; 167 last_deopt_or_trap_ = new_node;
170 } 168 }
171 169
172 // Look for operand dependencies. 170 // Look for operand dependencies.
173 for (size_t i = 0; i < instr->InputCount(); ++i) { 171 for (size_t i = 0; i < instr->InputCount(); ++i) {
174 const InstructionOperand* input = instr->InputAt(i); 172 const InstructionOperand* input = instr->InputAt(i);
175 if (input->IsUnallocated()) { 173 if (input->IsUnallocated()) {
176 int32_t vreg = UnallocatedOperand::cast(input)->virtual_register(); 174 int32_t vreg = UnallocatedOperand::cast(input)->virtual_register();
177 auto it = operands_map_.find(vreg); 175 auto it = operands_map_.find(vreg);
178 if (it != operands_map_.end()) { 176 if (it != operands_map_.end()) {
179 it->second->AddSuccessor(new_node); 177 it->second->AddSuccessor(new_node);
(...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after
390 } 388 }
391 } 389 }
392 390
393 node->set_total_latency(max_latency + node->latency()); 391 node->set_total_latency(max_latency + node->latency());
394 } 392 }
395 } 393 }
396 394
397 } // namespace compiler 395 } // namespace compiler
398 } // namespace internal 396 } // namespace internal
399 } // namespace v8 397 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-scheduler.h ('k') | src/compiler/x64/instruction-scheduler-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698