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

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
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('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 (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 4523 matching lines...) Expand 10 before | Expand all | Expand 10 after
4534 : flow_graph_(flow_graph), 4534 : flow_graph_(flow_graph),
4535 marked_defns_(NULL) { } 4535 marked_defns_(NULL) { }
4536 4536
4537 // Infer ranges for all values and remove overflow checks from binary smi 4537 // Infer ranges for all values and remove overflow checks from binary smi
4538 // operations when proven redundant. 4538 // operations when proven redundant.
4539 void Analyze(); 4539 void Analyze();
4540 4540
4541 private: 4541 private:
4542 // Collect all values that were proven to be smi in smi_values_ array and all 4542 // Collect all values that were proven to be smi in smi_values_ array and all
4543 // CheckSmi instructions in smi_check_ array. 4543 // CheckSmi instructions in smi_check_ array.
4544 void CollectSmiValues(); 4544 void CollectValues();
4545 4545
4546 // Iterate over smi values and constrain them at branch successors. 4546 // Iterate over smi values and constrain them at branch successors.
4547 // Additionally constraint values after CheckSmi instructions. 4547 // Additionally constraint values after CheckSmi instructions.
4548 void InsertConstraints(); 4548 void InsertConstraints();
4549 4549
4550 // Iterate over uses of the given definition and discover branches that 4550 // Iterate over uses of the given definition and discover branches that
4551 // constrain it. Insert appropriate Constraint instructions at true 4551 // constrain it. Insert appropriate Constraint instructions at true
4552 // and false successor and rename all dominated uses to refer to a 4552 // and false successor and rename all dominated uses to refer to a
4553 // Constraint instead of this definition. 4553 // Constraint instead of this definition.
4554 void InsertConstraintsFor(Definition* defn); 4554 void InsertConstraintsFor(Definition* defn);
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
4605 // Remove artificial Constraint instructions and replace them with actual 4605 // Remove artificial Constraint instructions and replace them with actual
4606 // unconstrained definitions. 4606 // unconstrained definitions.
4607 void RemoveConstraints(); 4607 void RemoveConstraints();
4608 4608
4609 Range* ConstraintRange(Token::Kind op, Definition* boundary); 4609 Range* ConstraintRange(Token::Kind op, Definition* boundary);
4610 4610
4611 Isolate* isolate() const { return flow_graph_->isolate(); } 4611 Isolate* isolate() const { return flow_graph_->isolate(); }
4612 4612
4613 FlowGraph* flow_graph_; 4613 FlowGraph* flow_graph_;
4614 4614
4615 GrowableArray<Definition*> smi_values_; // Value that are known to be smi. 4615 // Value that are known to be smi or mint.
4616 GrowableArray<CheckSmiInstr*> smi_checks_; // All CheckSmi instructions. 4616 GrowableArray<Definition*> values_;
4617 // All CheckSmi instructions.
4618 GrowableArray<CheckSmiInstr*> smi_checks_;
4617 4619
4618 // All Constraints inserted during InsertConstraints phase. They are treated 4620 // All Constraints inserted during InsertConstraints phase. They are treated
4619 // as smi values. 4621 // as smi values.
4620 GrowableArray<ConstraintInstr*> constraints_; 4622 GrowableArray<ConstraintInstr*> constraints_;
4621 4623
4622 // Bitvector for a quick filtering of known smi values. 4624 // Bitvector for a quick filtering of known smi or mint values.
4623 BitVector* smi_definitions_; 4625 BitVector* definitions_;
4624 4626
4625 // Worklist for induction variables analysis. 4627 // Worklist for induction variables analysis.
4626 GrowableArray<Definition*> worklist_; 4628 GrowableArray<Definition*> worklist_;
4627 BitVector* marked_defns_; 4629 BitVector* marked_defns_;
4628 4630
4629 DISALLOW_COPY_AND_ASSIGN(RangeAnalysis); 4631 DISALLOW_COPY_AND_ASSIGN(RangeAnalysis);
4630 }; 4632 };
4631 4633
4632 4634
4633 void RangeAnalysis::Analyze() { 4635 void RangeAnalysis::Analyze() {
4634 CollectSmiValues(); 4636 CollectValues();
4635 InsertConstraints(); 4637 InsertConstraints();
4636 InferRanges(); 4638 InferRanges();
4637 RemoveConstraints(); 4639 RemoveConstraints();
4638 } 4640 }
4639 4641
4640 4642
4641 void RangeAnalysis::CollectSmiValues() { 4643 void RangeAnalysis::CollectValues() {
4642 const GrowableArray<Definition*>& initial = 4644 const GrowableArray<Definition*>& initial =
4643 *flow_graph_->graph_entry()->initial_definitions(); 4645 *flow_graph_->graph_entry()->initial_definitions();
4644 for (intptr_t i = 0; i < initial.length(); ++i) { 4646 for (intptr_t i = 0; i < initial.length(); ++i) {
4645 Definition* current = initial[i]; 4647 Definition* current = initial[i];
4646 if (current->Type()->ToCid() == kSmiCid) { 4648 if (current->Type()->ToCid() == kSmiCid) {
4647 smi_values_.Add(current); 4649 values_.Add(current);
4650 } else if (current->IsMintDefinition()) {
4651 values_.Add(current);
4648 } 4652 }
4649 } 4653 }
4650 4654
4651 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator(); 4655 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
4652 !block_it.Done(); 4656 !block_it.Done();
4653 block_it.Advance()) { 4657 block_it.Advance()) {
4654 BlockEntryInstr* block = block_it.Current(); 4658 BlockEntryInstr* block = block_it.Current();
4655 4659
4656 4660
4657 if (block->IsGraphEntry() || block->IsCatchBlockEntry()) { 4661 if (block->IsGraphEntry() || block->IsCatchBlockEntry()) {
4658 const GrowableArray<Definition*>& initial = block->IsGraphEntry() 4662 const GrowableArray<Definition*>& initial = block->IsGraphEntry()
4659 ? *block->AsGraphEntry()->initial_definitions() 4663 ? *block->AsGraphEntry()->initial_definitions()
4660 : *block->AsCatchBlockEntry()->initial_definitions(); 4664 : *block->AsCatchBlockEntry()->initial_definitions();
4661 for (intptr_t i = 0; i < initial.length(); ++i) { 4665 for (intptr_t i = 0; i < initial.length(); ++i) {
4662 Definition* current = initial[i]; 4666 Definition* current = initial[i];
4663 if (current->Type()->ToCid() == kSmiCid) { 4667 if (current->Type()->ToCid() == kSmiCid) {
4664 smi_values_.Add(current); 4668 values_.Add(current);
4669 } else if (current->IsMintDefinition()) {
4670 values_.Add(current);
4665 } 4671 }
4666 } 4672 }
4667 } 4673 }
4668 4674
4669 JoinEntryInstr* join = block->AsJoinEntry(); 4675 JoinEntryInstr* join = block->AsJoinEntry();
4670 if (join != NULL) { 4676 if (join != NULL) {
4671 for (PhiIterator phi_it(join); !phi_it.Done(); phi_it.Advance()) { 4677 for (PhiIterator phi_it(join); !phi_it.Done(); phi_it.Advance()) {
4672 PhiInstr* current = phi_it.Current(); 4678 PhiInstr* current = phi_it.Current();
4673 if (current->Type()->ToCid() == kSmiCid) { 4679 if (current->Type()->ToCid() == kSmiCid) {
4674 smi_values_.Add(current); 4680 values_.Add(current);
4675 } 4681 }
4676 } 4682 }
4677 } 4683 }
4678 4684
4679 for (ForwardInstructionIterator instr_it(block); 4685 for (ForwardInstructionIterator instr_it(block);
4680 !instr_it.Done(); 4686 !instr_it.Done();
4681 instr_it.Advance()) { 4687 instr_it.Advance()) {
4682 Instruction* current = instr_it.Current(); 4688 Instruction* current = instr_it.Current();
4683 Definition* defn = current->AsDefinition(); 4689 Definition* defn = current->AsDefinition();
4684 if (defn != NULL) { 4690 if (defn != NULL) {
4685 if ((defn->Type()->ToCid() == kSmiCid) && 4691 if ((defn->Type()->ToCid() == kSmiCid) &&
4686 (defn->ssa_temp_index() != -1)) { 4692 (defn->ssa_temp_index() != -1)) {
4687 smi_values_.Add(defn); 4693 values_.Add(defn);
4694 } else if ((defn->IsMintDefinition()) &&
4695 (defn->ssa_temp_index() != -1)) {
4696 values_.Add(defn);
4688 } 4697 }
4689 } else if (current->IsCheckSmi()) { 4698 } else if (current->IsCheckSmi()) {
4690 smi_checks_.Add(current->AsCheckSmi()); 4699 smi_checks_.Add(current->AsCheckSmi());
4691 } 4700 }
4692 } 4701 }
4693 } 4702 }
4694 } 4703 }
4695 4704
4696 4705
4697 // Returns true if use is dominated by the given instruction. 4706 // Returns true if use is dominated by the given instruction.
(...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after
4842 branch->false_successor()); 4851 branch->false_successor());
4843 // Mark false_constraint an artificial use of boundary. This ensures 4852 // Mark false_constraint an artificial use of boundary. This ensures
4844 // that constraint's range is recalculated if boundary's range changes. 4853 // that constraint's range is recalculated if boundary's range changes.
4845 if (false_constraint != NULL) { 4854 if (false_constraint != NULL) {
4846 false_constraint->AddDependency(boundary); 4855 false_constraint->AddDependency(boundary);
4847 false_constraint->set_target(branch->false_successor()); 4856 false_constraint->set_target(branch->false_successor());
4848 } 4857 }
4849 } 4858 }
4850 } 4859 }
4851 4860
4861
4852 void RangeAnalysis::InsertConstraintsFor(Definition* defn) { 4862 void RangeAnalysis::InsertConstraintsFor(Definition* defn) {
4853 for (Value* use = defn->input_use_list(); 4863 for (Value* use = defn->input_use_list();
4854 use != NULL; 4864 use != NULL;
4855 use = use->next_use()) { 4865 use = use->next_use()) {
4856 if (use->instruction()->IsBranch()) { 4866 if (use->instruction()->IsBranch()) {
4857 ConstrainValueAfterBranch(defn, use); 4867 ConstrainValueAfterBranch(defn, use);
4858 } else if (use->instruction()->IsCheckArrayBound()) { 4868 } else if (use->instruction()->IsCheckArrayBound()) {
4859 ConstrainValueAfterCheckArrayBound( 4869 ConstrainValueAfterCheckArrayBound(
4860 defn, 4870 defn,
4861 use->instruction()->AsCheckArrayBound(), 4871 use->instruction()->AsCheckArrayBound(),
(...skipping 18 matching lines...) Expand all
4880 RangeBoundary::FromDefinition(index, 1), 4890 RangeBoundary::FromDefinition(index, 1),
4881 RangeBoundary::MaxSmi()); 4891 RangeBoundary::MaxSmi());
4882 } 4892 }
4883 InsertConstraintFor(defn, constraint_range, check); 4893 InsertConstraintFor(defn, constraint_range, check);
4884 } 4894 }
4885 4895
4886 4896
4887 void RangeAnalysis::InsertConstraints() { 4897 void RangeAnalysis::InsertConstraints() {
4888 for (intptr_t i = 0; i < smi_checks_.length(); i++) { 4898 for (intptr_t i = 0; i < smi_checks_.length(); i++) {
4889 CheckSmiInstr* check = smi_checks_[i]; 4899 CheckSmiInstr* check = smi_checks_[i];
4890 InsertConstraintFor(check->value()->definition(), Range::Unknown(), check); 4900 ConstraintInstr* constraint =
4901 InsertConstraintFor(check->value()->definition(),
4902 Range::UnknownSmi(),
4903 check);
4904 if (constraint == NULL) {
4905 // No constraint was needed.
4906 continue;
4907 }
4908 // Mark the constraint's value's reaching type as smi.
4909 CompileType* smi_compile_type =
4910 ZoneCompileType::Wrap(CompileType::FromCid(kSmiCid));
4911 constraint->value()->SetReachingType(smi_compile_type);
4891 } 4912 }
4892 4913
4893 for (intptr_t i = 0; i < smi_values_.length(); i++) { 4914 for (intptr_t i = 0; i < values_.length(); i++) {
4894 InsertConstraintsFor(smi_values_[i]); 4915 InsertConstraintsFor(values_[i]);
4895 } 4916 }
4896 4917
4897 for (intptr_t i = 0; i < constraints_.length(); i++) { 4918 for (intptr_t i = 0; i < constraints_.length(); i++) {
4898 InsertConstraintsFor(constraints_[i]); 4919 InsertConstraintsFor(constraints_[i]);
4899 } 4920 }
4900 } 4921 }
4901 4922
4902 4923
4903 void RangeAnalysis::ResetWorklist() { 4924 void RangeAnalysis::ResetWorklist() {
4904 if (marked_defns_ == NULL) { 4925 if (marked_defns_ == NULL) {
(...skipping 17 matching lines...) Expand all
4922 } 4943 }
4923 } 4944 }
4924 4945
4925 4946
4926 RangeAnalysis::Direction RangeAnalysis::ToDirection(Value* val) { 4947 RangeAnalysis::Direction RangeAnalysis::ToDirection(Value* val) {
4927 if (val->BindsToConstant()) { 4948 if (val->BindsToConstant()) {
4928 return (Smi::Cast(val->BoundConstant()).Value() >= 0) ? kPositive 4949 return (Smi::Cast(val->BoundConstant()).Value() >= 0) ? kPositive
4929 : kNegative; 4950 : kNegative;
4930 } else if (val->definition()->range() != NULL) { 4951 } else if (val->definition()->range() != NULL) {
4931 Range* range = val->definition()->range(); 4952 Range* range = val->definition()->range();
4932 if (Range::ConstantMin(range).value() >= 0) { 4953 if (Range::ConstantMin(range).ConstantValue() >= 0) {
4933 return kPositive; 4954 return kPositive;
4934 } else if (Range::ConstantMax(range).value() <= 0) { 4955 } else if (Range::ConstantMax(range).ConstantValue() <= 0) {
4935 return kNegative; 4956 return kNegative;
4936 } 4957 }
4937 } 4958 }
4938 return kUnknown; 4959 return kUnknown;
4939 } 4960 }
4940 4961
4941 4962
4942 Range* RangeAnalysis::InferInductionVariableRange(JoinEntryInstr* loop_header, 4963 Range* RangeAnalysis::InferInductionVariableRange(JoinEntryInstr* loop_header,
4943 PhiInstr* var) { 4964 PhiInstr* var) {
4944 BitVector* loop_info = loop_header->loop_info(); 4965 BitVector* loop_info = loop_header->loop_info();
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
5022 case kPositive: 5043 case kPositive:
5023 return new(I) Range(RangeBoundary::FromDefinition(initial_value), 5044 return new(I) Range(RangeBoundary::FromDefinition(initial_value),
5024 RangeBoundary::MaxSmi()); 5045 RangeBoundary::MaxSmi());
5025 5046
5026 case kNegative: 5047 case kNegative:
5027 return new(I) Range(RangeBoundary::MinSmi(), 5048 return new(I) Range(RangeBoundary::MinSmi(),
5028 RangeBoundary::FromDefinition(initial_value)); 5049 RangeBoundary::FromDefinition(initial_value));
5029 5050
5030 case kUnknown: 5051 case kUnknown:
5031 case kBoth: 5052 case kBoth:
5032 return Range::Unknown(); 5053 return Range::UnknownSmi();
5033 } 5054 }
5034 5055
5035 UNREACHABLE(); 5056 UNREACHABLE();
5036 return NULL; 5057 return NULL;
5037 } 5058 }
5038 5059
5039 5060
5040 void RangeAnalysis::InferRangesRecursive(BlockEntryInstr* block) { 5061 void RangeAnalysis::InferRangesRecursive(BlockEntryInstr* block) {
5041 JoinEntryInstr* join = block->AsJoinEntry(); 5062 JoinEntryInstr* join = block->AsJoinEntry();
5042 if (join != NULL) { 5063 if (join != NULL) {
5043 const bool is_loop_header = (join->loop_info() != NULL); 5064 const bool is_loop_header = (join->loop_info() != NULL);
5044 for (PhiIterator it(join); !it.Done(); it.Advance()) { 5065 for (PhiIterator it(join); !it.Done(); it.Advance()) {
5045 PhiInstr* phi = it.Current(); 5066 PhiInstr* phi = it.Current();
5046 if (smi_definitions_->Contains(phi->ssa_temp_index())) { 5067 if (definitions_->Contains(phi->ssa_temp_index())) {
5047 if (is_loop_header) { 5068 if (is_loop_header) {
5048 // Try recognizing simple induction variables. 5069 // Try recognizing simple induction variables.
5049 Range* range = InferInductionVariableRange(join, phi); 5070 Range* range = InferInductionVariableRange(join, phi);
5050 if (range != NULL) { 5071 if (range != NULL) {
5051 phi->range_ = range; 5072 phi->range_ = range;
5052 continue; 5073 continue;
5053 } 5074 }
5054 } 5075 }
5055 5076
5056 phi->InferRange(); 5077 phi->InferRange();
5057 } 5078 }
5058 } 5079 }
5059 } 5080 }
5060 5081
5061 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 5082 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
5062 Instruction* current = it.Current(); 5083 Instruction* current = it.Current();
5063 5084
5064 Definition* defn = current->AsDefinition(); 5085 Definition* defn = current->AsDefinition();
5065 if ((defn != NULL) && 5086 if ((defn != NULL) &&
5066 (defn->ssa_temp_index() != -1) && 5087 (defn->ssa_temp_index() != -1) &&
5067 smi_definitions_->Contains(defn->ssa_temp_index())) { 5088 definitions_->Contains(defn->ssa_temp_index())) {
5068 defn->InferRange(); 5089 defn->InferRange();
5069 } else if (FLAG_array_bounds_check_elimination && 5090 } else if (FLAG_array_bounds_check_elimination &&
5070 current->IsCheckArrayBound()) { 5091 current->IsCheckArrayBound()) {
5071 CheckArrayBoundInstr* check = current->AsCheckArrayBound(); 5092 CheckArrayBoundInstr* check = current->AsCheckArrayBound();
5072 RangeBoundary array_length = 5093 RangeBoundary array_length =
5073 RangeBoundary::FromDefinition(check->length()->definition()); 5094 RangeBoundary::FromDefinition(check->length()->definition());
5074 if (check->IsRedundant(array_length)) { 5095 if (check->IsRedundant(array_length)) {
5075 it.RemoveCurrentFromGraph(); 5096 it.RemoveCurrentFromGraph();
5076 } 5097 }
5077 } 5098 }
5078 } 5099 }
5079 5100
5080 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) { 5101 for (intptr_t i = 0; i < block->dominated_blocks().length(); ++i) {
5081 InferRangesRecursive(block->dominated_blocks()[i]); 5102 InferRangesRecursive(block->dominated_blocks()[i]);
5082 } 5103 }
5083 } 5104 }
5084 5105
5085 5106
5086 void RangeAnalysis::InferRanges() { 5107 void RangeAnalysis::InferRanges() {
5087 // Initialize bitvector for quick filtering of smi values. 5108 if (FLAG_trace_range_analysis) {
5088 smi_definitions_ = new(I) BitVector(flow_graph_->current_ssa_temp_index()); 5109 OS::Print("---- before range analysis -------\n");
5089 for (intptr_t i = 0; i < smi_values_.length(); i++) { 5110 FlowGraphPrinter printer(*flow_graph_);
5090 smi_definitions_->Add(smi_values_[i]->ssa_temp_index()); 5111 printer.PrintBlocks();
5112 }
5113 // Initialize bitvector for quick filtering of int values.
5114 definitions_ =
5115 new(I) BitVector(flow_graph_->current_ssa_temp_index());
5116 for (intptr_t i = 0; i < values_.length(); i++) {
5117 definitions_->Add(values_[i]->ssa_temp_index());
5091 } 5118 }
5092 for (intptr_t i = 0; i < constraints_.length(); i++) { 5119 for (intptr_t i = 0; i < constraints_.length(); i++) {
5093 smi_definitions_->Add(constraints_[i]->ssa_temp_index()); 5120 definitions_->Add(constraints_[i]->ssa_temp_index());
5094 } 5121 }
5095 5122
5096 // Infer initial values of ranges. 5123 // Infer initial values of ranges.
5097 const GrowableArray<Definition*>& initial = 5124 const GrowableArray<Definition*>& initial =
5098 *flow_graph_->graph_entry()->initial_definitions(); 5125 *flow_graph_->graph_entry()->initial_definitions();
5099 for (intptr_t i = 0; i < initial.length(); ++i) { 5126 for (intptr_t i = 0; i < initial.length(); ++i) {
5100 Definition* definition = initial[i]; 5127 Definition* definition = initial[i];
5101 if (smi_definitions_->Contains(definition->ssa_temp_index())) { 5128 if (definitions_->Contains(definition->ssa_temp_index())) {
5102 definition->InferRange(); 5129 definition->InferRange();
5103 } 5130 }
5104 } 5131 }
5105 InferRangesRecursive(flow_graph_->graph_entry()); 5132 InferRangesRecursive(flow_graph_->graph_entry());
5106 5133
5107 if (FLAG_trace_range_analysis) { 5134 if (FLAG_trace_range_analysis) {
5108 OS::Print("---- after range analysis -------\n"); 5135 OS::Print("---- after range analysis -------\n");
5109 FlowGraphPrinter printer(*flow_graph_); 5136 FlowGraphPrinter printer(*flow_graph_);
5110 printer.PrintBlocks(); 5137 printer.PrintBlocks();
5111 } 5138 }
5112 } 5139 }
5113 5140
5114 5141
5115 void RangeAnalysis::RemoveConstraints() { 5142 void RangeAnalysis::RemoveConstraints() {
5116 for (intptr_t i = 0; i < constraints_.length(); i++) { 5143 for (intptr_t i = 0; i < constraints_.length(); i++) {
5117 Definition* def = constraints_[i]->value()->definition(); 5144 Definition* def = constraints_[i]->value()->definition();
5118 // Some constraints might be constraining constraints. Unwind the chain of 5145 // Some constraints might be constraining constraints. Unwind the chain of
5119 // constraints until we reach the actual definition. 5146 // constraints until we reach the actual definition.
5120 while (def->IsConstraint()) { 5147 while (def->IsConstraint()) {
5121 def = def->AsConstraint()->value()->definition(); 5148 def = def->AsConstraint()->value()->definition();
5122 } 5149 }
5123 constraints_[i]->ReplaceUsesWith(def); 5150 constraints_[i]->ReplaceUsesWith(def);
5124 constraints_[i]->RemoveFromGraph(); 5151 constraints_[i]->RemoveFromGraph();
5125 } 5152 }
5126 } 5153 }
5127 5154
5128 5155
5129 void FlowGraphOptimizer::InferSmiRanges() { 5156 void FlowGraphOptimizer::InferIntRanges() {
5130 RangeAnalysis range_analysis(flow_graph_); 5157 RangeAnalysis range_analysis(flow_graph_);
5131 range_analysis.Analyze(); 5158 range_analysis.Analyze();
5132 } 5159 }
5133 5160
5134 5161
5135 void TryCatchAnalyzer::Optimize(FlowGraph* flow_graph) { 5162 void TryCatchAnalyzer::Optimize(FlowGraph* flow_graph) {
5136 // For every catch-block: Iterate over all call instructions inside the 5163 // For every catch-block: Iterate over all call instructions inside the
5137 // corresponding try-block and figure out for each environment value if it 5164 // corresponding try-block and figure out for each environment value if it
5138 // is the same constant at all calls. If yes, replace the initial definition 5165 // is the same constant at all calls. If yes, replace the initial definition
5139 // at the catch-entry with this constant. 5166 // at the catch-entry with this constant.
(...skipping 4663 matching lines...) Expand 10 before | Expand all | Expand 10 after
9803 } 9830 }
9804 9831
9805 // Insert materializations at environment uses. 9832 // Insert materializations at environment uses.
9806 for (intptr_t i = 0; i < exits.length(); i++) { 9833 for (intptr_t i = 0; i < exits.length(); i++) {
9807 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots); 9834 CreateMaterializationAt(exits[i], alloc, alloc->cls(), *slots);
9808 } 9835 }
9809 } 9836 }
9810 9837
9811 9838
9812 } // namespace dart 9839 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | runtime/vm/il_printer.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698