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

Side by Side Diff: src/compiler/bytecode-graph-builder.cc

Issue 2541443002: Revert of [ignition/turbo] Perform liveness analysis on the bytecodes (Closed)
Patch Set: Created 4 years 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/bytecode-graph-builder.h ('k') | src/compiler/bytecode-liveness-map.h » ('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/bytecode-graph-builder.h" 5 #include "src/compiler/bytecode-graph-builder.h"
6 6
7 #include "src/ast/ast.h" 7 #include "src/ast/ast.h"
8 #include "src/ast/scopes.h" 8 #include "src/ast/scopes.h"
9 #include "src/compilation-info.h" 9 #include "src/compilation-info.h"
10 #include "src/compiler/compiler-source-position-table.h" 10 #include "src/compiler/compiler-source-position-table.h"
(...skipping 17 matching lines...) Expand all
28 // Specifies whether environment binding methods should attach frame state 28 // Specifies whether environment binding methods should attach frame state
29 // inputs to nodes representing the value being bound. This is done because 29 // inputs to nodes representing the value being bound. This is done because
30 // the {OutputFrameStateCombine} is closely related to the binding method. 30 // the {OutputFrameStateCombine} is closely related to the binding method.
31 enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState }; 31 enum FrameStateAttachmentMode { kAttachFrameState, kDontAttachFrameState };
32 32
33 int parameter_count() const { return parameter_count_; } 33 int parameter_count() const { return parameter_count_; }
34 int register_count() const { return register_count_; } 34 int register_count() const { return register_count_; }
35 35
36 Node* LookupAccumulator() const; 36 Node* LookupAccumulator() const;
37 Node* LookupRegister(interpreter::Register the_register) const; 37 Node* LookupRegister(interpreter::Register the_register) const;
38 void MarkAllRegistersLive();
38 39
39 void BindAccumulator(Node* node, 40 void BindAccumulator(Node* node,
40 FrameStateAttachmentMode mode = kDontAttachFrameState); 41 FrameStateAttachmentMode mode = kDontAttachFrameState);
41 void BindRegister(interpreter::Register the_register, Node* node, 42 void BindRegister(interpreter::Register the_register, Node* node,
42 FrameStateAttachmentMode mode = kDontAttachFrameState); 43 FrameStateAttachmentMode mode = kDontAttachFrameState);
43 void BindRegistersToProjections( 44 void BindRegistersToProjections(
44 interpreter::Register first_reg, Node* node, 45 interpreter::Register first_reg, Node* node,
45 FrameStateAttachmentMode mode = kDontAttachFrameState); 46 FrameStateAttachmentMode mode = kDontAttachFrameState);
46 void RecordAfterState(Node* node, 47 void RecordAfterState(Node* node,
47 FrameStateAttachmentMode mode = kDontAttachFrameState); 48 FrameStateAttachmentMode mode = kDontAttachFrameState);
48 49
49 // Effect dependency tracked by this environment. 50 // Effect dependency tracked by this environment.
50 Node* GetEffectDependency() { return effect_dependency_; } 51 Node* GetEffectDependency() { return effect_dependency_; }
51 void UpdateEffectDependency(Node* dependency) { 52 void UpdateEffectDependency(Node* dependency) {
52 effect_dependency_ = dependency; 53 effect_dependency_ = dependency;
53 } 54 }
54 55
55 // Preserve a checkpoint of the environment for the IR graph. Any 56 // Preserve a checkpoint of the environment for the IR graph. Any
56 // further mutation of the environment will not affect checkpoints. 57 // further mutation of the environment will not affect checkpoints.
57 Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine, 58 Node* Checkpoint(BailoutId bytecode_offset, OutputFrameStateCombine combine,
58 bool owner_has_exception, const BitVector* liveness); 59 bool owner_has_exception);
59 60
60 // Control dependency tracked by this environment. 61 // Control dependency tracked by this environment.
61 Node* GetControlDependency() const { return control_dependency_; } 62 Node* GetControlDependency() const { return control_dependency_; }
62 void UpdateControlDependency(Node* dependency) { 63 void UpdateControlDependency(Node* dependency) {
63 control_dependency_ = dependency; 64 control_dependency_ = dependency;
64 } 65 }
65 66
66 Node* Context() const { return context_; } 67 Node* Context() const { return context_; }
67 void SetContext(Node* new_context) { context_ = new_context; } 68 void SetContext(Node* new_context) { context_ = new_context; }
68 69
69 Environment* CopyForConditional(); 70 Environment* CopyForConditional();
70 Environment* CopyForLoop(); 71 Environment* CopyForLoop();
71 Environment* CopyForOsrEntry(); 72 Environment* CopyForOsrEntry();
72 void Merge(Environment* other); 73 void Merge(Environment* other);
73 void PrepareForOsrEntry(); 74 void PrepareForOsrEntry();
74 75
75 void PrepareForLoopExit(Node* loop); 76 void PrepareForLoopExit(Node* loop);
76 77
77 private: 78 private:
78 explicit Environment(const Environment* copy); 79 Environment(const Environment* copy, LivenessAnalyzerBlock* liveness_block);
79 void PrepareForLoop(); 80 void PrepareForLoop();
80 81
81 bool StateValuesRequireUpdate(Node** state_values, Node** values, int count); 82 bool StateValuesRequireUpdate(Node** state_values, int offset, int count);
82 void UpdateStateValues(Node** state_values, Node** values, int count); 83 void UpdateStateValues(Node** state_values, int offset, int count);
83 void UpdateStateValuesWithCache(Node** state_values, Node** values,
84 int count);
85 84
86 int RegisterToValuesIndex(interpreter::Register the_register) const; 85 int RegisterToValuesIndex(interpreter::Register the_register) const;
87 86
87 bool IsLivenessBlockConsistent() const;
88
88 Zone* zone() const { return builder_->local_zone(); } 89 Zone* zone() const { return builder_->local_zone(); }
89 Graph* graph() const { return builder_->graph(); } 90 Graph* graph() const { return builder_->graph(); }
90 CommonOperatorBuilder* common() const { return builder_->common(); } 91 CommonOperatorBuilder* common() const { return builder_->common(); }
91 BytecodeGraphBuilder* builder() const { return builder_; } 92 BytecodeGraphBuilder* builder() const { return builder_; }
93 LivenessAnalyzerBlock* liveness_block() const { return liveness_block_; }
92 const NodeVector* values() const { return &values_; } 94 const NodeVector* values() const { return &values_; }
93 NodeVector* values() { return &values_; } 95 NodeVector* values() { return &values_; }
94 int register_base() const { return register_base_; } 96 int register_base() const { return register_base_; }
95 int accumulator_base() const { return accumulator_base_; } 97 int accumulator_base() const { return accumulator_base_; }
96 98
97 BytecodeGraphBuilder* builder_; 99 BytecodeGraphBuilder* builder_;
98 int register_count_; 100 int register_count_;
99 int parameter_count_; 101 int parameter_count_;
102 LivenessAnalyzerBlock* liveness_block_;
100 Node* context_; 103 Node* context_;
101 Node* control_dependency_; 104 Node* control_dependency_;
102 Node* effect_dependency_; 105 Node* effect_dependency_;
103 NodeVector values_; 106 NodeVector values_;
104 Node* parameters_state_values_; 107 Node* parameters_state_values_;
105 Node* registers_state_values_; 108 Node* registers_state_values_;
106 Node* accumulator_state_values_; 109 Node* accumulator_state_values_;
107 int register_base_; 110 int register_base_;
108 int accumulator_base_; 111 int accumulator_base_;
109
110 // A working area for writing maybe-dead values to when updating the state
111 // values for registers.
112 NodeVector state_value_working_area_;
113 }; 112 };
114 113
115 114
116 // Issues: 115 // Issues:
117 // - Scopes - intimately tied to AST. Need to eval what is needed. 116 // - Scopes - intimately tied to AST. Need to eval what is needed.
118 // - Need to resolve closure parameter treatment. 117 // - Need to resolve closure parameter treatment.
119 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder, 118 BytecodeGraphBuilder::Environment::Environment(BytecodeGraphBuilder* builder,
120 int register_count, 119 int register_count,
121 int parameter_count, 120 int parameter_count,
122 Node* control_dependency, 121 Node* control_dependency,
123 Node* context) 122 Node* context)
124 : builder_(builder), 123 : builder_(builder),
125 register_count_(register_count), 124 register_count_(register_count),
126 parameter_count_(parameter_count), 125 parameter_count_(parameter_count),
126 liveness_block_(builder->is_liveness_analysis_enabled_
127 ? builder_->liveness_analyzer()->NewBlock()
128 : nullptr),
127 context_(context), 129 context_(context),
128 control_dependency_(control_dependency), 130 control_dependency_(control_dependency),
129 effect_dependency_(control_dependency), 131 effect_dependency_(control_dependency),
130 values_(builder->local_zone()), 132 values_(builder->local_zone()),
131 parameters_state_values_(nullptr), 133 parameters_state_values_(nullptr),
132 registers_state_values_(nullptr), 134 registers_state_values_(nullptr),
133 accumulator_state_values_(nullptr), 135 accumulator_state_values_(nullptr) {
134 state_value_working_area_(builder->local_zone()) {
135 // The layout of values_ is: 136 // The layout of values_ is:
136 // 137 //
137 // [receiver] [parameters] [registers] [accumulator] 138 // [receiver] [parameters] [registers] [accumulator]
138 // 139 //
139 // parameter[0] is the receiver (this), parameters 1..N are the 140 // parameter[0] is the receiver (this), parameters 1..N are the
140 // parameters supplied to the method (arg0..argN-1). The accumulator 141 // parameters supplied to the method (arg0..argN-1). The accumulator
141 // is stored separately. 142 // is stored separately.
142 143
143 // Parameters including the receiver 144 // Parameters including the receiver
144 for (int i = 0; i < parameter_count; i++) { 145 for (int i = 0; i < parameter_count; i++) {
145 const char* debug_name = (i == 0) ? "%this" : nullptr; 146 const char* debug_name = (i == 0) ? "%this" : nullptr;
146 const Operator* op = common()->Parameter(i, debug_name); 147 const Operator* op = common()->Parameter(i, debug_name);
147 Node* parameter = builder->graph()->NewNode(op, graph()->start()); 148 Node* parameter = builder->graph()->NewNode(op, graph()->start());
148 values()->push_back(parameter); 149 values()->push_back(parameter);
149 } 150 }
150 151
151 // Registers 152 // Registers
152 register_base_ = static_cast<int>(values()->size()); 153 register_base_ = static_cast<int>(values()->size());
153 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); 154 Node* undefined_constant = builder->jsgraph()->UndefinedConstant();
154 values()->insert(values()->end(), register_count, undefined_constant); 155 values()->insert(values()->end(), register_count, undefined_constant);
155 156
156 // Accumulator 157 // Accumulator
157 accumulator_base_ = static_cast<int>(values()->size()); 158 accumulator_base_ = static_cast<int>(values()->size());
158 values()->push_back(undefined_constant); 159 values()->push_back(undefined_constant);
159
160 state_value_working_area_.resize(register_count_);
161 } 160 }
162 161
163 BytecodeGraphBuilder::Environment::Environment( 162 BytecodeGraphBuilder::Environment::Environment(
164 const BytecodeGraphBuilder::Environment* other) 163 const BytecodeGraphBuilder::Environment* other,
164 LivenessAnalyzerBlock* liveness_block)
165 : builder_(other->builder_), 165 : builder_(other->builder_),
166 register_count_(other->register_count_), 166 register_count_(other->register_count_),
167 parameter_count_(other->parameter_count_), 167 parameter_count_(other->parameter_count_),
168 liveness_block_(liveness_block),
168 context_(other->context_), 169 context_(other->context_),
169 control_dependency_(other->control_dependency_), 170 control_dependency_(other->control_dependency_),
170 effect_dependency_(other->effect_dependency_), 171 effect_dependency_(other->effect_dependency_),
171 values_(other->zone()), 172 values_(other->zone()),
172 parameters_state_values_(nullptr), 173 parameters_state_values_(nullptr),
173 registers_state_values_(nullptr), 174 registers_state_values_(nullptr),
174 accumulator_state_values_(nullptr), 175 accumulator_state_values_(nullptr),
175 register_base_(other->register_base_), 176 register_base_(other->register_base_),
176 accumulator_base_(other->accumulator_base_), 177 accumulator_base_(other->accumulator_base_) {
177 // Environments can share their working area.
178 state_value_working_area_(other->state_value_working_area_) {
179 values_ = other->values_; 178 values_ = other->values_;
180 } 179 }
181 180
182 181
183 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex( 182 int BytecodeGraphBuilder::Environment::RegisterToValuesIndex(
184 interpreter::Register the_register) const { 183 interpreter::Register the_register) const {
185 if (the_register.is_parameter()) { 184 if (the_register.is_parameter()) {
186 return the_register.ToParameterIndex(parameter_count()); 185 return the_register.ToParameterIndex(parameter_count());
187 } else { 186 } else {
188 return the_register.index() + register_base(); 187 return the_register.index() + register_base();
189 } 188 }
190 } 189 }
191 190
191 bool BytecodeGraphBuilder::Environment::IsLivenessBlockConsistent() const {
192 return !builder_->IsLivenessAnalysisEnabled() ==
193 (liveness_block() == nullptr);
194 }
195
192 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const { 196 Node* BytecodeGraphBuilder::Environment::LookupAccumulator() const {
197 DCHECK(IsLivenessBlockConsistent());
198 if (liveness_block() != nullptr) {
199 liveness_block()->LookupAccumulator();
200 }
193 return values()->at(accumulator_base_); 201 return values()->at(accumulator_base_);
194 } 202 }
195 203
196 204
197 Node* BytecodeGraphBuilder::Environment::LookupRegister( 205 Node* BytecodeGraphBuilder::Environment::LookupRegister(
198 interpreter::Register the_register) const { 206 interpreter::Register the_register) const {
199 if (the_register.is_current_context()) { 207 if (the_register.is_current_context()) {
200 return Context(); 208 return Context();
201 } else if (the_register.is_function_closure()) { 209 } else if (the_register.is_function_closure()) {
202 return builder()->GetFunctionClosure(); 210 return builder()->GetFunctionClosure();
203 } else if (the_register.is_new_target()) { 211 } else if (the_register.is_new_target()) {
204 return builder()->GetNewTarget(); 212 return builder()->GetNewTarget();
205 } else { 213 } else {
206 int values_index = RegisterToValuesIndex(the_register); 214 int values_index = RegisterToValuesIndex(the_register);
215 if (liveness_block() != nullptr && !the_register.is_parameter()) {
216 DCHECK(IsLivenessBlockConsistent());
217 liveness_block()->Lookup(the_register.index());
218 }
207 return values()->at(values_index); 219 return values()->at(values_index);
208 } 220 }
209 } 221 }
210 222
223 void BytecodeGraphBuilder::Environment::MarkAllRegistersLive() {
224 DCHECK(IsLivenessBlockConsistent());
225 if (liveness_block() != nullptr) {
226 for (int i = 0; i < register_count(); ++i) {
227 liveness_block()->Lookup(i);
228 }
229 }
230 }
231
211 void BytecodeGraphBuilder::Environment::BindAccumulator( 232 void BytecodeGraphBuilder::Environment::BindAccumulator(
212 Node* node, FrameStateAttachmentMode mode) { 233 Node* node, FrameStateAttachmentMode mode) {
213 if (mode == FrameStateAttachmentMode::kAttachFrameState) { 234 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
214 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0)); 235 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(0));
215 } 236 }
237 DCHECK(IsLivenessBlockConsistent());
238 if (liveness_block() != nullptr) {
239 liveness_block()->BindAccumulator();
240 }
216 values()->at(accumulator_base_) = node; 241 values()->at(accumulator_base_) = node;
217 } 242 }
218 243
219 void BytecodeGraphBuilder::Environment::BindRegister( 244 void BytecodeGraphBuilder::Environment::BindRegister(
220 interpreter::Register the_register, Node* node, 245 interpreter::Register the_register, Node* node,
221 FrameStateAttachmentMode mode) { 246 FrameStateAttachmentMode mode) {
222 int values_index = RegisterToValuesIndex(the_register); 247 int values_index = RegisterToValuesIndex(the_register);
223 if (mode == FrameStateAttachmentMode::kAttachFrameState) { 248 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
224 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt( 249 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
225 accumulator_base_ - values_index)); 250 accumulator_base_ - values_index));
226 } 251 }
227 values()->at(values_index) = node; 252 values()->at(values_index) = node;
253 if (liveness_block() != nullptr && !the_register.is_parameter()) {
254 DCHECK(IsLivenessBlockConsistent());
255 liveness_block()->Bind(the_register.index());
256 }
228 } 257 }
229 258
230 void BytecodeGraphBuilder::Environment::BindRegistersToProjections( 259 void BytecodeGraphBuilder::Environment::BindRegistersToProjections(
231 interpreter::Register first_reg, Node* node, 260 interpreter::Register first_reg, Node* node,
232 FrameStateAttachmentMode mode) { 261 FrameStateAttachmentMode mode) {
233 int values_index = RegisterToValuesIndex(first_reg); 262 int values_index = RegisterToValuesIndex(first_reg);
234 if (mode == FrameStateAttachmentMode::kAttachFrameState) { 263 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
235 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt( 264 builder()->PrepareFrameState(node, OutputFrameStateCombine::PokeAt(
236 accumulator_base_ - values_index)); 265 accumulator_base_ - values_index));
237 } 266 }
238 for (int i = 0; i < node->op()->ValueOutputCount(); i++) { 267 for (int i = 0; i < node->op()->ValueOutputCount(); i++) {
239 values()->at(values_index + i) = 268 values()->at(values_index + i) =
240 builder()->NewNode(common()->Projection(i), node); 269 builder()->NewNode(common()->Projection(i), node);
241 } 270 }
242 } 271 }
243 272
244 void BytecodeGraphBuilder::Environment::RecordAfterState( 273 void BytecodeGraphBuilder::Environment::RecordAfterState(
245 Node* node, FrameStateAttachmentMode mode) { 274 Node* node, FrameStateAttachmentMode mode) {
246 if (mode == FrameStateAttachmentMode::kAttachFrameState) { 275 if (mode == FrameStateAttachmentMode::kAttachFrameState) {
247 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore()); 276 builder()->PrepareFrameState(node, OutputFrameStateCombine::Ignore());
248 } 277 }
249 } 278 }
250 279
251 280
252 BytecodeGraphBuilder::Environment* 281 BytecodeGraphBuilder::Environment*
253 BytecodeGraphBuilder::Environment::CopyForLoop() { 282 BytecodeGraphBuilder::Environment::CopyForLoop() {
254 PrepareForLoop(); 283 PrepareForLoop();
255 return new (zone()) Environment(this); 284 if (liveness_block() != nullptr) {
285 // Finish the current block before copying.
286 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
287 }
288 return new (zone()) Environment(this, liveness_block());
256 } 289 }
257 290
258 BytecodeGraphBuilder::Environment* 291 BytecodeGraphBuilder::Environment*
259 BytecodeGraphBuilder::Environment::CopyForOsrEntry() { 292 BytecodeGraphBuilder::Environment::CopyForOsrEntry() {
260 return new (zone()) Environment(this); 293 return new (zone())
294 Environment(this, builder_->liveness_analyzer()->NewBlock());
261 } 295 }
262 296
263 BytecodeGraphBuilder::Environment* 297 BytecodeGraphBuilder::Environment*
264 BytecodeGraphBuilder::Environment::CopyForConditional() { 298 BytecodeGraphBuilder::Environment::CopyForConditional() {
265 return new (zone()) Environment(this); 299 LivenessAnalyzerBlock* copy_liveness_block = nullptr;
300 if (liveness_block() != nullptr) {
301 copy_liveness_block =
302 builder_->liveness_analyzer()->NewBlock(liveness_block());
303 liveness_block_ = builder_->liveness_analyzer()->NewBlock(liveness_block());
304 }
305 return new (zone()) Environment(this, copy_liveness_block);
266 } 306 }
267 307
268 308
269 void BytecodeGraphBuilder::Environment::Merge( 309 void BytecodeGraphBuilder::Environment::Merge(
270 BytecodeGraphBuilder::Environment* other) { 310 BytecodeGraphBuilder::Environment* other) {
311 if (builder_->is_liveness_analysis_enabled_) {
312 if (GetControlDependency()->opcode() != IrOpcode::kLoop) {
313 liveness_block_ =
314 builder()->liveness_analyzer()->NewBlock(liveness_block());
315 }
316 liveness_block()->AddPredecessor(other->liveness_block());
317 }
318
271 // Create a merge of the control dependencies of both environments and update 319 // Create a merge of the control dependencies of both environments and update
272 // the current environment's control dependency accordingly. 320 // the current environment's control dependency accordingly.
273 Node* control = builder()->MergeControl(GetControlDependency(), 321 Node* control = builder()->MergeControl(GetControlDependency(),
274 other->GetControlDependency()); 322 other->GetControlDependency());
275 UpdateControlDependency(control); 323 UpdateControlDependency(control);
276 324
277 // Create a merge of the effect dependencies of both environments and update 325 // Create a merge of the effect dependencies of both environments and update
278 // the current environment's effect dependency accordingly. 326 // the current environment's effect dependency accordingly.
279 Node* effect = builder()->MergeEffect(GetEffectDependency(), 327 Node* effect = builder()->MergeEffect(GetEffectDependency(),
280 other->GetEffectDependency(), control); 328 other->GetEffectDependency(), control);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
328 int size = static_cast<int>(values()->size()); 376 int size = static_cast<int>(values()->size());
329 for (int i = 0; i < size; i++) { 377 for (int i = 0; i < size; i++) {
330 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly. 378 int idx = i; // Indexing scheme follows {StandardFrame}, adapt accordingly.
331 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount; 379 if (i >= register_base()) idx += InterpreterFrameConstants::kExtraSlotCount;
332 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex; 380 if (i >= accumulator_base()) idx = Linkage::kOsrAccumulatorRegisterIndex;
333 values()->at(i) = graph()->NewNode(common()->OsrValue(idx), entry); 381 values()->at(i) = graph()->NewNode(common()->OsrValue(idx), entry);
334 } 382 }
335 383
336 BailoutId loop_id(builder_->bytecode_iterator().current_offset()); 384 BailoutId loop_id(builder_->bytecode_iterator().current_offset());
337 Node* frame_state = 385 Node* frame_state =
338 Checkpoint(loop_id, OutputFrameStateCombine::Ignore(), false, nullptr); 386 Checkpoint(loop_id, OutputFrameStateCombine::Ignore(), false);
339 Node* checkpoint = 387 Node* checkpoint =
340 graph()->NewNode(common()->Checkpoint(), frame_state, entry, entry); 388 graph()->NewNode(common()->Checkpoint(), frame_state, entry, entry);
341 UpdateEffectDependency(checkpoint); 389 UpdateEffectDependency(checkpoint);
342 390
343 // Create the OSR guard nodes. 391 // Create the OSR guard nodes.
344 const Operator* guard_op = common()->OsrGuard(OsrGuardType::kUninitialized); 392 const Operator* guard_op = common()->OsrGuard(OsrGuardType::kUninitialized);
345 Node* effect = checkpoint; 393 Node* effect = checkpoint;
346 for (int i = 0; i < size; i++) { 394 for (int i = 0; i < size; i++) {
347 values()->at(i) = effect = 395 values()->at(i) = effect =
348 graph()->NewNode(guard_op, values()->at(i), effect, entry); 396 graph()->NewNode(guard_op, values()->at(i), effect, entry);
349 } 397 }
350 Node* context = effect = graph()->NewNode(guard_op, Context(), effect, entry); 398 Node* context = effect = graph()->NewNode(guard_op, Context(), effect, entry);
351 SetContext(context); 399 SetContext(context);
352 UpdateEffectDependency(effect); 400 UpdateEffectDependency(effect);
353 } 401 }
354 402
355 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate( 403 bool BytecodeGraphBuilder::Environment::StateValuesRequireUpdate(
356 Node** state_values, Node** values, int count) { 404 Node** state_values, int offset, int count) {
357 if (*state_values == nullptr) { 405 if (*state_values == nullptr) {
358 return true; 406 return true;
359 } 407 }
360 DCHECK_EQ((*state_values)->InputCount(), count); 408 DCHECK_EQ((*state_values)->InputCount(), count);
409 DCHECK_LE(static_cast<size_t>(offset + count), values()->size());
410 Node** env_values = (count == 0) ? nullptr : &values()->at(offset);
361 for (int i = 0; i < count; i++) { 411 for (int i = 0; i < count; i++) {
362 if ((*state_values)->InputAt(i) != values[i]) { 412 if ((*state_values)->InputAt(i) != env_values[i]) {
363 return true; 413 return true;
364 } 414 }
365 } 415 }
366 return false; 416 return false;
367 } 417 }
368 418
369 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) { 419 void BytecodeGraphBuilder::Environment::PrepareForLoopExit(Node* loop) {
370 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop); 420 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
371 421
372 Node* control = GetControlDependency(); 422 Node* control = GetControlDependency();
(...skipping 13 matching lines...) Expand all
386 436
387 // Rename the environmnent values. 437 // Rename the environmnent values.
388 for (size_t i = 0; i < values_.size(); i++) { 438 for (size_t i = 0; i < values_.size(); i++) {
389 Node* rename = 439 Node* rename =
390 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit); 440 graph()->NewNode(common()->LoopExitValue(), values_[i], loop_exit);
391 values_[i] = rename; 441 values_[i] = rename;
392 } 442 }
393 } 443 }
394 444
395 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values, 445 void BytecodeGraphBuilder::Environment::UpdateStateValues(Node** state_values,
396 Node** values, 446 int offset,
397 int count) { 447 int count) {
398 if (StateValuesRequireUpdate(state_values, values, count)) { 448 if (StateValuesRequireUpdate(state_values, offset, count)) {
399 const Operator* op = common()->StateValues(count); 449 const Operator* op = common()->StateValues(count);
400 (*state_values) = graph()->NewNode(op, count, values); 450 (*state_values) = graph()->NewNode(op, count, &values()->at(offset));
401 } 451 }
402 } 452 }
403 453
404 void BytecodeGraphBuilder::Environment::UpdateStateValuesWithCache(
405 Node** state_values, Node** values, int count) {
406 *state_values = builder_->state_values_cache_.GetNodeForValues(
407 values, static_cast<size_t>(count));
408 }
409
410 Node* BytecodeGraphBuilder::Environment::Checkpoint( 454 Node* BytecodeGraphBuilder::Environment::Checkpoint(
411 BailoutId bailout_id, OutputFrameStateCombine combine, 455 BailoutId bailout_id, OutputFrameStateCombine combine,
412 bool owner_has_exception, const BitVector* liveness) { 456 bool owner_has_exception) {
413 UpdateStateValues(&parameters_state_values_, &values()->at(0), 457 UpdateStateValues(&parameters_state_values_, 0, parameter_count());
414 parameter_count()); 458 UpdateStateValues(&registers_state_values_, register_base(),
415 459 register_count());
416 if (liveness) { 460 UpdateStateValues(&accumulator_state_values_, accumulator_base(), 1);
417 Node* optimized_out = builder()->jsgraph()->OptimizedOutConstant();
418
419 for (int i = 0; i < register_count(); ++i) {
420 state_value_working_area_[i] = liveness->Contains(i)
421 ? values()->at(register_base() + i)
422 : optimized_out;
423 }
424
425 Node* accumulator_value = liveness->Contains(register_count())
426 ? values()->at(accumulator_base())
427 : optimized_out;
428
429 UpdateStateValuesWithCache(&registers_state_values_,
430 state_value_working_area_.data(),
431 register_count());
432
433 UpdateStateValues(&accumulator_state_values_, &accumulator_value, 1);
434 } else {
435 UpdateStateValuesWithCache(&registers_state_values_,
436 &values()->at(register_base()),
437 register_count());
438 UpdateStateValues(&accumulator_state_values_,
439 &values()->at(accumulator_base()), 1);
440 }
441 461
442 const Operator* op = common()->FrameState( 462 const Operator* op = common()->FrameState(
443 bailout_id, combine, builder()->frame_state_function_info()); 463 bailout_id, combine, builder()->frame_state_function_info());
444 Node* result = graph()->NewNode( 464 Node* result = graph()->NewNode(
445 op, parameters_state_values_, registers_state_values_, 465 op, parameters_state_values_, registers_state_values_,
446 accumulator_state_values_, Context(), builder()->GetFunctionClosure(), 466 accumulator_state_values_, Context(), builder()->GetFunctionClosure(),
447 builder()->graph()->start()); 467 builder()->graph()->start());
448 468
469 if (liveness_block() != nullptr) {
470 // If the owning node has an exception, register the checkpoint to the
471 // predecessor so that the checkpoint is used for both the normal and the
472 // exceptional paths. Yes, this is a terrible hack and we might want
473 // to use an explicit frame state for the exceptional path.
474 if (owner_has_exception) {
475 liveness_block()->GetPredecessor()->Checkpoint(result);
476 } else {
477 liveness_block()->Checkpoint(result);
478 }
479 }
480
449 return result; 481 return result;
450 } 482 }
451 483
452 BytecodeGraphBuilder::BytecodeGraphBuilder( 484 BytecodeGraphBuilder::BytecodeGraphBuilder(
453 Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph, 485 Zone* local_zone, CompilationInfo* info, JSGraph* jsgraph,
454 float invocation_frequency, SourcePositionTable* source_positions, 486 float invocation_frequency, SourcePositionTable* source_positions,
455 int inlining_id) 487 int inlining_id)
456 : local_zone_(local_zone), 488 : local_zone_(local_zone),
457 jsgraph_(jsgraph), 489 jsgraph_(jsgraph),
458 invocation_frequency_(invocation_frequency), 490 invocation_frequency_(invocation_frequency),
459 bytecode_array_(handle(info->shared_info()->bytecode_array())), 491 bytecode_array_(handle(info->shared_info()->bytecode_array())),
460 exception_handler_table_( 492 exception_handler_table_(
461 handle(HandlerTable::cast(bytecode_array()->handler_table()))), 493 handle(HandlerTable::cast(bytecode_array()->handler_table()))),
462 feedback_vector_(handle(info->closure()->feedback_vector())), 494 feedback_vector_(handle(info->closure()->feedback_vector())),
463 frame_state_function_info_(common()->CreateFrameStateFunctionInfo( 495 frame_state_function_info_(common()->CreateFrameStateFunctionInfo(
464 FrameStateType::kInterpretedFunction, 496 FrameStateType::kInterpretedFunction,
465 bytecode_array()->parameter_count(), 497 bytecode_array()->parameter_count(),
466 bytecode_array()->register_count(), info->shared_info())), 498 bytecode_array()->register_count(), info->shared_info())),
467 osr_ast_id_(info->osr_ast_id()), 499 osr_ast_id_(info->osr_ast_id()),
468 merge_environments_(local_zone), 500 merge_environments_(local_zone),
469 exception_handlers_(local_zone), 501 exception_handlers_(local_zone),
470 current_exception_handler_(0), 502 current_exception_handler_(0),
471 input_buffer_size_(0), 503 input_buffer_size_(0),
472 input_buffer_(nullptr), 504 input_buffer_(nullptr),
473 exit_controls_(local_zone), 505 exit_controls_(local_zone),
474 is_liveness_analysis_enabled_(FLAG_analyze_environment_liveness), 506 is_liveness_analysis_enabled_(FLAG_analyze_environment_liveness),
475 state_values_cache_(jsgraph), 507 state_values_cache_(jsgraph),
508 liveness_analyzer_(
509 static_cast<size_t>(bytecode_array()->register_count()), true,
510 local_zone),
476 source_positions_(source_positions), 511 source_positions_(source_positions),
477 start_position_(info->shared_info()->start_position(), inlining_id) { 512 start_position_(info->shared_info()->start_position(), inlining_id) {
478 // Bytecode graph builder assumes deoptimziation is enabled. 513 // Bytecode graph builder assumes deoptimziation is enabled.
479 DCHECK(info->is_deoptimization_enabled()); 514 DCHECK(info->is_deoptimization_enabled());
480 } 515 }
481 516
482 Node* BytecodeGraphBuilder::GetNewTarget() { 517 Node* BytecodeGraphBuilder::GetNewTarget() {
483 if (!new_target_.is_set()) { 518 if (!new_target_.is_set()) {
484 int params = bytecode_array()->parameter_count(); 519 int params = bytecode_array()->parameter_count();
485 int index = Linkage::GetJSCallNewTargetParamIndex(params); 520 int index = Linkage::GetJSCallNewTargetParamIndex(params);
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
546 581
547 VisitBytecodes(stack_check); 582 VisitBytecodes(stack_check);
548 583
549 // Finish the basic structure of the graph. 584 // Finish the basic structure of the graph.
550 DCHECK_NE(0u, exit_controls_.size()); 585 DCHECK_NE(0u, exit_controls_.size());
551 int const input_count = static_cast<int>(exit_controls_.size()); 586 int const input_count = static_cast<int>(exit_controls_.size());
552 Node** const inputs = &exit_controls_.front(); 587 Node** const inputs = &exit_controls_.front();
553 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs); 588 Node* end = graph()->NewNode(common()->End(input_count), input_count, inputs);
554 graph()->SetEnd(end); 589 graph()->SetEnd(end);
555 590
591 ClearNonLiveSlotsInFrameStates();
592
556 return true; 593 return true;
557 } 594 }
558 595
559 void BytecodeGraphBuilder::PrepareEagerCheckpoint() { 596 void BytecodeGraphBuilder::PrepareEagerCheckpoint() {
560 if (environment()->GetEffectDependency()->opcode() != IrOpcode::kCheckpoint) { 597 if (environment()->GetEffectDependency()->opcode() != IrOpcode::kCheckpoint) {
561 // Create an explicit checkpoint node for before the operation. This only 598 // Create an explicit checkpoint node for before the operation. This only
562 // needs to happen if we aren't effect-dominated by a {Checkpoint} already. 599 // needs to happen if we aren't effect-dominated by a {Checkpoint} already.
563 Node* node = NewNode(common()->Checkpoint()); 600 Node* node = NewNode(common()->Checkpoint());
564 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 601 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
565 DCHECK_EQ(IrOpcode::kDead, 602 DCHECK_EQ(IrOpcode::kDead,
566 NodeProperties::GetFrameStateInput(node)->opcode()); 603 NodeProperties::GetFrameStateInput(node)->opcode());
567 BailoutId bailout_id(bytecode_iterator().current_offset()); 604 BailoutId bailout_id(bytecode_iterator().current_offset());
568
569 const BitVector* liveness_before = bytecode_analysis()->GetInLivenessFor(
570 bytecode_iterator().current_offset());
571
572 Node* frame_state_before = environment()->Checkpoint( 605 Node* frame_state_before = environment()->Checkpoint(
573 bailout_id, OutputFrameStateCombine::Ignore(), false, liveness_before); 606 bailout_id, OutputFrameStateCombine::Ignore(), false);
574 NodeProperties::ReplaceFrameStateInput(node, frame_state_before); 607 NodeProperties::ReplaceFrameStateInput(node, frame_state_before);
575 } 608 }
576 } 609 }
577 610
578 void BytecodeGraphBuilder::PrepareFrameState(Node* node, 611 void BytecodeGraphBuilder::PrepareFrameState(Node* node,
579 OutputFrameStateCombine combine) { 612 OutputFrameStateCombine combine) {
580 if (OperatorProperties::HasFrameStateInput(node->op())) { 613 if (OperatorProperties::HasFrameStateInput(node->op())) {
581 // Add the frame state for after the operation. The node in question has 614 // Add the frame state for after the operation. The node in question has
582 // already been created and had a {Dead} frame state input up until now. 615 // already been created and had a {Dead} frame state input up until now.
583 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op())); 616 DCHECK_EQ(1, OperatorProperties::GetFrameStateInputCount(node->op()));
584 DCHECK_EQ(IrOpcode::kDead, 617 DCHECK_EQ(IrOpcode::kDead,
585 NodeProperties::GetFrameStateInput(node)->opcode()); 618 NodeProperties::GetFrameStateInput(node)->opcode());
586 BailoutId bailout_id(bytecode_iterator().current_offset()); 619 BailoutId bailout_id(bytecode_iterator().current_offset());
587 bool has_exception = NodeProperties::IsExceptionalCall(node); 620 bool has_exception = NodeProperties::IsExceptionalCall(node);
588 621 Node* frame_state_after =
589 const BitVector* liveness_after = bytecode_analysis()->GetOutLivenessFor( 622 environment()->Checkpoint(bailout_id, combine, has_exception);
590 bytecode_iterator().current_offset());
591
592 Node* frame_state_after = environment()->Checkpoint(
593 bailout_id, combine, has_exception, liveness_after);
594 NodeProperties::ReplaceFrameStateInput(node, frame_state_after); 623 NodeProperties::ReplaceFrameStateInput(node, frame_state_after);
595 } 624 }
596 } 625 }
597 626
627 void BytecodeGraphBuilder::ClearNonLiveSlotsInFrameStates() {
628 if (!IsLivenessAnalysisEnabled()) {
629 return;
630 }
631 NonLiveFrameStateSlotReplacer replacer(
632 &state_values_cache_, jsgraph()->OptimizedOutConstant(),
633 liveness_analyzer()->local_count(), true, local_zone());
634 liveness_analyzer()->Run(&replacer);
635 if (FLAG_trace_environment_liveness) {
636 OFStream os(stdout);
637 liveness_analyzer()->Print(os);
638 }
639 }
640
598 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) { 641 void BytecodeGraphBuilder::VisitBytecodes(bool stack_check) {
599 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone(), 642 BytecodeAnalysis bytecode_analysis(bytecode_array(), local_zone());
600 FLAG_analyze_environment_liveness);
601 bytecode_analysis.Analyze(); 643 bytecode_analysis.Analyze();
602 set_bytecode_analysis(&bytecode_analysis); 644 set_bytecode_analysis(&bytecode_analysis);
603 645
604 interpreter::BytecodeArrayIterator iterator(bytecode_array()); 646 interpreter::BytecodeArrayIterator iterator(bytecode_array());
605 set_bytecode_iterator(&iterator); 647 set_bytecode_iterator(&iterator);
606 SourcePositionTableIterator source_position_iterator( 648 SourcePositionTableIterator source_position_iterator(
607 bytecode_array()->source_position_table()); 649 bytecode_array()->source_position_table());
608 650
609 if (FLAG_trace_environment_liveness) {
610 OFStream of(stdout);
611
612 bytecode_analysis.PrintLivenessTo(of);
613 }
614
615 BuildOSRNormalEntryPoint(); 651 BuildOSRNormalEntryPoint();
616
617 for (; !iterator.done(); iterator.Advance()) { 652 for (; !iterator.done(); iterator.Advance()) {
618 int current_offset = iterator.current_offset(); 653 int current_offset = iterator.current_offset();
619 UpdateCurrentSourcePosition(&source_position_iterator, current_offset); 654 UpdateCurrentSourcePosition(&source_position_iterator, current_offset);
620 EnterAndExitExceptionHandlers(current_offset); 655 EnterAndExitExceptionHandlers(current_offset);
621 SwitchToMergeEnvironment(current_offset); 656 SwitchToMergeEnvironment(current_offset);
622 if (environment() != nullptr) { 657 if (environment() != nullptr) {
623 BuildLoopHeaderEnvironment(current_offset); 658 BuildLoopHeaderEnvironment(current_offset);
624 BuildOSRLoopEntryPoint(current_offset); 659 BuildOSRLoopEntryPoint(current_offset);
625 660
626 // Skip the first stack check if stack_check is false 661 // Skip the first stack check if stack_check is false
(...skipping 1100 matching lines...) Expand 10 before | Expand all | Expand 10 after
1727 Node* control = 1762 Node* control =
1728 NewNode(common()->Return(), pop_node, environment()->LookupAccumulator()); 1763 NewNode(common()->Return(), pop_node, environment()->LookupAccumulator());
1729 MergeControlToLeaveFunction(control); 1764 MergeControlToLeaveFunction(control);
1730 } 1765 }
1731 1766
1732 void BytecodeGraphBuilder::VisitDebugger() { 1767 void BytecodeGraphBuilder::VisitDebugger() {
1733 PrepareEagerCheckpoint(); 1768 PrepareEagerCheckpoint();
1734 Node* call = 1769 Node* call =
1735 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement)); 1770 NewNode(javascript()->CallRuntime(Runtime::kHandleDebuggerStatement));
1736 environment()->BindAccumulator(call, Environment::kAttachFrameState); 1771 environment()->BindAccumulator(call, Environment::kAttachFrameState);
1772 environment()->MarkAllRegistersLive();
1737 } 1773 }
1738 1774
1739 // We cannot create a graph from the debugger copy of the bytecode array. 1775 // We cannot create a graph from the debugger copy of the bytecode array.
1740 #define DEBUG_BREAK(Name, ...) \ 1776 #define DEBUG_BREAK(Name, ...) \
1741 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); } 1777 void BytecodeGraphBuilder::Visit##Name() { UNREACHABLE(); }
1742 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK); 1778 DEBUG_BREAK_BYTECODE_LIST(DEBUG_BREAK);
1743 #undef DEBUG_BREAK 1779 #undef DEBUG_BREAK
1744 1780
1745 void BytecodeGraphBuilder::BuildForInPrepare() { 1781 void BytecodeGraphBuilder::BuildForInPrepare() {
1746 PrepareEagerCheckpoint(); 1782 PrepareEagerCheckpoint();
(...skipping 445 matching lines...) Expand 10 before | Expand all | Expand 10 after
2192 it->source_position().ScriptOffset(), start_position_.InliningId())); 2228 it->source_position().ScriptOffset(), start_position_.InliningId()));
2193 it->Advance(); 2229 it->Advance();
2194 } else { 2230 } else {
2195 DCHECK_GT(it->code_offset(), offset); 2231 DCHECK_GT(it->code_offset(), offset);
2196 } 2232 }
2197 } 2233 }
2198 2234
2199 } // namespace compiler 2235 } // namespace compiler
2200 } // namespace internal 2236 } // namespace internal
2201 } // namespace v8 2237 } // namespace v8
OLDNEW
« no previous file with comments | « src/compiler/bytecode-graph-builder.h ('k') | src/compiler/bytecode-liveness-map.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698