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/ast-graph-builder.h" | 5 #include "src/compiler/ast-graph-builder.h" |
6 | 6 |
7 #include "src/compiler.h" | 7 #include "src/compiler.h" |
8 #include "src/compiler/ast-loop-assignment-analyzer.h" | 8 #include "src/compiler/ast-loop-assignment-analyzer.h" |
9 #include "src/compiler/control-builders.h" | 9 #include "src/compiler/control-builders.h" |
10 #include "src/compiler/linkage.h" | 10 #include "src/compiler/linkage.h" |
| 11 #include "src/compiler/liveness-analyzer.h" |
11 #include "src/compiler/machine-operator.h" | 12 #include "src/compiler/machine-operator.h" |
12 #include "src/compiler/node-matchers.h" | 13 #include "src/compiler/node-matchers.h" |
13 #include "src/compiler/node-properties.h" | 14 #include "src/compiler/node-properties.h" |
14 #include "src/compiler/operator-properties.h" | 15 #include "src/compiler/operator-properties.h" |
15 #include "src/compiler/state-values-utils.h" | 16 #include "src/compiler/state-values-utils.h" |
16 #include "src/full-codegen.h" | 17 #include "src/full-codegen.h" |
17 #include "src/parser.h" | 18 #include "src/parser.h" |
18 #include "src/scopes.h" | 19 #include "src/scopes.h" |
19 | 20 |
20 namespace v8 { | 21 namespace v8 { |
(...skipping 366 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
387 environment_(nullptr), | 388 environment_(nullptr), |
388 ast_context_(nullptr), | 389 ast_context_(nullptr), |
389 globals_(0, local_zone), | 390 globals_(0, local_zone), |
390 execution_control_(nullptr), | 391 execution_control_(nullptr), |
391 execution_context_(nullptr), | 392 execution_context_(nullptr), |
392 try_nesting_level_(0), | 393 try_nesting_level_(0), |
393 input_buffer_size_(0), | 394 input_buffer_size_(0), |
394 input_buffer_(nullptr), | 395 input_buffer_(nullptr), |
395 exit_control_(nullptr), | 396 exit_control_(nullptr), |
396 loop_assignment_analysis_(loop), | 397 loop_assignment_analysis_(loop), |
397 state_values_cache_(jsgraph) { | 398 state_values_cache_(jsgraph), |
| 399 liveness_analyzer_(new (local_zone) LivenessAnalyzer( |
| 400 static_cast<size_t>(info->scope()->num_stack_slots()), local_zone)) { |
398 InitializeAstVisitor(info->isolate(), local_zone); | 401 InitializeAstVisitor(info->isolate(), local_zone); |
399 } | 402 } |
400 | 403 |
401 | 404 |
402 Node* AstGraphBuilder::GetFunctionClosure() { | 405 Node* AstGraphBuilder::GetFunctionClosure() { |
403 if (!function_closure_.is_set()) { | 406 if (!function_closure_.is_set()) { |
404 const Operator* op = | 407 const Operator* op = |
405 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); | 408 common()->Parameter(Linkage::kJSFunctionCallClosureParamIndex); |
406 Node* node = NewNode(op, graph()->start()); | 409 Node* node = NewNode(op, graph()->start()); |
407 function_closure_.set(node); | 410 function_closure_.set(node); |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
473 ContextScope top_context(this, scope, inner_context); | 476 ContextScope top_context(this, scope, inner_context); |
474 CreateGraphBody(stack_check); | 477 CreateGraphBody(stack_check); |
475 } else { | 478 } else { |
476 // Simply use the outer function context in building the graph. | 479 // Simply use the outer function context in building the graph. |
477 CreateGraphBody(stack_check); | 480 CreateGraphBody(stack_check); |
478 } | 481 } |
479 | 482 |
480 // Finish the basic structure of the graph. | 483 // Finish the basic structure of the graph. |
481 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); | 484 graph()->SetEnd(graph()->NewNode(common()->End(), exit_control())); |
482 | 485 |
| 486 // Compute local variable liveness information and use it to relax |
| 487 // frame states. |
| 488 ClearNonLiveSlotsInFrameStates(); |
| 489 |
483 // Failures indicated by stack overflow. | 490 // Failures indicated by stack overflow. |
484 return !HasStackOverflow(); | 491 return !HasStackOverflow(); |
485 } | 492 } |
486 | 493 |
487 | 494 |
488 void AstGraphBuilder::CreateGraphBody(bool stack_check) { | 495 void AstGraphBuilder::CreateGraphBody(bool stack_check) { |
489 Scope* scope = info()->scope(); | 496 Scope* scope = info()->scope(); |
490 | 497 |
491 // Build the arguments object if it is used. | 498 // Build the arguments object if it is used. |
492 BuildArgumentsObject(scope->arguments()); | 499 BuildArgumentsObject(scope->arguments()); |
(...skipping 30 matching lines...) Expand all Loading... |
523 // TODO(mstarzinger): Only traces implicit return. | 530 // TODO(mstarzinger): Only traces implicit return. |
524 Node* return_value = jsgraph()->UndefinedConstant(); | 531 Node* return_value = jsgraph()->UndefinedConstant(); |
525 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); | 532 NewNode(javascript()->CallRuntime(Runtime::kTraceExit, 1), return_value); |
526 } | 533 } |
527 | 534 |
528 // Return 'undefined' in case we can fall off the end. | 535 // Return 'undefined' in case we can fall off the end. |
529 BuildReturn(jsgraph()->UndefinedConstant()); | 536 BuildReturn(jsgraph()->UndefinedConstant()); |
530 } | 537 } |
531 | 538 |
532 | 539 |
| 540 void AstGraphBuilder::ClearNonLiveSlotsInFrameStates() { |
| 541 if (!FLAG_analyze_environment_liveness) return; |
| 542 |
| 543 NonLiveFrameStateSlotReplacer replacer( |
| 544 &state_values_cache_, jsgraph()->UndefinedConstant(), |
| 545 liveness_analyzer()->local_count(), local_zone()); |
| 546 Variable* arguments = info()->scope()->arguments(); |
| 547 if (arguments != nullptr && arguments->IsStackAllocated()) { |
| 548 replacer.MarkPermanentlyLive(arguments->index()); |
| 549 } |
| 550 liveness_analyzer()->Run(&replacer); |
| 551 if (FLAG_trace_environment_liveness) { |
| 552 OFStream os(stdout); |
| 553 liveness_analyzer()->Print(os); |
| 554 } |
| 555 } |
| 556 |
| 557 |
533 // Left-hand side can only be a property, a global or a variable slot. | 558 // Left-hand side can only be a property, a global or a variable slot. |
534 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; | 559 enum LhsKind { VARIABLE, NAMED_PROPERTY, KEYED_PROPERTY }; |
535 | 560 |
536 | 561 |
537 // Determine the left-hand side kind of an assignment. | 562 // Determine the left-hand side kind of an assignment. |
538 static LhsKind DetermineLhsKind(Expression* expr) { | 563 static LhsKind DetermineLhsKind(Expression* expr) { |
539 Property* property = expr->AsProperty(); | 564 Property* property = expr->AsProperty(); |
540 DCHECK(expr->IsValidReferenceExpression()); | 565 DCHECK(expr->IsValidReferenceExpression()); |
541 LhsKind lhs_kind = | 566 LhsKind lhs_kind = |
542 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) | 567 (property == NULL) ? VARIABLE : (property->key()->IsPropertyName()) |
543 ? NAMED_PROPERTY | 568 ? NAMED_PROPERTY |
544 : KEYED_PROPERTY; | 569 : KEYED_PROPERTY; |
545 return lhs_kind; | 570 return lhs_kind; |
546 } | 571 } |
547 | 572 |
548 | 573 |
549 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, | 574 AstGraphBuilder::Environment::Environment(AstGraphBuilder* builder, |
550 Scope* scope, | 575 Scope* scope, |
551 Node* control_dependency) | 576 Node* control_dependency) |
552 : builder_(builder), | 577 : builder_(builder), |
553 parameters_count_(scope->num_parameters() + 1), | 578 parameters_count_(scope->num_parameters() + 1), |
554 locals_count_(scope->num_stack_slots()), | 579 locals_count_(scope->num_stack_slots()), |
| 580 liveness_block_(builder_->liveness_analyzer()->New()), |
555 values_(builder_->local_zone()), | 581 values_(builder_->local_zone()), |
556 contexts_(builder_->local_zone()), | 582 contexts_(builder_->local_zone()), |
557 control_dependency_(control_dependency), | 583 control_dependency_(control_dependency), |
558 effect_dependency_(control_dependency), | 584 effect_dependency_(control_dependency), |
559 parameters_node_(nullptr), | 585 parameters_node_(nullptr), |
560 locals_node_(nullptr), | 586 locals_node_(nullptr), |
561 stack_node_(nullptr) { | 587 stack_node_(nullptr) { |
562 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); | 588 DCHECK_EQ(scope->num_parameters() + 1, parameters_count()); |
563 | 589 |
564 // Bind the receiver variable. | 590 // Bind the receiver variable. |
565 Node* receiver = builder->graph()->NewNode(common()->Parameter(0), | 591 Node* receiver = builder->graph()->NewNode(common()->Parameter(0), |
566 builder->graph()->start()); | 592 builder->graph()->start()); |
567 values()->push_back(receiver); | 593 values()->push_back(receiver); |
568 | 594 |
569 // Bind all parameter variables. The parameter indices are shifted by 1 | 595 // Bind all parameter variables. The parameter indices are shifted by 1 |
570 // (receiver is parameter index -1 but environment index 0). | 596 // (receiver is parameter index -1 but environment index 0). |
571 for (int i = 0; i < scope->num_parameters(); ++i) { | 597 for (int i = 0; i < scope->num_parameters(); ++i) { |
572 Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1), | 598 Node* parameter = builder->graph()->NewNode(common()->Parameter(i + 1), |
573 builder->graph()->start()); | 599 builder->graph()->start()); |
574 values()->push_back(parameter); | 600 values()->push_back(parameter); |
575 } | 601 } |
576 | 602 |
577 // Bind all local variables to undefined. | 603 // Bind all local variables to undefined. |
578 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); | 604 Node* undefined_constant = builder->jsgraph()->UndefinedConstant(); |
579 values()->insert(values()->end(), locals_count(), undefined_constant); | 605 values()->insert(values()->end(), locals_count(), undefined_constant); |
580 } | 606 } |
581 | 607 |
582 | 608 |
583 AstGraphBuilder::Environment::Environment( | 609 AstGraphBuilder::Environment::Environment(AstGraphBuilder::Environment* copy) |
584 const AstGraphBuilder::Environment* copy) | |
585 : builder_(copy->builder_), | 610 : builder_(copy->builder_), |
586 parameters_count_(copy->parameters_count_), | 611 parameters_count_(copy->parameters_count_), |
587 locals_count_(copy->locals_count_), | 612 locals_count_(copy->locals_count_), |
588 values_(copy->zone()), | 613 values_(copy->zone()), |
589 contexts_(copy->zone()), | 614 contexts_(copy->zone()), |
590 control_dependency_(copy->control_dependency_), | 615 control_dependency_(copy->control_dependency_), |
591 effect_dependency_(copy->effect_dependency_), | 616 effect_dependency_(copy->effect_dependency_), |
592 parameters_node_(copy->parameters_node_), | 617 parameters_node_(copy->parameters_node_), |
593 locals_node_(copy->locals_node_), | 618 locals_node_(copy->locals_node_), |
594 stack_node_(copy->stack_node_) { | 619 stack_node_(copy->stack_node_) { |
595 const size_t kStackEstimate = 7; // optimum from experimentation! | 620 const size_t kStackEstimate = 7; // optimum from experimentation! |
596 values_.reserve(copy->values_.size() + kStackEstimate); | 621 values_.reserve(copy->values_.size() + kStackEstimate); |
597 values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end()); | 622 values_.insert(values_.begin(), copy->values_.begin(), copy->values_.end()); |
598 contexts_.reserve(copy->contexts_.size()); | 623 contexts_.reserve(copy->contexts_.size()); |
599 contexts_.insert(contexts_.begin(), copy->contexts_.begin(), | 624 contexts_.insert(contexts_.begin(), copy->contexts_.begin(), |
600 copy->contexts_.end()); | 625 copy->contexts_.end()); |
| 626 |
| 627 if (FLAG_analyze_environment_liveness) { |
| 628 // Split the liveness blocks. |
| 629 copy->liveness_block_ = |
| 630 builder_->liveness_analyzer()->New(copy->liveness_block()); |
| 631 liveness_block_ = |
| 632 builder_->liveness_analyzer()->New(copy->liveness_block()); |
| 633 } |
601 } | 634 } |
602 | 635 |
603 | 636 |
| 637 void AstGraphBuilder::Environment::Bind(Variable* variable, Node* node) { |
| 638 DCHECK(variable->IsStackAllocated()); |
| 639 if (variable->IsParameter()) { |
| 640 // The parameter indices are shifted by 1 (receiver is parameter |
| 641 // index -1 but environment index 0). |
| 642 values()->at(variable->index() + 1) = node; |
| 643 } else { |
| 644 DCHECK(variable->IsStackLocal()); |
| 645 values()->at(variable->index() + parameters_count_) = node; |
| 646 if (FLAG_analyze_environment_liveness) { |
| 647 liveness_block()->Bind(variable->index()); |
| 648 } |
| 649 } |
| 650 } |
| 651 |
| 652 |
| 653 Node* AstGraphBuilder::Environment::Lookup(Variable* variable) { |
| 654 DCHECK(variable->IsStackAllocated()); |
| 655 if (variable->IsParameter()) { |
| 656 // The parameter indices are shifted by 1 (receiver is parameter |
| 657 // index -1 but environment index 0). |
| 658 return values()->at(variable->index() + 1); |
| 659 } else { |
| 660 DCHECK(variable->IsStackLocal()); |
| 661 if (FLAG_analyze_environment_liveness) { |
| 662 liveness_block()->Lookup(variable->index()); |
| 663 } |
| 664 return values()->at(variable->index() + parameters_count_); |
| 665 } |
| 666 } |
| 667 |
| 668 |
| 669 void AstGraphBuilder::Environment::MarkAllLocalsLive() { |
| 670 if (FLAG_analyze_environment_liveness) { |
| 671 for (int i = 0; i < locals_count_; i++) { |
| 672 liveness_block()->Lookup(i); |
| 673 } |
| 674 } |
| 675 } |
| 676 |
| 677 |
| 678 AstGraphBuilder::Environment* |
| 679 AstGraphBuilder::Environment::CopyAndShareLiveness() { |
| 680 Environment* env = new (zone()) Environment(this); |
| 681 if (FLAG_analyze_environment_liveness) { |
| 682 env->liveness_block_ = liveness_block(); |
| 683 } |
| 684 return env; |
| 685 } |
| 686 |
| 687 |
604 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, | 688 void AstGraphBuilder::Environment::UpdateStateValues(Node** state_values, |
605 int offset, int count) { | 689 int offset, int count) { |
606 bool should_update = false; | 690 bool should_update = false; |
607 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); | 691 Node** env_values = (count == 0) ? nullptr : &values()->at(offset); |
608 if (*state_values == NULL || (*state_values)->InputCount() != count) { | 692 if (*state_values == NULL || (*state_values)->InputCount() != count) { |
609 should_update = true; | 693 should_update = true; |
610 } else { | 694 } else { |
611 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); | 695 DCHECK(static_cast<size_t>(offset + count) <= values()->size()); |
612 for (int i = 0; i < count; i++) { | 696 for (int i = 0; i < count; i++) { |
613 if ((*state_values)->InputAt(i) != env_values[i]) { | 697 if ((*state_values)->InputAt(i) != env_values[i]) { |
(...skipping 21 matching lines...) Expand all Loading... |
635 BailoutId ast_id, OutputFrameStateCombine combine) { | 719 BailoutId ast_id, OutputFrameStateCombine combine) { |
636 if (!FLAG_turbo_deoptimization) return nullptr; | 720 if (!FLAG_turbo_deoptimization) return nullptr; |
637 | 721 |
638 UpdateStateValues(¶meters_node_, 0, parameters_count()); | 722 UpdateStateValues(¶meters_node_, 0, parameters_count()); |
639 UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count()); | 723 UpdateStateValuesWithCache(&locals_node_, parameters_count(), locals_count()); |
640 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), | 724 UpdateStateValues(&stack_node_, parameters_count() + locals_count(), |
641 stack_height()); | 725 stack_height()); |
642 | 726 |
643 const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine); | 727 const Operator* op = common()->FrameState(JS_FRAME, ast_id, combine); |
644 | 728 |
645 return graph()->NewNode(op, parameters_node_, locals_node_, stack_node_, | 729 Node* result = graph()->NewNode(op, parameters_node_, locals_node_, |
646 builder()->current_context(), | 730 stack_node_, builder()->current_context(), |
647 builder()->jsgraph()->UndefinedConstant()); | 731 builder()->jsgraph()->UndefinedConstant()); |
| 732 if (FLAG_analyze_environment_liveness) { |
| 733 liveness_block()->Checkpoint(result); |
| 734 } |
| 735 return result; |
648 } | 736 } |
649 | 737 |
650 | 738 |
651 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, | 739 AstGraphBuilder::AstContext::AstContext(AstGraphBuilder* own, |
652 Expression::Context kind) | 740 Expression::Context kind) |
653 : kind_(kind), owner_(own), outer_(own->ast_context()) { | 741 : kind_(kind), owner_(own), outer_(own->ast_context()) { |
654 owner()->set_ast_context(this); // Push. | 742 owner()->set_ast_context(this); // Push. |
655 #ifdef DEBUG | 743 #ifdef DEBUG |
656 original_height_ = environment()->stack_height(); | 744 original_height_ = environment()->stack_height(); |
657 #endif | 745 #endif |
(...skipping 668 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1326 | 1414 |
1327 // TODO(mstarzinger): Remove bailout once everything works. | 1415 // TODO(mstarzinger): Remove bailout once everything works. |
1328 if (!FLAG_turbo_exceptions) SetStackOverflow(); | 1416 if (!FLAG_turbo_exceptions) SetStackOverflow(); |
1329 } | 1417 } |
1330 | 1418 |
1331 | 1419 |
1332 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { | 1420 void AstGraphBuilder::VisitDebuggerStatement(DebuggerStatement* stmt) { |
1333 // TODO(turbofan): Do we really need a separate reloc-info for this? | 1421 // TODO(turbofan): Do we really need a separate reloc-info for this? |
1334 Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0)); | 1422 Node* node = NewNode(javascript()->CallRuntime(Runtime::kDebugBreak, 0)); |
1335 PrepareFrameState(node, stmt->DebugBreakId()); | 1423 PrepareFrameState(node, stmt->DebugBreakId()); |
| 1424 environment()->MarkAllLocalsLive(); |
1336 } | 1425 } |
1337 | 1426 |
1338 | 1427 |
1339 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { | 1428 void AstGraphBuilder::VisitFunctionLiteral(FunctionLiteral* expr) { |
1340 Node* context = current_context(); | 1429 Node* context = current_context(); |
1341 | 1430 |
1342 // Build a new shared function info if we cannot find one in the baseline | 1431 // Build a new shared function info if we cannot find one in the baseline |
1343 // code. We also have a stack overflow if the recursive compilation did. | 1432 // code. We also have a stack overflow if the recursive compilation did. |
1344 expr->InitializeSharedInfo(handle(info()->shared_info()->code())); | 1433 expr->InitializeSharedInfo(handle(info()->shared_info()->code())); |
1345 Handle<SharedFunctionInfo> shared_info = expr->shared_info(); | 1434 Handle<SharedFunctionInfo> shared_info = expr->shared_info(); |
(...skipping 1821 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3167 DCHECK(contexts_.size() <= other->contexts_.size()); | 3256 DCHECK(contexts_.size() <= other->contexts_.size()); |
3168 | 3257 |
3169 // Nothing to do if the other environment is dead. | 3258 // Nothing to do if the other environment is dead. |
3170 if (other->IsMarkedAsUnreachable()) return; | 3259 if (other->IsMarkedAsUnreachable()) return; |
3171 | 3260 |
3172 // Resurrect a dead environment by copying the contents of the other one and | 3261 // Resurrect a dead environment by copying the contents of the other one and |
3173 // placing a singleton merge as the new control dependency. | 3262 // placing a singleton merge as the new control dependency. |
3174 if (this->IsMarkedAsUnreachable()) { | 3263 if (this->IsMarkedAsUnreachable()) { |
3175 Node* other_control = other->control_dependency_; | 3264 Node* other_control = other->control_dependency_; |
3176 Node* inputs[] = {other_control}; | 3265 Node* inputs[] = {other_control}; |
| 3266 liveness_block_ = other->liveness_block_; |
3177 control_dependency_ = | 3267 control_dependency_ = |
3178 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); | 3268 graph()->NewNode(common()->Merge(1), arraysize(inputs), inputs, true); |
3179 effect_dependency_ = other->effect_dependency_; | 3269 effect_dependency_ = other->effect_dependency_; |
3180 values_ = other->values_; | 3270 values_ = other->values_; |
3181 // TODO(titzer): make context stack heights match. | 3271 // TODO(titzer): make context stack heights match. |
3182 size_t min = std::min(contexts_.size(), other->contexts_.size()); | 3272 size_t min = std::min(contexts_.size(), other->contexts_.size()); |
3183 contexts_ = other->contexts_; | 3273 contexts_ = other->contexts_; |
3184 contexts_.resize(min, nullptr); | 3274 contexts_.resize(min, nullptr); |
3185 return; | 3275 return; |
3186 } | 3276 } |
3187 | 3277 |
| 3278 // Record the merge for the local variable liveness calculation. |
| 3279 // Unfortunately, we have to mirror the logic in the MergeControl method: |
| 3280 // connect before merge or loop, or create a new merge otherwise. |
| 3281 if (FLAG_analyze_environment_liveness) { |
| 3282 if (GetControlDependency()->opcode() != IrOpcode::kLoop && |
| 3283 GetControlDependency()->opcode() != IrOpcode::kMerge) { |
| 3284 liveness_block_ = builder_->liveness_analyzer()->New(liveness_block()); |
| 3285 } |
| 3286 liveness_block()->AddPredecessor(other->liveness_block()); |
| 3287 } |
| 3288 |
3188 // Create a merge of the control dependencies of both environments and update | 3289 // Create a merge of the control dependencies of both environments and update |
3189 // the current environment's control dependency accordingly. | 3290 // the current environment's control dependency accordingly. |
3190 Node* control = builder_->MergeControl(this->GetControlDependency(), | 3291 Node* control = builder_->MergeControl(this->GetControlDependency(), |
3191 other->GetControlDependency()); | 3292 other->GetControlDependency()); |
3192 UpdateControlDependency(control); | 3293 UpdateControlDependency(control); |
3193 | 3294 |
3194 // Create a merge of the effect dependencies of both environments and update | 3295 // Create a merge of the effect dependencies of both environments and update |
3195 // the current environment's effect dependency accordingly. | 3296 // the current environment's effect dependency accordingly. |
3196 Node* effect = builder_->MergeEffect(this->GetEffectDependency(), | 3297 Node* effect = builder_->MergeEffect(this->GetEffectDependency(), |
3197 other->GetEffectDependency(), control); | 3298 other->GetEffectDependency(), control); |
(...skipping 150 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3348 // Phi does not exist yet, introduce one. | 3449 // Phi does not exist yet, introduce one. |
3349 value = NewPhi(inputs, value, control); | 3450 value = NewPhi(inputs, value, control); |
3350 value->ReplaceInput(inputs - 1, other); | 3451 value->ReplaceInput(inputs - 1, other); |
3351 } | 3452 } |
3352 return value; | 3453 return value; |
3353 } | 3454 } |
3354 | 3455 |
3355 } // namespace compiler | 3456 } // namespace compiler |
3356 } // namespace internal | 3457 } // namespace internal |
3357 } // namespace v8 | 3458 } // namespace v8 |
OLD | NEW |