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

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

Issue 1695253002: VM: Use BlockIterator in the optimizer consistently for iterating the flow graph (Closed) Base URL: git@github.com:dart-lang/sdk.git@master
Patch Set: Created 4 years, 10 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
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.h » ('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/branch_optimizer.h" 8 #include "vm/branch_optimizer.h"
9 #include "vm/cha.h" 9 #include "vm/cha.h"
10 #include "vm/compiler.h" 10 #include "vm/compiler.h"
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
81 81
82 82
83 // Optimize instance calls using ICData. 83 // Optimize instance calls using ICData.
84 void FlowGraphOptimizer::ApplyICData() { 84 void FlowGraphOptimizer::ApplyICData() {
85 VisitBlocks(); 85 VisitBlocks();
86 } 86 }
87 87
88 88
89 void FlowGraphOptimizer::PopulateWithICData() { 89 void FlowGraphOptimizer::PopulateWithICData() {
90 ASSERT(current_iterator_ == NULL); 90 ASSERT(current_iterator_ == NULL);
91 for (intptr_t i = 0; i < block_order_.length(); ++i) { 91 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
92 BlockEntryInstr* entry = block_order_[i]; 92 !block_it.Done();
93 ForwardInstructionIterator it(entry); 93 block_it.Advance()) {
94 ForwardInstructionIterator it(block_it.Current());
94 for (; !it.Done(); it.Advance()) { 95 for (; !it.Done(); it.Advance()) {
95 Instruction* instr = it.Current(); 96 Instruction* instr = it.Current();
96 if (instr->IsInstanceCall()) { 97 if (instr->IsInstanceCall()) {
97 InstanceCallInstr* call = instr->AsInstanceCall(); 98 InstanceCallInstr* call = instr->AsInstanceCall();
98 if (!call->HasICData()) { 99 if (!call->HasICData()) {
99 const Array& arguments_descriptor = 100 const Array& arguments_descriptor =
100 Array::Handle(zone(), 101 Array::Handle(zone(),
101 ArgumentsDescriptor::New(call->ArgumentCount(), 102 ArgumentsDescriptor::New(call->ArgumentCount(),
102 call->argument_names())); 103 call->argument_names()));
103 const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New( 104 const ICData& ic_data = ICData::ZoneHandle(zone(), ICData::New(
(...skipping 10 matching lines...) Expand all
114 115
115 116
116 // Optimize instance calls using cid. This is called after optimizer 117 // Optimize instance calls using cid. This is called after optimizer
117 // converted instance calls to instructions. Any remaining 118 // converted instance calls to instructions. Any remaining
118 // instance calls are either megamorphic calls, cannot be optimized or 119 // instance calls are either megamorphic calls, cannot be optimized or
119 // have no runtime type feedback collected. 120 // have no runtime type feedback collected.
120 // Attempts to convert an instance call (IC call) using propagated class-ids, 121 // Attempts to convert an instance call (IC call) using propagated class-ids,
121 // e.g., receiver class id, guarded-cid, or by guessing cid-s. 122 // e.g., receiver class id, guarded-cid, or by guessing cid-s.
122 void FlowGraphOptimizer::ApplyClassIds() { 123 void FlowGraphOptimizer::ApplyClassIds() {
123 ASSERT(current_iterator_ == NULL); 124 ASSERT(current_iterator_ == NULL);
124 for (intptr_t i = 0; i < block_order_.length(); ++i) { 125 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
125 BlockEntryInstr* entry = block_order_[i]; 126 !block_it.Done();
126 ForwardInstructionIterator it(entry); 127 block_it.Advance()) {
128 ForwardInstructionIterator it(block_it.Current());
127 current_iterator_ = &it; 129 current_iterator_ = &it;
128 for (; !it.Done(); it.Advance()) { 130 for (; !it.Done(); it.Advance()) {
129 Instruction* instr = it.Current(); 131 Instruction* instr = it.Current();
130 if (instr->IsInstanceCall()) { 132 if (instr->IsInstanceCall()) {
131 InstanceCallInstr* call = instr->AsInstanceCall(); 133 InstanceCallInstr* call = instr->AsInstanceCall();
132 if (call->HasICData()) { 134 if (call->HasICData()) {
133 if (TryCreateICData(call)) { 135 if (TryCreateICData(call)) {
134 VisitInstanceCall(call); 136 VisitInstanceCall(call);
135 } 137 }
136 } 138 }
(...skipping 412 matching lines...) Expand 10 before | Expand all | Expand 10 after
549 551
550 552
551 // Optimize (a << b) & c pattern: if c is a positive Smi or zero, then the 553 // Optimize (a << b) & c pattern: if c is a positive Smi or zero, then the
552 // shift can be a truncating Smi shift-left and result is always Smi. 554 // shift can be a truncating Smi shift-left and result is always Smi.
553 // Merging occurs only per basic-block. 555 // Merging occurs only per basic-block.
554 void FlowGraphOptimizer::TryOptimizePatterns() { 556 void FlowGraphOptimizer::TryOptimizePatterns() {
555 if (!FLAG_truncating_left_shift) return; 557 if (!FLAG_truncating_left_shift) return;
556 ASSERT(current_iterator_ == NULL); 558 ASSERT(current_iterator_ == NULL);
557 GrowableArray<BinarySmiOpInstr*> div_mod_merge; 559 GrowableArray<BinarySmiOpInstr*> div_mod_merge;
558 GrowableArray<MathUnaryInstr*> sin_cos_merge; 560 GrowableArray<MathUnaryInstr*> sin_cos_merge;
559 for (intptr_t i = 0; i < block_order_.length(); ++i) { 561 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
562 !block_it.Done();
563 block_it.Advance()) {
560 // Merging only per basic-block. 564 // Merging only per basic-block.
561 div_mod_merge.Clear(); 565 div_mod_merge.Clear();
562 sin_cos_merge.Clear(); 566 sin_cos_merge.Clear();
563 BlockEntryInstr* entry = block_order_[i]; 567 ForwardInstructionIterator it(block_it.Current());
564 ForwardInstructionIterator it(entry);
565 current_iterator_ = &it; 568 current_iterator_ = &it;
566 for (; !it.Done(); it.Advance()) { 569 for (; !it.Done(); it.Advance()) {
567 if (it.Current()->IsBinarySmiOp()) { 570 if (it.Current()->IsBinarySmiOp()) {
568 BinarySmiOpInstr* binop = it.Current()->AsBinarySmiOp(); 571 BinarySmiOpInstr* binop = it.Current()->AsBinarySmiOp();
569 if (binop->op_kind() == Token::kBIT_AND) { 572 if (binop->op_kind() == Token::kBIT_AND) {
570 OptimizeLeftShiftBitAndSmiOp(binop, 573 OptimizeLeftShiftBitAndSmiOp(binop,
571 binop->left()->definition(), 574 binop->left()->definition(),
572 binop->right()->definition()); 575 binop->right()->definition());
573 } else if ((binop->op_kind() == Token::kTRUNCDIV) || 576 } else if ((binop->op_kind() == Token::kTRUNCDIV) ||
574 (binop->op_kind() == Token::kMOD)) { 577 (binop->op_kind() == Token::kMOD)) {
(...skipping 20 matching lines...) Expand all
595 } 598 }
596 TryMergeTruncDivMod(&div_mod_merge); 599 TryMergeTruncDivMod(&div_mod_merge);
597 TryMergeMathUnary(&sin_cos_merge); 600 TryMergeMathUnary(&sin_cos_merge);
598 current_iterator_ = NULL; 601 current_iterator_ = NULL;
599 } 602 }
600 } 603 }
601 604
602 605
603 bool FlowGraphOptimizer::Canonicalize() { 606 bool FlowGraphOptimizer::Canonicalize() {
604 bool changed = false; 607 bool changed = false;
605 for (intptr_t i = 0; i < block_order_.length(); ++i) { 608
606 BlockEntryInstr* entry = block_order_[i]; 609 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
607 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 610 !block_it.Done();
611 block_it.Advance()) {
612 for (ForwardInstructionIterator it(block_it.Current());
613 !it.Done();
614 it.Advance()) {
608 Instruction* current = it.Current(); 615 Instruction* current = it.Current();
609 if (current->HasUnmatchedInputRepresentations()) { 616 if (current->HasUnmatchedInputRepresentations()) {
610 // Can't canonicalize this instruction until all conversions for its 617 // Can't canonicalize this instruction until all conversions for its
611 // inputs are inserted. 618 // inputs are inserted.
612 continue; 619 continue;
613 } 620 }
614 621
615 Instruction* replacement = current->Canonicalize(flow_graph()); 622 Instruction* replacement = current->Canonicalize(flow_graph());
616 623
617 if (replacement != current) { 624 if (replacement != current) {
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
829 } 836 }
830 } 837 }
831 838
832 phi->set_representation(unboxed); 839 phi->set_representation(unboxed);
833 } 840 }
834 841
835 842
836 void FlowGraphOptimizer::SelectRepresentations() { 843 void FlowGraphOptimizer::SelectRepresentations() {
837 // Conservatively unbox all phis that were proven to be of Double, 844 // Conservatively unbox all phis that were proven to be of Double,
838 // Float32x4, or Int32x4 type. 845 // Float32x4, or Int32x4 type.
839 for (intptr_t i = 0; i < block_order_.length(); ++i) { 846 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
840 JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry(); 847 !block_it.Done();
848 block_it.Advance()) {
849 JoinEntryInstr* join_entry = block_it.Current()->AsJoinEntry();
841 if (join_entry != NULL) { 850 if (join_entry != NULL) {
842 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) { 851 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
843 PhiInstr* phi = it.Current(); 852 PhiInstr* phi = it.Current();
844 UnboxPhi(phi); 853 UnboxPhi(phi);
845 } 854 }
846 } 855 }
847 } 856 }
848 857
849 // Process all instructions and insert conversions where needed. 858 // Process all instructions and insert conversions where needed.
850 GraphEntryInstr* graph_entry = block_order_[0]->AsGraphEntry(); 859 GraphEntryInstr* graph_entry = flow_graph_->graph_entry();
851 860
852 // Visit incoming parameters and constants. 861 // Visit incoming parameters and constants.
853 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) { 862 for (intptr_t i = 0; i < graph_entry->initial_definitions()->length(); i++) {
854 InsertConversionsFor((*graph_entry->initial_definitions())[i]); 863 InsertConversionsFor((*graph_entry->initial_definitions())[i]);
855 } 864 }
856 865
857 for (intptr_t i = 0; i < block_order_.length(); ++i) { 866 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
858 BlockEntryInstr* entry = block_order_[i]; 867 !block_it.Done();
868 block_it.Advance()) {
869 BlockEntryInstr* entry = block_it.Current();
859 JoinEntryInstr* join_entry = entry->AsJoinEntry(); 870 JoinEntryInstr* join_entry = entry->AsJoinEntry();
860 if (join_entry != NULL) { 871 if (join_entry != NULL) {
861 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) { 872 for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
862 PhiInstr* phi = it.Current(); 873 PhiInstr* phi = it.Current();
863 ASSERT(phi != NULL); 874 ASSERT(phi != NULL);
864 ASSERT(phi->is_alive()); 875 ASSERT(phi->is_alive());
865 InsertConversionsFor(phi); 876 InsertConversionsFor(phi);
866 } 877 }
867 } 878 }
868 CatchBlockEntryInstr* catch_entry = entry->AsCatchBlockEntry(); 879 CatchBlockEntryInstr* catch_entry = entry->AsCatchBlockEntry();
(...skipping 3069 matching lines...) Expand 10 before | Expand all | Expand 10 after
3938 // save enough range information in the ICData to drive this decision. 3949 // save enough range information in the ICData to drive this decision.
3939 } 3950 }
3940 #endif 3951 #endif
3941 3952
3942 3953
3943 void FlowGraphOptimizer::EliminateEnvironments() { 3954 void FlowGraphOptimizer::EliminateEnvironments() {
3944 // After this pass we can no longer perform LICM and hoist instructions 3955 // After this pass we can no longer perform LICM and hoist instructions
3945 // that can deoptimize. 3956 // that can deoptimize.
3946 3957
3947 flow_graph_->disallow_licm(); 3958 flow_graph_->disallow_licm();
3948 for (intptr_t i = 0; i < block_order_.length(); ++i) { 3959 for (BlockIterator block_it = flow_graph_->reverse_postorder_iterator();
3949 BlockEntryInstr* block = block_order_[i]; 3960 !block_it.Done();
3961 block_it.Advance()) {
3962 BlockEntryInstr* block = block_it.Current();
3950 block->RemoveEnvironment(); 3963 block->RemoveEnvironment();
3951 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 3964 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
3952 Instruction* current = it.Current(); 3965 Instruction* current = it.Current();
3953 if (!current->CanDeoptimize()) { 3966 if (!current->CanDeoptimize()) {
3954 // TODO(srdjan): --source-lines needs deopt environments to get at 3967 // TODO(srdjan): --source-lines needs deopt environments to get at
3955 // the code for this instruction, however, leaving the environment 3968 // the code for this instruction, however, leaving the environment
3956 // changes code. 3969 // changes code.
3957 current->RemoveEnvironment(); 3970 current->RemoveEnvironment();
3958 } 3971 }
3959 } 3972 }
3960 } 3973 }
3961 } 3974 }
3962 3975
3963 3976
3964 } // namespace dart 3977 } // namespace dart
OLDNEW
« no previous file with comments | « no previous file | runtime/vm/intermediate_language.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698