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

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

Issue 11638030: When replacing one value with another ensure that replacement has SSA index assigned. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years 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') | no next file » | 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) 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_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/flow_graph_builder.h" 9 #include "vm/flow_graph_builder.h"
10 #include "vm/flow_graph_compiler.h" 10 #include "vm/flow_graph_compiler.h"
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
110 call->deopt_id(), 110 call->deopt_id(),
111 class_ids.length())); 111 class_ids.length()));
112 ic_data.AddReceiverCheck(class_ids[0], function); 112 ic_data.AddReceiverCheck(class_ids[0], function);
113 call->set_ic_data(&ic_data); 113 call->set_ic_data(&ic_data);
114 return true; 114 return true;
115 } 115 }
116 return false; 116 return false;
117 } 117 }
118 118
119 119
120 static void EnsureSSATempIndex(FlowGraph* graph,
121 Definition* defn,
122 Definition* replacement) {
123 if ((replacement->ssa_temp_index() == -1) &&
124 (defn->ssa_temp_index() != -1)) {
125 replacement->set_ssa_temp_index(graph->alloc_ssa_temp_index());
126 }
127 }
128
129
120 static void ReplaceCurrentInstruction(ForwardInstructionIterator* it, 130 static void ReplaceCurrentInstruction(ForwardInstructionIterator* it,
121 Instruction* current, 131 Instruction* current,
122 Instruction* replacement) { 132 Instruction* replacement,
133 FlowGraph* graph) {
123 if ((replacement != NULL) && current->IsDefinition()) { 134 if ((replacement != NULL) && current->IsDefinition()) {
124 Definition* current_defn = current->AsDefinition(); 135 Definition* current_defn = current->AsDefinition();
125 Definition* replacement_defn = replacement->AsDefinition(); 136 Definition* replacement_defn = replacement->AsDefinition();
126 ASSERT(replacement_defn != NULL); 137 ASSERT(replacement_defn != NULL);
127 current_defn->ReplaceUsesWith(replacement_defn); 138 current_defn->ReplaceUsesWith(replacement_defn);
139 EnsureSSATempIndex(graph, current_defn, replacement_defn);
128 140
129 if (FLAG_trace_optimization) { 141 if (FLAG_trace_optimization) {
130 OS::Print("Replacing v%"Pd" with v%"Pd"\n", 142 OS::Print("Replacing v%"Pd" with v%"Pd"\n",
131 current_defn->ssa_temp_index(), 143 current_defn->ssa_temp_index(),
132 replacement_defn->ssa_temp_index()); 144 replacement_defn->ssa_temp_index());
133 } 145 }
134 } else if (FLAG_trace_optimization) { 146 } else if (FLAG_trace_optimization) {
135 ASSERT(!current->IsDefinition() || 147 ASSERT(!current->IsDefinition() ||
136 ((current->AsDefinition()->input_use_list() == NULL) && 148 ((current->AsDefinition()->input_use_list() == NULL) &&
137 (current->AsDefinition()->env_use_list() == NULL))); 149 (current->AsDefinition()->env_use_list() == NULL)));
(...skipping 12 matching lines...) Expand all
150 for (intptr_t i = 0; i < block_order_.length(); ++i) { 162 for (intptr_t i = 0; i < block_order_.length(); ++i) {
151 BlockEntryInstr* entry = block_order_[i]; 163 BlockEntryInstr* entry = block_order_[i];
152 entry->Accept(this); 164 entry->Accept(this);
153 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) { 165 for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
154 Instruction* current = it.Current(); 166 Instruction* current = it.Current();
155 Instruction* replacement = current->Canonicalize(this); 167 Instruction* replacement = current->Canonicalize(this);
156 if (replacement != current) { 168 if (replacement != current) {
157 // For non-definitions Canonicalize should return either NULL or 169 // For non-definitions Canonicalize should return either NULL or
158 // this. 170 // this.
159 ASSERT((replacement == NULL) || current->IsDefinition()); 171 ASSERT((replacement == NULL) || current->IsDefinition());
160 ReplaceCurrentInstruction(&it, current, replacement); 172 ReplaceCurrentInstruction(&it, current, replacement, flow_graph_);
161 } 173 }
162 } 174 }
163 } 175 }
164 } 176 }
165 177
166 178
167 void FlowGraphOptimizer::InsertConversion(Representation from, 179 void FlowGraphOptimizer::InsertConversion(Representation from,
168 Representation to, 180 Representation to,
169 Instruction* instr, 181 Instruction* instr,
170 Value* use, 182 Value* use,
(...skipping 2927 matching lines...) Expand 10 before | Expand all | Expand 10 after
3098 Definition* defn = instr->AsDefinition(); 3110 Definition* defn = instr->AsDefinition();
3099 if ((defn == NULL) || !IsLoadEliminationCandidate(defn)) { 3111 if ((defn == NULL) || !IsLoadEliminationCandidate(defn)) {
3100 continue; 3112 continue;
3101 } 3113 }
3102 3114
3103 const intptr_t expr_id = defn->expr_id(); 3115 const intptr_t expr_id = defn->expr_id();
3104 if (gen->Contains(expr_id)) { 3116 if (gen->Contains(expr_id)) {
3105 // This is a locally redundant load. 3117 // This is a locally redundant load.
3106 ASSERT((out_values != NULL) && ((*out_values)[expr_id] != NULL)); 3118 ASSERT((out_values != NULL) && ((*out_values)[expr_id] != NULL));
3107 3119
3120 Definition* replacement = (*out_values)[expr_id];
3121 EnsureSSATempIndex(graph_, defn, replacement);
3108 if (FLAG_trace_optimization) { 3122 if (FLAG_trace_optimization) {
3109 OS::Print("Replacing load v%"Pd" with v%"Pd"\n", 3123 OS::Print("Replacing load v%"Pd" with v%"Pd"\n",
3110 defn->ssa_temp_index(), 3124 defn->ssa_temp_index(),
3111 (*out_values)[expr_id]->ssa_temp_index()); 3125 replacement->ssa_temp_index());
3112 } 3126 }
3113 3127
3114 defn->ReplaceUsesWith((*out_values)[expr_id]); 3128 defn->ReplaceUsesWith(replacement);
3115 instr_it.RemoveCurrentFromGraph(); 3129 instr_it.RemoveCurrentFromGraph();
3116 continue; 3130 continue;
3117 } else if (!kill->Contains(expr_id)) { 3131 } else if (!kill->Contains(expr_id)) {
3118 // This is an exposed load: it is the first representative of a 3132 // This is an exposed load: it is the first representative of a
3119 // given expression id and it is not killed on the path from 3133 // given expression id and it is not killed on the path from
3120 // the block entry. 3134 // the block entry.
3121 if (exposed_values == NULL) { 3135 if (exposed_values == NULL) {
3122 static const intptr_t kMaxExposedValuesInitialSize = 5; 3136 static const intptr_t kMaxExposedValuesInitialSize = 5;
3123 exposed_values = new ZoneGrowableArray<Definition*>( 3137 exposed_values = new ZoneGrowableArray<Definition*>(
3124 Utils::Minimum(kMaxExposedValuesInitialSize, max_expr_id_)); 3138 Utils::Minimum(kMaxExposedValuesInitialSize, max_expr_id_));
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
3306 Definition* replacement = MergeIncomingValues(block, load->expr_id()); 3320 Definition* replacement = MergeIncomingValues(block, load->expr_id());
3307 3321
3308 // Sets of outgoing values are not linked into use lists so 3322 // Sets of outgoing values are not linked into use lists so
3309 // they might contain values that were replace and removed 3323 // they might contain values that were replace and removed
3310 // from the graph by this iteration. 3324 // from the graph by this iteration.
3311 // To prevent using them we additionally mark definitions themselves 3325 // To prevent using them we additionally mark definitions themselves
3312 // as replaced and store a pointer to the replacement. 3326 // as replaced and store a pointer to the replacement.
3313 replacement = replacement->Replacement(); 3327 replacement = replacement->Replacement();
3314 3328
3315 if (load != replacement) { 3329 if (load != replacement) {
3330 EnsureSSATempIndex(graph_, load, replacement);
3331
3316 if (FLAG_trace_optimization) { 3332 if (FLAG_trace_optimization) {
3317 OS::Print("Replacing load v%"Pd" with v%"Pd"\n", 3333 OS::Print("Replacing load v%"Pd" with v%"Pd"\n",
3318 load->ssa_temp_index(), 3334 load->ssa_temp_index(),
3319 replacement->ssa_temp_index()); 3335 replacement->ssa_temp_index());
3320 } 3336 }
3321 3337
3322 load->ReplaceUsesWith(replacement); 3338 load->ReplaceUsesWith(replacement);
3323 load->RemoveFromGraph(); 3339 load->RemoveFromGraph();
3324 load->SetReplacement(replacement); 3340 load->SetReplacement(replacement);
3325 } 3341 }
(...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after
3442 DirectChainedHashMap<LoadKeyValueTrait> map; 3458 DirectChainedHashMap<LoadKeyValueTrait> map;
3443 const intptr_t max_expr_id = 3459 const intptr_t max_expr_id =
3444 NumberLoadExpressions(graph, &map, &kill_by_offs); 3460 NumberLoadExpressions(graph, &map, &kill_by_offs);
3445 if (max_expr_id > 0) { 3461 if (max_expr_id > 0) {
3446 LoadOptimizer load_optimizer(graph, max_expr_id, &map, kill_by_offs); 3462 LoadOptimizer load_optimizer(graph, max_expr_id, &map, kill_by_offs);
3447 load_optimizer.Optimize(); 3463 load_optimizer.Optimize();
3448 } 3464 }
3449 } 3465 }
3450 3466
3451 DirectChainedHashMap<PointerKeyValueTrait<Instruction> > map; 3467 DirectChainedHashMap<PointerKeyValueTrait<Instruction> > map;
3452 changed = OptimizeRecursive(graph->graph_entry(), &map) || changed; 3468 changed = OptimizeRecursive(graph, graph->graph_entry(), &map) || changed;
3453 3469
3454 return changed; 3470 return changed;
3455 } 3471 }
3456 3472
3457 3473
3458 bool DominatorBasedCSE::OptimizeRecursive( 3474 bool DominatorBasedCSE::OptimizeRecursive(
3475 FlowGraph* graph,
3459 BlockEntryInstr* block, 3476 BlockEntryInstr* block,
3460 DirectChainedHashMap<PointerKeyValueTrait<Instruction> >* map) { 3477 DirectChainedHashMap<PointerKeyValueTrait<Instruction> >* map) {
3461 bool changed = false; 3478 bool changed = false;
3462 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) { 3479 for (ForwardInstructionIterator it(block); !it.Done(); it.Advance()) {
3463 Instruction* current = it.Current(); 3480 Instruction* current = it.Current();
3464 if (current->AffectedBySideEffect()) continue; 3481 if (current->AffectedBySideEffect()) continue;
3465 Instruction* replacement = map->Lookup(current); 3482 Instruction* replacement = map->Lookup(current);
3466 if (replacement == NULL) { 3483 if (replacement == NULL) {
3467 map->Insert(current); 3484 map->Insert(current);
3468 continue; 3485 continue;
3469 } 3486 }
3470 // Replace current with lookup result. 3487 // Replace current with lookup result.
3471 ReplaceCurrentInstruction(&it, current, replacement); 3488 ReplaceCurrentInstruction(&it, current, replacement, graph);
3472 changed = true; 3489 changed = true;
3473 } 3490 }
3474 3491
3475 // Process children in the dominator tree recursively. 3492 // Process children in the dominator tree recursively.
3476 intptr_t num_children = block->dominated_blocks().length(); 3493 intptr_t num_children = block->dominated_blocks().length();
3477 for (intptr_t i = 0; i < num_children; ++i) { 3494 for (intptr_t i = 0; i < num_children; ++i) {
3478 BlockEntryInstr* child = block->dominated_blocks()[i]; 3495 BlockEntryInstr* child = block->dominated_blocks()[i];
3479 if (i < num_children - 1) { 3496 if (i < num_children - 1) {
3480 // Copy map. 3497 // Copy map.
3481 DirectChainedHashMap<PointerKeyValueTrait<Instruction> > child_map(*map); 3498 DirectChainedHashMap<PointerKeyValueTrait<Instruction> > child_map(*map);
3482 changed = OptimizeRecursive(child, &child_map) || changed; 3499 changed = OptimizeRecursive(graph, child, &child_map) || changed;
3483 } else { 3500 } else {
3484 // Reuse map for the last child. 3501 // Reuse map for the last child.
3485 changed = OptimizeRecursive(child, map) || changed; 3502 changed = OptimizeRecursive(graph, child, map) || changed;
3486 } 3503 }
3487 } 3504 }
3488 return changed; 3505 return changed;
3489 } 3506 }
3490 3507
3491 3508
3492 ConstantPropagator::ConstantPropagator( 3509 ConstantPropagator::ConstantPropagator(
3493 FlowGraph* graph, 3510 FlowGraph* graph,
3494 const GrowableArray<BlockEntryInstr*>& ignored) 3511 const GrowableArray<BlockEntryInstr*>& ignored)
3495 : FlowGraphVisitor(ignored), 3512 : FlowGraphVisitor(ignored),
(...skipping 837 matching lines...) Expand 10 before | Expand all | Expand 10 after
4333 4350
4334 if (FLAG_trace_constant_propagation) { 4351 if (FLAG_trace_constant_propagation) {
4335 OS::Print("\n==== After constant propagation ====\n"); 4352 OS::Print("\n==== After constant propagation ====\n");
4336 FlowGraphPrinter printer(*graph_); 4353 FlowGraphPrinter printer(*graph_);
4337 printer.PrintBlocks(); 4354 printer.PrintBlocks();
4338 } 4355 }
4339 } 4356 }
4340 4357
4341 4358
4342 } // namespace dart 4359 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_optimizer.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698