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

Side by Side Diff: runtime/vm/flow_graph.cc

Issue 678763004: Make CTX allocatable by the register allocator. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: incorporated latest comments Created 6 years, 1 month 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 #include "vm/flow_graph.h" 5 #include "vm/flow_graph.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/flow_graph_builder.h" 8 #include "vm/flow_graph_builder.h"
9 #include "vm/intermediate_language.h" 9 #include "vm/intermediate_language.h"
10 #include "vm/growable_array.h" 10 #include "vm/growable_array.h"
11 #include "vm/object_store.h"
11 #include "vm/report.h" 12 #include "vm/report.h"
12 13
13 namespace dart { 14 namespace dart {
14 15
15 DECLARE_FLAG(bool, reorder_basic_blocks); 16 DECLARE_FLAG(bool, reorder_basic_blocks);
16 DECLARE_FLAG(bool, trace_optimization); 17 DECLARE_FLAG(bool, trace_optimization);
17 DECLARE_FLAG(bool, verify_compiler); 18 DECLARE_FLAG(bool, verify_compiler);
18 19
19 20
20 FlowGraph::FlowGraph(const FlowGraphBuilder& builder, 21 FlowGraph::FlowGraph(const FlowGraphBuilder& builder,
21 GraphEntryInstr* graph_entry, 22 GraphEntryInstr* graph_entry,
22 intptr_t max_block_id) 23 intptr_t max_block_id)
23 : isolate_(Isolate::Current()), 24 : isolate_(Isolate::Current()),
24 parent_(), 25 parent_(),
25 current_ssa_temp_index_(0), 26 current_ssa_temp_index_(0),
26 max_block_id_(max_block_id), 27 max_block_id_(max_block_id),
27 builder_(builder), 28 builder_(builder),
28 parsed_function_(*builder.parsed_function()), 29 parsed_function_(*builder.parsed_function()),
29 num_copied_params_(builder.num_copied_params()), 30 num_copied_params_(builder.num_copied_params()),
30 num_non_copied_params_(builder.num_non_copied_params()), 31 num_non_copied_params_(builder.num_non_copied_params()),
31 num_stack_locals_(builder.num_stack_locals()), 32 num_stack_locals_(builder.num_stack_locals()),
32 graph_entry_(graph_entry), 33 graph_entry_(graph_entry),
33 preorder_(), 34 preorder_(),
34 postorder_(), 35 postorder_(),
35 reverse_postorder_(), 36 reverse_postorder_(),
36 optimized_block_order_(), 37 optimized_block_order_(),
37 constant_null_(NULL), 38 constant_null_(NULL),
38 constant_dead_(NULL), 39 constant_dead_(NULL),
40 constant_empty_context_(NULL),
39 block_effects_(NULL), 41 block_effects_(NULL),
40 licm_allowed_(true), 42 licm_allowed_(true),
41 loop_headers_(NULL), 43 loop_headers_(NULL),
42 loop_invariant_loads_(NULL), 44 loop_invariant_loads_(NULL),
43 guarded_fields_(builder.guarded_fields()), 45 guarded_fields_(builder.guarded_fields()),
44 deferred_prefixes_(builder.deferred_prefixes()), 46 deferred_prefixes_(builder.deferred_prefixes()),
45 captured_parameters_( 47 captured_parameters_(
46 new(isolate_) BitVector(isolate_, variable_count())) { 48 new(isolate_) BitVector(isolate_, variable_count())) {
47 DiscoverBlocks(); 49 DiscoverBlocks();
48 } 50 }
(...skipping 409 matching lines...) Expand 10 before | Expand all | Expand 10 after
458 } 460 }
459 assigned_vars_.Add(kill); 461 assigned_vars_.Add(kill);
460 } 462 }
461 463
462 return assigned_vars_; 464 return assigned_vars_;
463 } 465 }
464 466
465 // Returns true if the value set by the given store reaches any load from the 467 // Returns true if the value set by the given store reaches any load from the
466 // same local variable. 468 // same local variable.
467 bool IsStoreAlive(BlockEntryInstr* block, StoreLocalInstr* store) { 469 bool IsStoreAlive(BlockEntryInstr* block, StoreLocalInstr* store) {
470 if (store->local().Equals(*flow_graph_->CurrentContextVar())) {
471 return true;
472 }
473
468 if (store->is_dead()) { 474 if (store->is_dead()) {
469 return false; 475 return false;
470 } 476 }
471
472 if (store->is_last()) { 477 if (store->is_last()) {
473 const intptr_t index = store->local().BitIndexIn(num_non_copied_params_); 478 const intptr_t index = store->local().BitIndexIn(num_non_copied_params_);
474 return GetLiveOutSet(block)->Contains(index); 479 return GetLiveOutSet(block)->Contains(index);
475 } 480 }
476 481
477 return true; 482 return true;
478 } 483 }
479 484
480 // Returns true if the given load is the last for the local and the value 485 // Returns true if the given load is the last for the local and the value
481 // of the local will not flow into another one. 486 // of the local will not flow into another one.
482 bool IsLastLoad(BlockEntryInstr* block, LoadLocalInstr* load) { 487 bool IsLastLoad(BlockEntryInstr* block, LoadLocalInstr* load) {
488 if (load->local().Equals(*flow_graph_->CurrentContextVar())) {
489 return false;
490 }
483 const intptr_t index = load->local().BitIndexIn(num_non_copied_params_); 491 const intptr_t index = load->local().BitIndexIn(num_non_copied_params_);
484 return load->is_last() && !GetLiveOutSet(block)->Contains(index); 492 return load->is_last() && !GetLiveOutSet(block)->Contains(index);
485 } 493 }
486 494
487 private: 495 private:
488 virtual void ComputeInitialSets(); 496 virtual void ComputeInitialSets();
489 497
490 const FlowGraph* flow_graph_; 498 const FlowGraph* flow_graph_;
491 const intptr_t num_non_copied_params_; 499 const intptr_t num_non_copied_params_;
492 GrowableArray<BitVector*> assigned_vars_; 500 GrowableArray<BitVector*> assigned_vars_;
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
558 intptr_t next_virtual_register_number, 566 intptr_t next_virtual_register_number,
559 ZoneGrowableArray<Definition*>* inlining_parameters) { 567 ZoneGrowableArray<Definition*>* inlining_parameters) {
560 ASSERT((next_virtual_register_number == 0) || (inlining_parameters != NULL)); 568 ASSERT((next_virtual_register_number == 0) || (inlining_parameters != NULL));
561 current_ssa_temp_index_ = next_virtual_register_number; 569 current_ssa_temp_index_ = next_virtual_register_number;
562 GrowableArray<BitVector*> dominance_frontier; 570 GrowableArray<BitVector*> dominance_frontier;
563 ComputeDominators(&dominance_frontier); 571 ComputeDominators(&dominance_frontier);
564 572
565 VariableLivenessAnalysis variable_liveness(this); 573 VariableLivenessAnalysis variable_liveness(this);
566 variable_liveness.Analyze(); 574 variable_liveness.Analyze();
567 575
576 GrowableArray<PhiInstr*> live_phis;
577
568 InsertPhis(preorder_, 578 InsertPhis(preorder_,
569 variable_liveness.ComputeAssignedVars(), 579 variable_liveness.ComputeAssignedVars(),
570 dominance_frontier); 580 dominance_frontier,
581 &live_phis);
571 582
572 GrowableArray<PhiInstr*> live_phis;
573 583
574 // Rename uses to reference inserted phis where appropriate. 584 // Rename uses to reference inserted phis where appropriate.
575 // Collect phis that reach a non-environment use. 585 // Collect phis that reach a non-environment use.
576 Rename(&live_phis, &variable_liveness, inlining_parameters); 586 Rename(&live_phis, &variable_liveness, inlining_parameters);
577 587
578 // Propagate alive mark transitively from alive phis and then remove 588 // Propagate alive mark transitively from alive phis and then remove
579 // non-live ones. 589 // non-live ones.
580 RemoveDeadPhis(&live_phis); 590 RemoveDeadPhis(&live_phis);
581 } 591 }
582 592
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
695 (*label)[current_index] = 705 (*label)[current_index] =
696 Utils::Minimum((*label)[current_index], (*label)[next_index]); 706 Utils::Minimum((*label)[current_index], (*label)[next_index]);
697 (*parent)[current_index] = (*parent)[next_index]; 707 (*parent)[current_index] = (*parent)[next_index];
698 } 708 }
699 } 709 }
700 710
701 711
702 void FlowGraph::InsertPhis( 712 void FlowGraph::InsertPhis(
703 const GrowableArray<BlockEntryInstr*>& preorder, 713 const GrowableArray<BlockEntryInstr*>& preorder,
704 const GrowableArray<BitVector*>& assigned_vars, 714 const GrowableArray<BitVector*>& assigned_vars,
705 const GrowableArray<BitVector*>& dom_frontier) { 715 const GrowableArray<BitVector*>& dom_frontier,
716 GrowableArray<PhiInstr*>* live_phis) {
706 const intptr_t block_count = preorder.length(); 717 const intptr_t block_count = preorder.length();
707 // Map preorder block number to the highest variable index that has a phi 718 // Map preorder block number to the highest variable index that has a phi
708 // in that block. Use it to avoid inserting multiple phis for the same 719 // in that block. Use it to avoid inserting multiple phis for the same
709 // variable. 720 // variable.
710 GrowableArray<intptr_t> has_already(block_count); 721 GrowableArray<intptr_t> has_already(block_count);
711 // Map preorder block number to the highest variable index for which the 722 // Map preorder block number to the highest variable index for which the
712 // block went on the worklist. Use it to avoid adding the same block to 723 // block went on the worklist. Use it to avoid adding the same block to
713 // the worklist more than once for the same variable. 724 // the worklist more than once for the same variable.
714 GrowableArray<intptr_t> work(block_count); 725 GrowableArray<intptr_t> work(block_count);
715 726
716 // Initialize has_already and work. 727 // Initialize has_already and work.
717 for (intptr_t block_index = 0; block_index < block_count; ++block_index) { 728 for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
718 has_already.Add(-1); 729 has_already.Add(-1);
719 work.Add(-1); 730 work.Add(-1);
720 } 731 }
721 732
722 // Insert phis for each variable in turn. 733 // Insert phis for each variable in turn.
723 GrowableArray<BlockEntryInstr*> worklist; 734 GrowableArray<BlockEntryInstr*> worklist;
724 for (intptr_t var_index = 0; var_index < variable_count(); ++var_index) { 735 for (intptr_t var_index = 0; var_index < variable_count(); ++var_index) {
736 const bool always_live = var_index == CurrentContextEnvIndex();
725 // Add to the worklist each block containing an assignment. 737 // Add to the worklist each block containing an assignment.
726 for (intptr_t block_index = 0; block_index < block_count; ++block_index) { 738 for (intptr_t block_index = 0; block_index < block_count; ++block_index) {
727 if (assigned_vars[block_index]->Contains(var_index)) { 739 if (assigned_vars[block_index]->Contains(var_index)) {
728 work[block_index] = var_index; 740 work[block_index] = var_index;
729 worklist.Add(preorder[block_index]); 741 worklist.Add(preorder[block_index]);
730 } 742 }
731 } 743 }
732 744
733 while (!worklist.is_empty()) { 745 while (!worklist.is_empty()) {
734 BlockEntryInstr* current = worklist.RemoveLast(); 746 BlockEntryInstr* current = worklist.RemoveLast();
735 // Ensure a phi for each block in the dominance frontier of current. 747 // Ensure a phi for each block in the dominance frontier of current.
736 for (BitVector::Iterator it(dom_frontier[current->preorder_number()]); 748 for (BitVector::Iterator it(dom_frontier[current->preorder_number()]);
737 !it.Done(); 749 !it.Done();
738 it.Advance()) { 750 it.Advance()) {
739 int index = it.Current(); 751 int index = it.Current();
740 if (has_already[index] < var_index) { 752 if (has_already[index] < var_index) {
741 BlockEntryInstr* block = preorder[index]; 753 BlockEntryInstr* block = preorder[index];
742 ASSERT(block->IsJoinEntry()); 754 ASSERT(block->IsJoinEntry());
743 block->AsJoinEntry()->InsertPhi(var_index, variable_count()); 755 PhiInstr* phi = block->AsJoinEntry()->InsertPhi(var_index,
756 variable_count());
757 if (always_live) {
758 phi->mark_alive();
759 live_phis->Add(phi);
760 }
744 has_already[index] = var_index; 761 has_already[index] = var_index;
745 if (work[index] < var_index) { 762 if (work[index] < var_index) {
746 work[index] = var_index; 763 work[index] = var_index;
747 worklist.Add(block); 764 worklist.Add(block);
748 } 765 }
749 } 766 }
750 } 767 }
751 } 768 }
752 } 769 }
753 } 770 }
754 771
755 772
756 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis, 773 void FlowGraph::Rename(GrowableArray<PhiInstr*>* live_phis,
757 VariableLivenessAnalysis* variable_liveness, 774 VariableLivenessAnalysis* variable_liveness,
758 ZoneGrowableArray<Definition*>* inlining_parameters) { 775 ZoneGrowableArray<Definition*>* inlining_parameters) {
759 GraphEntryInstr* entry = graph_entry(); 776 GraphEntryInstr* entry = graph_entry();
760 777
761 // Initial renaming environment. 778 // Initial renaming environment.
762 GrowableArray<Definition*> env(variable_count()); 779 GrowableArray<Definition*> env(variable_count());
763 780
764 // Add global constants to the initial definitions. 781 // Add global constants to the initial definitions.
765 constant_null_ = GetConstant(Object::ZoneHandle()); 782 constant_null_ = GetConstant(Object::ZoneHandle());
766 constant_dead_ = GetConstant(Symbols::OptimizedOut()); 783 constant_dead_ = GetConstant(Symbols::OptimizedOut());
784 constant_empty_context_ = GetConstant(Context::Handle(
785 isolate()->object_store()->empty_context()));
767 786
768 // Add parameters to the initial definitions and renaming environment. 787 // Add parameters to the initial definitions and renaming environment.
769 if (inlining_parameters != NULL) { 788 if (inlining_parameters != NULL) {
770 // Use known parameters. 789 // Use known parameters.
771 ASSERT(parameter_count() == inlining_parameters->length()); 790 ASSERT(parameter_count() == inlining_parameters->length());
772 for (intptr_t i = 0; i < parameter_count(); ++i) { 791 for (intptr_t i = 0; i < parameter_count(); ++i) {
773 Definition* defn = (*inlining_parameters)[i]; 792 Definition* defn = (*inlining_parameters)[i];
774 AllocateSSAIndexes(defn); 793 AllocateSSAIndexes(defn);
775 AddToInitialDefinitions(defn); 794 AddToInitialDefinitions(defn);
776 env.Add(defn); 795 env.Add(defn);
777 } 796 }
778 } else { 797 } else {
779 // Create new parameters. For functions compiled for OSR, the locals 798 // Create new parameters. For functions compiled for OSR, the locals
780 // are unknown and so treated like parameters. 799 // are unknown and so treated like parameters.
781 intptr_t count = IsCompiledForOsr() ? variable_count() : parameter_count(); 800 intptr_t count = IsCompiledForOsr() ? variable_count() : parameter_count();
782 for (intptr_t i = 0; i < count; ++i) { 801 for (intptr_t i = 0; i < count; ++i) {
783 ParameterInstr* param = new(isolate()) ParameterInstr(i, entry); 802 ParameterInstr* param = new(isolate()) ParameterInstr(i, entry);
784 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. 803 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
785 AddToInitialDefinitions(param); 804 AddToInitialDefinitions(param);
786 env.Add(param); 805 env.Add(param);
787 } 806 }
788 } 807 }
789 808
790 // Initialize all locals with #null in the renaming environment. For OSR, 809 // Initialize all locals in the renaming environment For OSR, the locals have
791 // the locals have already been handled as parameters. 810 // already been handled as parameters.
792 if (!IsCompiledForOsr()) { 811 if (!IsCompiledForOsr()) {
793 for (intptr_t i = parameter_count(); i < variable_count(); ++i) { 812 for (intptr_t i = parameter_count(); i < variable_count(); ++i) {
794 env.Add(constant_null()); 813 if (i == CurrentContextEnvIndex()) {
814 if (parsed_function().function().IsClosureFunction()) {
815 CurrentContextInstr* context = new CurrentContextInstr();
816 context->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
817 AddToInitialDefinitions(context);
818 env.Add(context);
819 } else {
820 env.Add(constant_empty_context());
821 }
822 } else {
823 env.Add(constant_null());
824 }
795 } 825 }
796 } 826 }
797 827
798 if (entry->SuccessorCount() > 1) { 828 if (entry->SuccessorCount() > 1) {
799 // Functions with try-catch have a fixed area of stack slots reserved 829 // Functions with try-catch have a fixed area of stack slots reserved
800 // so that all local variables are stored at a known location when 830 // so that all local variables are stored at a known location when
801 // on entry to the catch. 831 // on entry to the catch.
802 entry->set_fixed_slot_count(num_stack_locals() + num_copied_params()); 832 entry->set_fixed_slot_count(num_stack_locals() + num_copied_params());
803 } 833 }
804 RenameRecursive(entry, &env, live_phis, variable_liveness); 834 RenameRecursive(entry, &env, live_phis, variable_liveness);
805 } 835 }
806 836
807 837
808 void FlowGraph::AttachEnvironment(Instruction* instr, 838 void FlowGraph::AttachEnvironment(Instruction* instr,
809 GrowableArray<Definition*>* env) { 839 GrowableArray<Definition*>* env) {
810 Environment* deopt_env = 840 Environment* deopt_env =
811 Environment::From(isolate(), 841 Environment::From(isolate(),
812 *env, 842 *env,
813 num_non_copied_params_, 843 num_non_copied_params_,
814 &parsed_function_); 844 &parsed_function_);
815 // TODO(fschneider): Add predicates CanEagerlyDeoptimize and
816 // CanLazilyDeoptimize to instructions to generally deal with instructions
817 // that have pushed arguments and input operands.
818 // Right now, closure calls are the only instructions that have both. They
819 // also don't have an eager deoptimziation point, so the environment attached
820 // here is only used for after the call.
821 if (instr->IsClosureCall()) { 845 if (instr->IsClosureCall()) {
822 deopt_env = deopt_env->DeepCopy(isolate(), 846 deopt_env = deopt_env->DeepCopy(isolate(),
823 deopt_env->Length() - instr->InputCount()); 847 deopt_env->Length() - instr->InputCount());
824 } 848 }
825 instr->SetEnvironment(deopt_env); 849 instr->SetEnvironment(deopt_env);
826 for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) { 850 for (Environment::DeepIterator it(deopt_env); !it.Done(); it.Advance()) {
827 Value* use = it.CurrentValue(); 851 Value* use = it.CurrentValue();
828 use->definition()->AddEnvUse(use); 852 use->definition()->AddEnvUse(use);
829 } 853 }
830 if (instr->CanDeoptimize()) { 854 if (instr->CanDeoptimize()) {
831 instr->env()->set_deopt_id(instr->deopt_id()); 855 instr->env()->set_deopt_id(instr->deopt_id());
832 } 856 }
833 } 857 }
834 858
835 859
836 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry, 860 void FlowGraph::RenameRecursive(BlockEntryInstr* block_entry,
837 GrowableArray<Definition*>* env, 861 GrowableArray<Definition*>* env,
838 GrowableArray<PhiInstr*>* live_phis, 862 GrowableArray<PhiInstr*>* live_phis,
839 VariableLivenessAnalysis* variable_liveness) { 863 VariableLivenessAnalysis* variable_liveness) {
840 // 1. Process phis first. 864 // 1. Process phis first.
841 if (block_entry->IsJoinEntry()) { 865 if (block_entry->IsJoinEntry()) {
842 JoinEntryInstr* join = block_entry->AsJoinEntry(); 866 JoinEntryInstr* join = block_entry->AsJoinEntry();
843 if (join->phis() != NULL) { 867 if (join->phis() != NULL) {
844 for (intptr_t i = 0; i < join->phis()->length(); ++i) { 868 for (intptr_t i = 0; i < join->phis()->length(); ++i) {
845 PhiInstr* phi = (*join->phis())[i]; 869 PhiInstr* phi = (*join->phis())[i];
846 if (phi != NULL) { 870 if (phi != NULL) {
847 (*env)[i] = phi; 871 (*env)[i] = phi;
848 phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. 872 phi->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
849 if (block_entry->InsideTryBlock()) { 873 if (block_entry->InsideTryBlock() && !phi->is_alive()) {
850 // This is a safe approximation. Inside try{} all locals are 874 // This is a safe approximation. Inside try{} all locals are
851 // used at every call implicitly, so we mark all phis as live 875 // used at every call implicitly, so we mark all phis as live
852 // from the start. 876 // from the start.
853 // TODO(fschneider): Improve this approximation to eliminate 877 // TODO(fschneider): Improve this approximation to eliminate
854 // more redundant phis. 878 // more redundant phis.
855 phi->mark_alive(); 879 phi->mark_alive();
856 live_phis->Add(phi); 880 live_phis->Add(phi);
857 } 881 }
858 } 882 }
859 } 883 }
860 } 884 }
861 } else if (block_entry->IsCatchBlockEntry()) { 885 } else if (block_entry->IsCatchBlockEntry()) {
862 // Add real definitions for all locals and parameters. 886 // Add real definitions for all locals and parameters.
863 for (intptr_t i = 0; i < env->length(); ++i) { 887 for (intptr_t i = 0; i < env->length(); ++i) {
864 ParameterInstr* param = new(isolate()) ParameterInstr(i, block_entry); 888 ParameterInstr* param = new(isolate()) ParameterInstr(i, block_entry);
865 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp. 889 param->set_ssa_temp_index(alloc_ssa_temp_index()); // New SSA temp.
866 (*env)[i] = param; 890 (*env)[i] = param;
867 block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param); 891 block_entry->AsCatchBlockEntry()->initial_definitions()->Add(param);
868 } 892 }
869 } 893 }
870 894
871 // Prune non-live variables at block entry by replacing their environment 895 // Prune non-live variables at block entry by replacing their environment
872 // slots with null. 896 // slots with null.
873 BitVector* live_in = variable_liveness->GetLiveInSet(block_entry); 897 BitVector* live_in = variable_liveness->GetLiveInSet(block_entry);
874 for (intptr_t i = 0; i < variable_count(); i++) { 898 for (intptr_t i = 0; i < variable_count(); i++) {
875 if (!live_in->Contains(i)) { 899 // TODO(fschneider): Make sure that live_in always contains the
900 // CurrentContext variable to avoid the special case here.
901 if (!live_in->Contains(i) && (i != CurrentContextEnvIndex())) {
876 (*env)[i] = constant_dead(); 902 (*env)[i] = constant_dead();
877 } 903 }
878 } 904 }
879 905
880 // Attach environment to the block entry. 906 // Attach environment to the block entry.
881 AttachEnvironment(block_entry, env); 907 AttachEnvironment(block_entry, env);
882 908
883 // 2. Process normal instructions. 909 // 2. Process normal instructions.
884 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) { 910 for (ForwardInstructionIterator it(block_entry); !it.Done(); it.Advance()) {
885 Instruction* current = it.Current(); 911 Instruction* current = it.Current();
(...skipping 422 matching lines...) Expand 10 before | Expand all | Expand 10 after
1308 } 1334 }
1309 1335
1310 1336
1311 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from, 1337 bool BlockEffects::IsSideEffectFreePath(BlockEntryInstr* from,
1312 BlockEntryInstr* to) const { 1338 BlockEntryInstr* to) const {
1313 return available_at_[to->postorder_number()]->Contains( 1339 return available_at_[to->postorder_number()]->Contains(
1314 from->postorder_number()); 1340 from->postorder_number());
1315 } 1341 }
1316 1342
1317 } // namespace dart 1343 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698