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

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

Issue 328503003: Extend Range analysis to 64-bit range and mint operations (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 6 years, 6 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, 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_optimizer.h" 5 #include "vm/flow_graph_optimizer.h"
6 6
7 #include "vm/bit_vector.h" 7 #include "vm/bit_vector.h"
8 #include "vm/cha.h" 8 #include "vm/cha.h"
9 #include "vm/cpu.h" 9 #include "vm/cpu.h"
10 #include "vm/dart_entry.h" 10 #include "vm/dart_entry.h"
(...skipping 4563 matching lines...) Expand 10 before | Expand all | Expand 10 after
4574 : flow_graph_(flow_graph), 4574 : flow_graph_(flow_graph),
4575 marked_defns_(NULL) { } 4575 marked_defns_(NULL) { }
4576 4576
4577 // Infer ranges for all values and remove overflow checks from binary smi 4577 // Infer ranges for all values and remove overflow checks from binary smi
4578 // operations when proven redundant. 4578 // operations when proven redundant.
4579 void Analyze(); 4579 void Analyze();
4580 4580
4581 private: 4581 private:
4582 // Collect all values that were proven to be smi in smi_values_ array and all 4582 // Collect all values that were proven to be smi in smi_values_ array and all
4583 // CheckSmi instructions in smi_check_ array. 4583 // CheckSmi instructions in smi_check_ array.
4584 void CollectSmiValues(); 4584 void CollectValues();
4585 4585
4586 // Iterate over smi values and constrain them at branch successors. 4586 // Iterate over smi values and constrain them at branch successors.
4587 // Additionally constraint values after CheckSmi instructions. 4587 // Additionally constraint values after CheckSmi instructions.
4588 void InsertConstraints(); 4588 void InsertConstraints();
4589 4589
4590 // Iterate over uses of the given definition and discover branches that 4590 // Iterate over uses of the given definition and discover branches that
4591 // constrain it. Insert appropriate Constraint instructions at true 4591 // constrain it. Insert appropriate Constraint instructions at true
4592 // and false successor and rename all dominated uses to refer to a 4592 // and false successor and rename all dominated uses to refer to a
4593 // Constraint instead of this definition. 4593 // Constraint instead of this definition.
4594 void InsertConstraintsFor(Definition* defn); 4594 void InsertConstraintsFor(Definition* defn);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4645 // Remove artificial Constraint instructions and replace them with actual 4645 // Remove artificial Constraint instructions and replace them with actual
4646 // unconstrained definitions. 4646 // unconstrained definitions.
4647 void RemoveConstraints(); 4647 void RemoveConstraints();
4648 4648
4649 Range* ConstraintRange(Token::Kind op, Definition* boundary); 4649 Range* ConstraintRange(Token::Kind op, Definition* boundary);
4650 4650
4651 Isolate* isolate() const { return flow_graph_->isolate(); } 4651 Isolate* isolate() const { return flow_graph_->isolate(); }
4652 4652
4653 FlowGraph* flow_graph_; 4653 FlowGraph* flow_graph_;
4654 4654
4655 GrowableArray<Definition*> smi_values_; // Value that are known to be smi. 4655 // Value that are known to be smi or mint.
4656 GrowableArray<CheckSmiInstr*> smi_checks_; // All CheckSmi instructions. 4656 GrowableArray<Definition*> values_;
4657 // All CheckSmi instructions.
4658 GrowableArray<CheckSmiInstr*> smi_checks_;
4657 4659
4658 // All Constraints inserted during InsertConstraints phase. They are treated 4660 // All Constraints inserted during InsertConstraints phase. They are treated
4659 // as smi values. 4661 // as smi values.
4660 GrowableArray<ConstraintInstr*> constraints_; 4662 GrowableArray<ConstraintInstr*> constraints_;
4661 4663
4662 // Bitvector for a quick filtering of known smi values. 4664 // Bitvector for a quick filtering of known smi or mint values.
4663 BitVector* smi_definitions_; 4665 BitVector* definitions_;
4664 4666
4665 // Worklist for induction variables analysis. 4667 // Worklist for induction variables analysis.
4666 GrowableArray<Definition*> worklist_; 4668 GrowableArray<Definition*> worklist_;
4667 BitVector* marked_defns_; 4669 BitVector* marked_defns_;
4668 4670
4669 DISALLOW_COPY_AND_ASSIGN(RangeAnalysis); 4671 DISALLOW_COPY_AND_ASSIGN(RangeAnalysis);
4670 }; 4672 };
4671 4673
4672 4674
4673 void RangeAnalysis::Analyze() { 4675 void RangeAnalysis::Analyze() {
4674 CollectSmiValues(); 4676 CollectValues();
4675 InsertConstraints(); 4677 InsertConstraints();
4676 InferRanges(); 4678 InferRanges();
4677 RemoveConstraints(); 4679 RemoveConstraints();
4678 } 4680 }
4679 4681
4680 4682
4681 void RangeAnalysis::CollectSmiValues() { 4683 void RangeAnalysis::CollectValues() {
4682 const GrowableArray<Definition*>& initial = 4684 const GrowableArray<Definition*>& initial =
4683 *flow_graph_->graph_entry()->initial_definitions(); 4685 *flow_graph_->graph_entry()->initial_definitions();
4684 for (intptr_t i = 0; i < initial.length(); ++i) { 4686 for (intptr_t i = 0; i < initial.length(); ++i) {
4685 Definition* current = initial[i]; 4687 Definition* current = initial[i];
4686 if (current->Type()->ToCid() == kSmiCid) { 4688 if (current->Type()->ToCid() == kSmiCid) {
4687 smi_values_.Add(current); 4689 values_.Add(current);
4690 } else if (current->IsMintDefinition()) {
4691 values_.Add(current);
4688 } 4692 }
4689 } 4693 }
4690 4694
4691 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator(); 4695 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
4692 !block_it.Done(); 4696 !block_it.Done();
4693 block_it.Advance()) { 4697 block_it.Advance()) {
4694 BlockEntryInstr* block = block_it.Current(); 4698 BlockEntryInstr* block = block_it.Current();
4695 4699
4696 4700
4697 if (block->IsGraphEntry() || block->IsCatchBlockEntry()) { 4701 if (block->IsGraphEntry() || block->IsCatchBlockEntry()) {
4698 const GrowableArray<Definition*>& initial = block->IsGraphEntry() 4702 const GrowableArray<Definition*>& initial = block->IsGraphEntry()
4699 ? *block->AsGraphEntry()->initial_definitions() 4703 ? *block->AsGraphEntry()->initial_definitions()
4700 : *block->AsCatchBlockEntry()->initial_definitions(); 4704 : *block->AsCatchBlockEntry()->initial_definitions();
4701 for (intptr_t i = 0; i < initial.length(); ++i) { 4705 for (intptr_t i = 0; i < initial.length(); ++i) {
4702 Definition* current = initial[i]; 4706 Definition* current = initial[i];
4703 if (current->Type()->ToCid() == kSmiCid) { 4707 if (current->Type()->ToCid() == kSmiCid) {
4704 smi_values_.Add(current); 4708 values_.Add(current);
4709 } else if (current->IsMintDefinition()) {
4710 values_.Add(current);
4705 } 4711 }
4706 } 4712 }
4707 } 4713 }
4708 4714
4709 JoinEntryInstr* join = block->AsJoinEntry(); 4715 JoinEntryInstr* join = block->AsJoinEntry();
4710 if (join != NULL) { 4716 if (join != NULL) {
4711 for (PhiIterator phi_it(join); !phi_it.Done(); phi_it.Advance()) { 4717 for (PhiIterator phi_it(join); !phi_it.Done(); phi_it.Advance()) {
4712 PhiInstr* current = phi_it.Current(); 4718 PhiInstr* current = phi_it.Current();
4713 if (current->Type()->ToCid() == kSmiCid) { 4719 if (current->Type()->ToCid() == kSmiCid) {
4714 smi_values_.Add(current); 4720 values_.Add(current);
4721 } else if (current->IsMintDefinition()) {
4722 values_.Add(current);
4715 } 4723 }
4716 } 4724 }
4717 } 4725 }
4718 4726
4719 for (ForwardInstructionIterator instr_it(block); 4727 for (ForwardInstructionIterator instr_it(block);
4720 !instr_it.Done(); 4728 !instr_it.Done();
4721 instr_it.Advance()) { 4729 instr_it.Advance()) {
4722 Instruction* current = instr_it.Current(); 4730 Instruction* current = instr_it.Current();
4723 Definition* defn = current->AsDefinition(); 4731 Definition* defn = current->AsDefinition();
4724 if (defn != NULL) { 4732 if (defn != NULL) {
4725 if ((defn->Type()->ToCid() == kSmiCid) && 4733 if ((defn->Type()->ToCid() == kSmiCid) &&
4726 (defn->ssa_temp_index() != -1)) { 4734 (defn->ssa_temp_index() != -1)) {
4727 smi_values_.Add(defn); 4735 values_.Add(defn);
4736 } else if ((defn->IsMintDefinition()) &&
4737 (defn->ssa_temp_index() != -1)) {
4738 values_.Add(defn);
4728 } 4739 }
4729 } else if (current->IsCheckSmi()) { 4740 } else if (current->IsCheckSmi()) {
4730 smi_checks_.Add(current->AsCheckSmi()); 4741 smi_checks_.Add(current->AsCheckSmi());
4731 } 4742 }
4732 } 4743 }
4733 } 4744 }
4734 } 4745 }
4735 4746
4736 4747
4737 // Returns true if use is dominated by the given instruction. 4748 // Returns true if use is dominated by the given instruction.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4882 branch->false_successor()); 4893 branch->false_successor());
4883 // Mark false_constraint an artificial use of boundary. This ensures 4894 // Mark false_constraint an artificial use of boundary. This ensures
4884 // that constraint's range is recalculated if boundary's range changes. 4895 // that constraint's range is recalculated if boundary's range changes.
4885 if (false_constraint != NULL) { 4896 if (false_constraint != NULL) {
4886 false_constraint->AddDependency(boundary); 4897 false_constraint->AddDependency(boundary);
4887 false_constraint->set_target(branch->false_successor()); 4898 false_constraint->set_target(branch->false_successor());
4888 } 4899 }
4889 } 4900 }
4890 } 4901 }
4891 4902
4903
4892 void RangeAnalysis::InsertConstraintsFor(Definition* defn) { 4904 void RangeAnalysis::InsertConstraintsFor(Definition* defn) {
4893 for (Value* use = defn->input_use_list(); 4905 for (Value* use = defn->input_use_list();
4894 use != NULL; 4906 use != NULL;
4895 use = use->next_use()) { 4907 use = use->next_use()) {
4896 if (use->instruction()->IsBranch()) { 4908 if (use->instruction()->IsBranch()) {
4897 ConstrainValueAfterBranch(defn, use); 4909 ConstrainValueAfterBranch(defn, use);
4898 } else if (use->instruction()->IsCheckArrayBound()) { 4910 } else if (use->instruction()->IsCheckArrayBound()) {
4899 ConstrainValueAfterCheckArrayBound( 4911 ConstrainValueAfterCheckArrayBound(
4900 defn, 4912 defn,
4901 use->instruction()->AsCheckArrayBound(), 4913 use->instruction()->AsCheckArrayBound(),
(...skipping 18 matching lines...) Expand all
4920 RangeBoundary::FromDefinition(index, 1), 4932 RangeBoundary::FromDefinition(index, 1),
4921 RangeBoundary::MaxSmi()); 4933 RangeBoundary::MaxSmi());
4922 } 4934 }
4923 InsertConstraintFor(defn, constraint_range, check); 4935 InsertConstraintFor(defn, constraint_range, check);
4924 } 4936 }
4925 4937
4926 4938
4927 void RangeAnalysis::InsertConstraints() { 4939 void RangeAnalysis::InsertConstraints() {
4928 for (intptr_t i = 0; i < smi_checks_.length(); i++) { 4940 for (intptr_t i = 0; i < smi_checks_.length(); i++) {
4929 CheckSmiInstr* check = smi_checks_[i]; 4941 CheckSmiInstr* check = smi_checks_[i];
4930 InsertConstraintFor(check->value()->definition(), Range::Unknown(), check); 4942 InsertConstraintFor(check->value()->definition(),
4943 Range::UnknownSmi(),
4944 check);
4931 } 4945 }
4932 4946
4933 for (intptr_t i = 0; i < smi_values_.length(); i++) { 4947 for (intptr_t i = 0; i < values_.length(); i++) {
4934 InsertConstraintsFor(smi_values_[i]); 4948 InsertConstraintsFor(values_[i]);
4935 } 4949 }
4936 4950
4937 for (intptr_t i = 0; i < constraints_.length(); i++) { 4951 for (intptr_t i = 0; i < constraints_.length(); i++) {
4938 InsertConstraintsFor(constraints_[i]); 4952 InsertConstraintsFor(constraints_[i]);
4939 } 4953 }
4940 } 4954 }
4941 4955
4942 4956
4943 void RangeAnalysis::ResetWorklist() { 4957 void RangeAnalysis::ResetWorklist() {
4944 if (marked_defns_ == NULL) { 4958 if (marked_defns_ == NULL) {
(...skipping 18 matching lines...) Expand all
4963 } 4977 }
4964 } 4978 }
4965 4979
4966 4980
4967 RangeAnalysis::Direction RangeAnalysis::ToDirection(Value* val) { 4981 RangeAnalysis::Direction RangeAnalysis::ToDirection(Value* val) {
4968 if (val->BindsToConstant()) { 4982 if (val->BindsToConstant()) {
4969 return (Smi::Cast(val->BoundConstant()).Value() >= 0) ? kPositive 4983 return (Smi::Cast(val->BoundConstant()).Value() >= 0) ? kPositive
4970 : kNegative; 4984 : kNegative;
4971 } else if (val->definition()->range() != NULL) { 4985 } else if (val->definition()->range() != NULL) {
4972 Range* range = val->definition()->range(); 4986 Range* range = val->definition()->range();
4973 if (Range::ConstantMin(range).value() >= 0) { 4987 if (Range::ConstantMin(range).ConstantValue() >= 0) {
4974 return kPositive; 4988 return kPositive;
4975 } else if (Range::ConstantMax(range).value() <= 0) { 4989 } else if (Range::ConstantMax(range).ConstantValue() <= 0) {
4976 return kNegative; 4990 return kNegative;
4977 } 4991 }
4978 } 4992 }
4979 return kUnknown; 4993 return kUnknown;
4980 } 4994 }
4981 4995
4982 4996
4983 Range* RangeAnalysis::InferInductionVariableRange(JoinEntryInstr* loop_header, 4997 Range* RangeAnalysis::InferInductionVariableRange(JoinEntryInstr* loop_header,
4984 PhiInstr* var) { 4998 PhiInstr* var) {
4985 BitVector* loop_info = loop_header->loop_info(); 4999 BitVector* loop_info = loop_header->loop_info();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
5063 case kPositive: 5077 case kPositive:
5064 return new(isolate()) Range(RangeBoundary::FromDefinition(initial_value), 5078 return new(isolate()) Range(RangeBoundary::FromDefinition(initial_value),
5065 RangeBoundary::MaxSmi()); 5079 RangeBoundary::MaxSmi());
5066 5080
5067 case kNegative: 5081 case kNegative:
5068 return new(isolate()) Range(RangeBoundary::MinSmi(), 5082 return new(isolate()) Range(RangeBoundary::MinSmi(),
5069 RangeBoundary::FromDefinition(initial_value)); 5083 RangeBoundary::FromDefinition(initial_value));
5070 5084
5071 case kUnknown: 5085 case kUnknown:
5072 case kBoth: 5086 case kBoth:
5073 return Range::Unknown(); 5087 return Range::UnknownSmi();
5074 } 5088 }
5075 5089
5076 UNREACHABLE(); 5090 UNREACHABLE();
5077 return NULL; 5091 return NULL;
5078 } 5092 }
5079 5093
5080 5094
5081 void RangeAnalysis::InferRangesRecursive(BlockEntryInstr* block) { 5095 void RangeAnalysis::InferRangesRecursive(BlockEntryInstr* block) {
5082 JoinEntryInstr* join = block->AsJoinEntry(); 5096 JoinEntryInstr* join = block->AsJoinEntry();
5083 if (join != NULL) { 5097 if (join != NULL) {
5084 const bool is_loop_header = (join->loop_info() != NULL); 5098 const bool is_loop_header = (join->loop_info() != NULL);
5085 for (PhiIterator it(join); !it.Done(); it.Advance()) { 5099 for (PhiIterator it(join); !it.Done(); it.Advance()) {
5086 PhiInstr* phi = it.Current(); 5100 PhiInstr* phi = it.Current();
5087 if (smi_definitions_->Contains(phi->ssa_temp_index())) { 5101 if (definitions_->Contains(phi->ssa_temp_index())) {
5088 if (is_loop_header) { 5102 if (is_loop_header) {
5089 // Try recognizing simple induction variables. 5103 // Try recognizing simple induction variables.
5090 Range* range = InferInductionVariableRange(join, phi); 5104 Range* range = InferInductionVariableRange(join, phi);
5091 if (range != NULL) { 5105 if (range != NULL) {
5092 phi->range_ = range; 5106 phi->range_ = range;
5093 continue; 5107 continue;
5094 } 5108 }
5095 } 5109 }
5096 5110
5097 phi->InferRange(); 5111 phi->InferRange();
5098 } 5112 }
5099 } 5113 }
5100 } 5114 }
5101 5115
5102 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 5116 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
5103 Instruction* current = it.Current(); 5117 Instruction* current = it.Current();
5104 5118
5105 Definition* defn = current->AsDefinition(); 5119 Definition* defn = current->AsDefinition();
5106 if ((defn != NULL) && 5120 if ((defn != NULL) &&
5107 (defn->ssa_temp_index() != -1) && 5121 (defn->ssa_temp_index() != -1) &&
5108 smi_definitions_->Contains(defn->ssa_temp_index())) { 5122 definitions_->Contains(defn->ssa_temp_index())) {
5109 defn->InferRange(); 5123 defn->InferRange();
5110 } else if (FLAG_array_bounds_check_elimination && 5124 } else if (FLAG_array_bounds_check_elimination &&
5111 current->IsCheckArrayBound()) { 5125 current->IsCheckArrayBound()) {
5112 CheckArrayBoundInstr* check = current->AsCheckArrayBound(); 5126 CheckArrayBoundInstr* check = current->AsCheckArrayBound();
5113 RangeBoundary array_length = 5127 RangeBoundary array_length =
5114 RangeBoundary::FromDefinition(check->length()->definition()); 5128 RangeBoundary::FromDefinition(check->length()->definition());
5115 if (check->IsRedundant(array_length)) { 5129 if (check->IsRedundant(array_length)) {
5116 it.RemoveCurrentFromGraph(); 5130 it.RemoveCurrentFromGraph();
5117 } 5131 }
5118 } 5132 }
5119 } 5133 }
5120 5134
5121 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) { 5135 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) {
5122 InferRangesRecursive(block->dominated_blocks()[i]); 5136 InferRangesRecursive(block->dominated_blocks()[i]);
5123 } 5137 }
5124 } 5138 }
5125 5139
5126 5140
5127 void RangeAnalysis::InferRanges() { 5141 void RangeAnalysis::InferRanges() {
5128 // Initialize bitvector for quick filtering of smi values. 5142 // Initialize bitvector for quick filtering of smi values.
5129 smi_definitions_ = 5143 definitions_ =
5130 new(isolate()) BitVector(flow_graph_->current_ssa_temp_index()); 5144 new(isolate()) BitVector(flow_graph_->current_ssa_temp_index());
5131 for (intptr_t i = 0; i < smi_values_.length(); i++) { 5145 for (intptr_t i = 0; i < values_.length(); i++) {
5132 smi_definitions_->Add(smi_values_[i]->ssa_temp_index()); 5146 definitions_->Add(values_[i]->ssa_temp_index());
5133 } 5147 }
5134 for (intptr_t i = 0; i < constraints_.length(); i++) { 5148 for (intptr_t i = 0; i < constraints_.length(); i++) {
5135 smi_definitions_->Add(constraints_[i]->ssa_temp_index()); 5149 definitions_->Add(constraints_[i]->ssa_temp_index());
5136 } 5150 }
5137 5151
5138 // Infer initial values of ranges. 5152 // Infer initial values of ranges.
5139 const GrowableArray<Definition*>& initial = 5153 const GrowableArray<Definition*>& initial =
5140 *flow_graph_->graph_entry()->initial_definitions(); 5154 *flow_graph_->graph_entry()->initial_definitions();
5141 for (intptr_t i = 0; i < initial.length(); ++i) { 5155 for (intptr_t i = 0; i < initial.length(); ++i) {
5142 Definition* definition = initial[i]; 5156 Definition* definition = initial[i];
5143 if (smi_definitions_->Contains(definition->ssa_temp_index())) { 5157 if (definitions_->Contains(definition->ssa_temp_index())) {
5144 definition->InferRange(); 5158 definition->InferRange();
5145 } 5159 }
5146 } 5160 }
5147 InferRangesRecursive(flow_graph_->graph_entry()); 5161 InferRangesRecursive(flow_graph_->graph_entry());
5148 5162
5149 if (FLAG_trace_range_analysis) { 5163 if (FLAG_trace_range_analysis) {
5150 OS::Print("---- after range analysis -------\n"); 5164 OS::Print("---- after range analysis -------\n");
5151 FlowGraphPrinter printer(*flow_graph_); 5165 FlowGraphPrinter printer(*flow_graph_);
5152 printer.PrintBlocks(); 5166 printer.PrintBlocks();
5153 } 5167 }
5154 } 5168 }
5155 5169
5156 5170
5157 void RangeAnalysis::RemoveConstraints() { 5171 void RangeAnalysis::RemoveConstraints() {
5158 for (intptr_t i = 0; i < constraints_.length(); i++) { 5172 for (intptr_t i = 0; i < constraints_.length(); i++) {
5159 Definition* def = constraints_[i]->value()->definition(); 5173 Definition* def = constraints_[i]->value()->definition();
5160 // Some constraints might be constraining constraints. Unwind the chain of 5174 // Some constraints might be constraining constraints. Unwind the chain of
5161 // constraints until we reach the actual definition. 5175 // constraints until we reach the actual definition.
5162 while (def->IsConstraint()) { 5176 while (def->IsConstraint()) {
5163 def = def->AsConstraint()->value()->definition(); 5177 def = def->AsConstraint()->value()->definition();
5164 } 5178 }
5165 constraints_[i]->ReplaceUsesWith(def); 5179 constraints_[i]->ReplaceUsesWith(def);
5166 constraints_[i]->RemoveFromGraph(); 5180 constraints_[i]->RemoveFromGraph();
5167 } 5181 }
5168 } 5182 }
5169 5183
5170 5184
5171 void FlowGraphOptimizer::InferSmiRanges() { 5185 void FlowGraphOptimizer::InferIntRanges() {
5172 RangeAnalysis range_analysis(flow_graph_); 5186 RangeAnalysis range_analysis(flow_graph_);
5173 range_analysis.Analyze(); 5187 range_analysis.Analyze();
5174 } 5188 }
5175 5189
5176 5190
5177 void TryCatchAnalyzer::Optimize(FlowGraph* flow_graph) { 5191 void TryCatchAnalyzer::Optimize(FlowGraph* flow_graph) {
5178 // For every catch-block: Iterate over all call instructions inside the 5192 // For every catch-block: Iterate over all call instructions inside the
5179 // corresponding try-block and figure out for each environment value if it 5193 // corresponding try-block and figure out for each environment value if it
5180 // is the same constant at all calls. If yes, replace the initial definition 5194 // is the same constant at all calls. If yes, replace the initial definition
5181 // at the catch-entry with this constant. 5195 // at the catch-entry with this constant.
(...skipping 4671 matching lines...) Expand 10 before | Expand all | Expand 10 after
9853 } 9867 }
9854 9868
9855 // Insert materializations at environment uses. 9869 // Insert materializations at environment uses.
9856 for (intptr_t i = 0; i < exits.length(); i++) { 9870 for (intptr_t i = 0; i < exits.length(); i++) {
9857 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); 9871 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots);
9858 } 9872 }
9859 } 9873 }
9860 9874
9861 9875
9862 } // namespace dart 9876 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698