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

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

Issue 2140673007: [turbofan] Introduce explicit loop exits markers. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix Created 4 years, 5 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
OLDNEW
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/ast-graph-builder.h" 5 #include "src/compiler/ast-graph-builder.h"
6 6
7 #include "src/ast/scopes.h" 7 #include "src/ast/scopes.h"
8 #include "src/compiler.h" 8 #include "src/compiler.h"
9 #include "src/compiler/ast-loop-assignment-analyzer.h" 9 #include "src/compiler/ast-loop-assignment-analyzer.h"
10 #include "src/compiler/control-builders.h" 10 #include "src/compiler/control-builders.h"
(...skipping 160 matching lines...) Expand 10 before | Expand all | Expand 10 after
171 enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW }; 171 enum Command { CMD_BREAK, CMD_CONTINUE, CMD_RETURN, CMD_THROW };
172 172
173 // Performs one of the above commands on this stack of control scopes. This 173 // Performs one of the above commands on this stack of control scopes. This
174 // walks through the stack giving each scope a chance to execute or defer the 174 // walks through the stack giving each scope a chance to execute or defer the
175 // given command by overriding the {Execute} method appropriately. Note that 175 // given command by overriding the {Execute} method appropriately. Note that
176 // this also drops extra operands from the environment for each skipped scope. 176 // this also drops extra operands from the environment for each skipped scope.
177 void PerformCommand(Command cmd, Statement* target, Node* value); 177 void PerformCommand(Command cmd, Statement* target, Node* value);
178 178
179 // Interface to execute a given command in this scope. Returning {true} here 179 // Interface to execute a given command in this scope. Returning {true} here
180 // indicates successful execution whereas {false} requests to skip scope. 180 // indicates successful execution whereas {false} requests to skip scope.
181 virtual bool Execute(Command cmd, Statement* target, Node* value) { 181 virtual bool Execute(Command cmd, Statement* target, Node** value) {
182 // For function-level control. 182 // For function-level control.
183 switch (cmd) { 183 switch (cmd) {
184 case CMD_THROW: 184 case CMD_THROW:
185 builder()->BuildThrow(value); 185 builder()->BuildThrow(*value);
186 return true; 186 return true;
187 case CMD_RETURN: 187 case CMD_RETURN:
188 builder()->BuildReturn(value); 188 builder()->BuildReturn(*value);
189 return true; 189 return true;
190 case CMD_BREAK: 190 case CMD_BREAK:
191 case CMD_CONTINUE: 191 case CMD_CONTINUE:
192 break; 192 break;
193 } 193 }
194 return false; 194 return false;
195 } 195 }
196 196
197 Environment* environment() { return builder_->environment(); } 197 Environment* environment() { return builder_->environment(); }
198 AstGraphBuilder* builder() const { return builder_; } 198 AstGraphBuilder* builder() const { return builder_; }
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 296
297 297
298 // Control scope implementation for a BreakableStatement. 298 // Control scope implementation for a BreakableStatement.
299 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope { 299 class AstGraphBuilder::ControlScopeForBreakable : public ControlScope {
300 public: 300 public:
301 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target, 301 ControlScopeForBreakable(AstGraphBuilder* owner, BreakableStatement* target,
302 ControlBuilder* control) 302 ControlBuilder* control)
303 : ControlScope(owner), target_(target), control_(control) {} 303 : ControlScope(owner), target_(target), control_(control) {}
304 304
305 protected: 305 protected:
306 bool Execute(Command cmd, Statement* target, Node* value) override { 306 bool Execute(Command cmd, Statement* target, Node** value) override {
307 if (target != target_) return false; // We are not the command target. 307 if (target != target_) return false; // We are not the command target.
308 switch (cmd) { 308 switch (cmd) {
309 case CMD_BREAK: 309 case CMD_BREAK:
310 control_->Break(); 310 control_->Break();
311 return true; 311 return true;
312 case CMD_CONTINUE: 312 case CMD_CONTINUE:
313 case CMD_THROW: 313 case CMD_THROW:
314 case CMD_RETURN: 314 case CMD_RETURN:
315 break; 315 break;
316 } 316 }
317 return false; 317 return false;
318 } 318 }
319 319
320 private: 320 private:
321 BreakableStatement* target_; 321 BreakableStatement* target_;
322 ControlBuilder* control_; 322 ControlBuilder* control_;
323 }; 323 };
324 324
325 325
326 // Control scope implementation for an IterationStatement. 326 // Control scope implementation for an IterationStatement.
327 class AstGraphBuilder::ControlScopeForIteration : public ControlScope { 327 class AstGraphBuilder::ControlScopeForIteration : public ControlScope {
328 public: 328 public:
329 ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target, 329 ControlScopeForIteration(AstGraphBuilder* owner, IterationStatement* target,
330 LoopBuilder* control) 330 LoopBuilder* control)
331 : ControlScope(owner), target_(target), control_(control) {} 331 : ControlScope(owner), target_(target), control_(control) {}
332 332
333 protected: 333 protected:
334 bool Execute(Command cmd, Statement* target, Node* value) override { 334 bool Execute(Command cmd, Statement* target, Node** value) override {
335 if (target != target_) return false; // We are not the command target. 335 if (target != target_) {
336 control_->ExitLoop(value);
337 return false;
338 }
336 switch (cmd) { 339 switch (cmd) {
337 case CMD_BREAK: 340 case CMD_BREAK:
338 control_->Break(); 341 control_->Break();
339 return true; 342 return true;
340 case CMD_CONTINUE: 343 case CMD_CONTINUE:
341 control_->Continue(); 344 control_->Continue();
342 return true; 345 return true;
343 case CMD_THROW: 346 case CMD_THROW:
344 case CMD_RETURN: 347 case CMD_RETURN:
345 break; 348 break;
(...skipping 17 matching lines...) Expand all
363 outer_prediction_(owner->try_catch_prediction_) { 366 outer_prediction_(owner->try_catch_prediction_) {
364 builder()->try_nesting_level_++; // Increment nesting. 367 builder()->try_nesting_level_++; // Increment nesting.
365 builder()->try_catch_prediction_ = stmt->catch_predicted(); 368 builder()->try_catch_prediction_ = stmt->catch_predicted();
366 } 369 }
367 ~ControlScopeForCatch() { 370 ~ControlScopeForCatch() {
368 builder()->try_nesting_level_--; // Decrement nesting. 371 builder()->try_nesting_level_--; // Decrement nesting.
369 builder()->try_catch_prediction_ = outer_prediction_; 372 builder()->try_catch_prediction_ = outer_prediction_;
370 } 373 }
371 374
372 protected: 375 protected:
373 bool Execute(Command cmd, Statement* target, Node* value) override { 376 bool Execute(Command cmd, Statement* target, Node** value) override {
374 switch (cmd) { 377 switch (cmd) {
375 case CMD_THROW: 378 case CMD_THROW:
376 control_->Throw(value); 379 control_->Throw(*value);
377 return true; 380 return true;
378 case CMD_BREAK: 381 case CMD_BREAK:
379 case CMD_CONTINUE: 382 case CMD_CONTINUE:
380 case CMD_RETURN: 383 case CMD_RETURN:
381 break; 384 break;
382 } 385 }
383 return false; 386 return false;
384 } 387 }
385 388
386 private: 389 private:
(...skipping 13 matching lines...) Expand all
400 outer_prediction_(owner->try_catch_prediction_) { 403 outer_prediction_(owner->try_catch_prediction_) {
401 builder()->try_nesting_level_++; // Increment nesting. 404 builder()->try_nesting_level_++; // Increment nesting.
402 builder()->try_catch_prediction_ = stmt->catch_predicted(); 405 builder()->try_catch_prediction_ = stmt->catch_predicted();
403 } 406 }
404 ~ControlScopeForFinally() { 407 ~ControlScopeForFinally() {
405 builder()->try_nesting_level_--; // Decrement nesting. 408 builder()->try_nesting_level_--; // Decrement nesting.
406 builder()->try_catch_prediction_ = outer_prediction_; 409 builder()->try_catch_prediction_ = outer_prediction_;
407 } 410 }
408 411
409 protected: 412 protected:
410 bool Execute(Command cmd, Statement* target, Node* value) override { 413 bool Execute(Command cmd, Statement* target, Node** value) override {
411 Node* token = commands_->RecordCommand(cmd, target, value); 414 Node* token = commands_->RecordCommand(cmd, target, *value);
412 control_->LeaveTry(token, value); 415 control_->LeaveTry(token, *value);
413 return true; 416 return true;
414 } 417 }
415 418
416 private: 419 private:
417 DeferredCommands* commands_; 420 DeferredCommands* commands_;
418 TryFinallyBuilder* control_; 421 TryFinallyBuilder* control_;
419 bool outer_prediction_; 422 bool outer_prediction_;
420 }; 423 };
421 424
422 425
(...skipping 505 matching lines...) Expand 10 before | Expand all | Expand 10 after
928 // to use an explicit frame state for the exceptional path. 931 // to use an explicit frame state for the exceptional path.
929 if (owner_has_exception) { 932 if (owner_has_exception) {
930 liveness_block()->GetPredecessor()->Checkpoint(result); 933 liveness_block()->GetPredecessor()->Checkpoint(result);
931 } else { 934 } else {
932 liveness_block()->Checkpoint(result); 935 liveness_block()->Checkpoint(result);
933 } 936 }
934 } 937 }
935 return result; 938 return result;
936 } 939 }
937 940
941 void AstGraphBuilder::Environment::PrepareForLoopExit(
942 Node* loop, BitVector* assigned_variables) {
943 if (IsMarkedAsUnreachable()) return;
944
945 DCHECK_EQ(loop->opcode(), IrOpcode::kLoop);
946
947 Node* control = GetControlDependency();
948
949 // Create the loop exit node.
950 Node* loop_exit = graph()->NewNode(common()->LoopExit(), control, loop);
951 UpdateControlDependency(loop_exit);
952
953 // Rename the environmnent values.
954 for (size_t i = 0; i < values()->size(); i++) {
955 if (assigned_variables == nullptr ||
956 static_cast<int>(i) >= assigned_variables->length() ||
957 assigned_variables->Contains(static_cast<int>(i))) {
958 Node* rename = graph()->NewNode(common()->LoopExitValue(), (*values())[i],
959 loop_exit);
960 (*values())[i] = rename;
Michael Starzinger 2016/07/14 13:09:40 nit: Why not just "values_[i] = rename"?
961 }
962 }
963
964 // Rename the effect.
965 Node* effect_rename = graph()->NewNode(common()->LoopExitEffect(),
966 GetEffectDependency(), loop_exit);
967 UpdateEffectDependency(effect_rename);
968 }
938 969
939 bool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() { 970 bool AstGraphBuilder::Environment::IsLivenessAnalysisEnabled() {
940 return FLAG_analyze_environment_liveness && 971 return FLAG_analyze_environment_liveness &&
941 builder()->info()->is_deoptimization_enabled(); 972 builder()->info()->is_deoptimization_enabled();
942 } 973 }
943 974
944 975
945 bool AstGraphBuilder::Environment::IsLivenessBlockConsistent() { 976 bool AstGraphBuilder::Environment::IsLivenessBlockConsistent() {
946 return (!IsLivenessAnalysisEnabled() || IsMarkedAsUnreachable()) == 977 return (!IsLivenessAnalysisEnabled() || IsMarkedAsUnreachable()) ==
947 (liveness_block() == nullptr); 978 (liveness_block() == nullptr);
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 1051
1021 1052
1022 void AstGraphBuilder::ControlScope::PerformCommand(Command command, 1053 void AstGraphBuilder::ControlScope::PerformCommand(Command command,
1023 Statement* target, 1054 Statement* target,
1024 Node* value) { 1055 Node* value) {
1025 Environment* env = environment()->CopyAsUnreachable(); 1056 Environment* env = environment()->CopyAsUnreachable();
1026 ControlScope* current = this; 1057 ControlScope* current = this;
1027 while (current != nullptr) { 1058 while (current != nullptr) {
1028 environment()->TrimStack(current->stack_height()); 1059 environment()->TrimStack(current->stack_height());
1029 environment()->TrimContextChain(current->context_length()); 1060 environment()->TrimContextChain(current->context_length());
1030 if (current->Execute(command, target, value)) break; 1061 if (current->Execute(command, target, &value)) break;
1031 current = current->outer_; 1062 current = current->outer_;
1032 } 1063 }
1033 builder()->set_environment(env); 1064 builder()->set_environment(env);
1034 DCHECK_NOT_NULL(current); // Always handled (unless stack is malformed). 1065 DCHECK_NOT_NULL(current); // Always handled (unless stack is malformed).
1035 } 1066 }
1036 1067
1037 1068
1038 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) { 1069 void AstGraphBuilder::ControlScope::BreakTo(BreakableStatement* stmt) {
1039 PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant()); 1070 PerformCommand(CMD_BREAK, stmt, builder()->jsgraph()->TheHoleConstant());
1040 } 1071 }
(...skipping 3345 matching lines...) Expand 10 before | Expand all | Expand 10 after
4386 // Phi does not exist yet, introduce one. 4417 // Phi does not exist yet, introduce one.
4387 value = NewPhi(inputs, value, control); 4418 value = NewPhi(inputs, value, control);
4388 value->ReplaceInput(inputs - 1, other); 4419 value->ReplaceInput(inputs - 1, other);
4389 } 4420 }
4390 return value; 4421 return value;
4391 } 4422 }
4392 4423
4393 } // namespace compiler 4424 } // namespace compiler
4394 } // namespace internal 4425 } // namespace internal
4395 } // namespace v8 4426 } // namespace v8
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698