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

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

Issue 1897213003: [turbofan] Properly handle deoptimizations in the instruction scheduler. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Created 4 years, 8 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') | no next file » | 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 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
75 } 75 }
76 76
77 77
78 InstructionScheduler::InstructionScheduler(Zone* zone, 78 InstructionScheduler::InstructionScheduler(Zone* zone,
79 InstructionSequence* sequence) 79 InstructionSequence* sequence)
80 : zone_(zone), 80 : zone_(zone),
81 sequence_(sequence), 81 sequence_(sequence),
82 graph_(zone), 82 graph_(zone),
83 last_side_effect_instr_(nullptr), 83 last_side_effect_instr_(nullptr),
84 pending_loads_(zone), 84 pending_loads_(zone),
85 last_live_in_reg_marker_(nullptr) { 85 last_live_in_reg_marker_(nullptr),
86 last_deopt_(nullptr) {
86 } 87 }
87 88
88 89
89 void InstructionScheduler::StartBlock(RpoNumber rpo) { 90 void InstructionScheduler::StartBlock(RpoNumber rpo) {
90 DCHECK(graph_.empty()); 91 DCHECK(graph_.empty());
91 DCHECK(last_side_effect_instr_ == nullptr); 92 DCHECK(last_side_effect_instr_ == nullptr);
92 DCHECK(pending_loads_.empty()); 93 DCHECK(pending_loads_.empty());
93 DCHECK(last_live_in_reg_marker_ == nullptr); 94 DCHECK(last_live_in_reg_marker_ == nullptr);
95 DCHECK(last_deopt_ == nullptr);
94 sequence()->StartBlock(rpo); 96 sequence()->StartBlock(rpo);
95 } 97 }
96 98
97 99
98 void InstructionScheduler::EndBlock(RpoNumber rpo) { 100 void InstructionScheduler::EndBlock(RpoNumber rpo) {
99 if (FLAG_turbo_stress_instruction_scheduling) { 101 if (FLAG_turbo_stress_instruction_scheduling) {
100 ScheduleBlock<StressSchedulerQueue>(); 102 ScheduleBlock<StressSchedulerQueue>();
101 } else { 103 } else {
102 ScheduleBlock<CriticalPathFirstQueue>(); 104 ScheduleBlock<CriticalPathFirstQueue>();
103 } 105 }
104 sequence()->EndBlock(rpo); 106 sequence()->EndBlock(rpo);
105 graph_.clear(); 107 graph_.clear();
106 last_side_effect_instr_ = nullptr; 108 last_side_effect_instr_ = nullptr;
107 pending_loads_.clear(); 109 pending_loads_.clear();
108 last_live_in_reg_marker_ = nullptr; 110 last_live_in_reg_marker_ = nullptr;
111 last_deopt_ = nullptr;
109 } 112 }
110 113
111 114
112 void InstructionScheduler::AddInstruction(Instruction* instr) { 115 void InstructionScheduler::AddInstruction(Instruction* instr) {
113 ScheduleGraphNode* new_node = new (zone()) ScheduleGraphNode(zone(), instr); 116 ScheduleGraphNode* new_node = new (zone()) ScheduleGraphNode(zone(), instr);
114 117
115 if (IsBlockTerminator(instr)) { 118 if (IsBlockTerminator(instr)) {
116 // Make sure that basic block terminators are not moved by adding them 119 // Make sure that basic block terminators are not moved by adding them
117 // as successor of every instruction. 120 // as successor of every instruction.
118 for (ScheduleGraphNode* node : graph_) { 121 for (ScheduleGraphNode* node : graph_) {
119 node->AddSuccessor(new_node); 122 node->AddSuccessor(new_node);
120 } 123 }
121 } else if (IsFixedRegisterParameter(instr)) { 124 } else if (IsFixedRegisterParameter(instr)) {
122 if (last_live_in_reg_marker_ != nullptr) { 125 if (last_live_in_reg_marker_ != nullptr) {
123 last_live_in_reg_marker_->AddSuccessor(new_node); 126 last_live_in_reg_marker_->AddSuccessor(new_node);
124 } 127 }
125 last_live_in_reg_marker_ = new_node; 128 last_live_in_reg_marker_ = new_node;
126 } else { 129 } else {
127 if (last_live_in_reg_marker_ != nullptr) { 130 if (last_live_in_reg_marker_ != nullptr) {
128 last_live_in_reg_marker_->AddSuccessor(new_node); 131 last_live_in_reg_marker_->AddSuccessor(new_node);
129 } 132 }
130 133
134 // Make sure that new instructions are not scheduled before the last
135 // deoptimization point.
136 if (last_deopt_ != nullptr) {
137 last_deopt_->AddSuccessor(new_node);
138 }
139
131 // Instructions with side effects and memory operations can't be 140 // Instructions with side effects and memory operations can't be
132 // reordered with respect to each other. 141 // reordered with respect to each other.
133 if (HasSideEffect(instr)) { 142 if (HasSideEffect(instr)) {
134 if (last_side_effect_instr_ != nullptr) { 143 if (last_side_effect_instr_ != nullptr) {
135 last_side_effect_instr_->AddSuccessor(new_node); 144 last_side_effect_instr_->AddSuccessor(new_node);
136 } 145 }
137 for (ScheduleGraphNode* load : pending_loads_) { 146 for (ScheduleGraphNode* load : pending_loads_) {
138 load->AddSuccessor(new_node); 147 load->AddSuccessor(new_node);
139 } 148 }
140 pending_loads_.clear(); 149 pending_loads_.clear();
141 last_side_effect_instr_ = new_node; 150 last_side_effect_instr_ = new_node;
142 } else if (IsLoadOperation(instr)) { 151 } else if (IsLoadOperation(instr)) {
143 // Load operations can't be reordered with side effects instructions but 152 // Load operations can't be reordered with side effects instructions but
144 // independent loads can be reordered with respect to each other. 153 // independent loads can be reordered with respect to each other.
145 if (last_side_effect_instr_ != nullptr) { 154 if (last_side_effect_instr_ != nullptr) {
146 last_side_effect_instr_->AddSuccessor(new_node); 155 last_side_effect_instr_->AddSuccessor(new_node);
147 } 156 }
148 pending_loads_.push_back(new_node); 157 pending_loads_.push_back(new_node);
158 } else if (instr->IsDeoptimizeCall()) {
159 // Ensure that deopts are not reordered with respect to side-effect
160 // instructions.
161 if (last_side_effect_instr_ != nullptr) {
162 last_side_effect_instr_->AddSuccessor(new_node);
163 }
164 last_deopt_ = new_node;
149 } 165 }
150 166
151 // Look for operand dependencies. 167 // Look for operand dependencies.
152 for (ScheduleGraphNode* node : graph_) { 168 for (ScheduleGraphNode* node : graph_) {
153 if (HasOperandDependency(node->instruction(), instr)) { 169 if (HasOperandDependency(node->instruction(), instr)) {
154 node->AddSuccessor(new_node); 170 node->AddSuccessor(new_node);
155 } 171 }
156 } 172 }
157 } 173 }
158 174
(...skipping 157 matching lines...) Expand 10 before | Expand all | Expand 10 after
316 } 332 }
317 } 333 }
318 334
319 node->set_total_latency(max_latency + node->latency()); 335 node->set_total_latency(max_latency + node->latency());
320 } 336 }
321 } 337 }
322 338
323 } // namespace compiler 339 } // namespace compiler
324 } // namespace internal 340 } // namespace internal
325 } // namespace v8 341 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/instruction-scheduler.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698