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

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

Issue 10939036: A simpler scheme for garbage collection of ureachable phi inputs. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 8 years, 3 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) 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/hash_map.h" 10 #include "vm/hash_map.h"
(...skipping 2365 matching lines...) Expand 10 before | Expand all | Expand 10 after
2376 void ConstantPropagator::Transform() { 2376 void ConstantPropagator::Transform() {
2377 // We will recompute dominators, block ordering, block ids, block last 2377 // We will recompute dominators, block ordering, block ids, block last
2378 // instructions, previous pointers, predecessors, etc. after eliminating 2378 // instructions, previous pointers, predecessors, etc. after eliminating
2379 // unreachable code. We do not maintain those properties during the 2379 // unreachable code. We do not maintain those properties during the
2380 // transformation. 2380 // transformation.
2381 for (BlockIterator b = graph_->reverse_postorder_iterator(); 2381 for (BlockIterator b = graph_->reverse_postorder_iterator();
2382 !b.Done(); 2382 !b.Done();
2383 b.Advance()) { 2383 b.Advance()) {
2384 BlockEntryInstr* block = b.Current(); 2384 BlockEntryInstr* block = b.Current();
2385 if (!reachable_->Contains(block->preorder_number())) { 2385 if (!reachable_->Contains(block->preorder_number())) {
2386 // Remove phi inputs corresponding to unreachable predecessor blocks.
2387 // Predecessors will be recomputed (in block id order) after removing
2388 // unreachable code so we merely have to keep the phi inputs in order.
2389 GotoInstr* jump = block->last_instruction()->AsGoto();
2390 if (jump != NULL) {
2391 JoinEntryInstr* join = jump->successor();
2392 ZoneGrowableArray<PhiInstr*>* phis = join->phis();
2393 if (phis != NULL) {
2394 intptr_t pred_idx = join->IndexOfPredecessor(block);
2395 ASSERT(pred_idx >= 0);
2396 for (intptr_t phi_idx = 0; phi_idx < phis->length(); ++phi_idx) {
2397 PhiInstr* phi = (*phis)[phi_idx];
2398 if (phi == NULL) continue;
2399 phi->RemoveInputAt(pred_idx);
2400 }
2401 }
2402 }
2386 continue; 2403 continue;
2387 } 2404 }
2388 for (ForwardInstructionIterator i(block); !i.Done(); i.Advance()) { 2405 for (ForwardInstructionIterator i(block); !i.Done(); i.Advance()) {
2389 Definition* defn = i.Current()->AsDefinition(); 2406 Definition* defn = i.Current()->AsDefinition();
2390 BranchInstr* branch = i.Current()->AsBranch(); 2407 BranchInstr* branch = i.Current()->AsBranch();
Vyacheslav Egorov (Google) 2012/09/21 12:52:59 I find it very confusing that branch case in insid
Kevin Millikin (Google) 2012/09/21 13:08:04 I'll move it out.
2391 if (defn != NULL) { 2408 if (defn != NULL) {
2392 if (IsConstant(defn->constant_value())) { 2409 if (IsConstant(defn->constant_value())) {
2393 if (!defn->IsConstant() && 2410 if (!defn->IsConstant() &&
2394 !defn->IsPushArgument() && 2411 !defn->IsPushArgument() &&
2395 !defn->IsStoreLocal() && 2412 !defn->IsStoreLocal() &&
2396 !defn->IsStoreIndexed() && 2413 !defn->IsStoreIndexed() &&
2397 !defn->IsStoreInstanceField() && 2414 !defn->IsStoreInstanceField() &&
2398 !defn->IsStoreStaticField() && 2415 !defn->IsStoreStaticField() &&
2399 !defn->IsStoreVMField()) { 2416 !defn->IsStoreVMField()) {
2400 // TODO(kmillikin): propagate constants to replace instructions 2417 // TODO(kmillikin): propagate constants to replace instructions
2401 // without side effects. 2418 // without side effects.
2402 } 2419 }
2403 } 2420 }
2404 } else if (branch != NULL) { 2421 } else if (branch != NULL) {
2405 TargetEntryInstr* if_true = branch->true_successor(); 2422 TargetEntryInstr* if_true = branch->true_successor();
2406 TargetEntryInstr* if_false = branch->false_successor(); 2423 TargetEntryInstr* if_false = branch->false_successor();
2407 JoinEntryInstr* join = NULL; 2424 JoinEntryInstr* join = NULL;
2408 Instruction* next = NULL; 2425 Instruction* next = NULL;
2409 2426
2410 if (!reachable_->Contains(if_true->preorder_number())) { 2427 if (!reachable_->Contains(if_true->preorder_number())) {
2411 ASSERT(reachable_->Contains(if_false->preorder_number())); 2428 ASSERT(reachable_->Contains(if_false->preorder_number()));
2412 ASSERT(branch->comparison()->IsStrictCompare()); 2429 ASSERT(branch->comparison()->IsStrictCompare());
2413 ASSERT(if_false->parallel_move() == NULL); 2430 ASSERT(if_false->parallel_move() == NULL);
2414 ASSERT(if_false->loop_info() == NULL); 2431 ASSERT(if_false->loop_info() == NULL);
2415 join = new JoinEntryInstr(if_false->try_index()); 2432 join =
2433 new JoinEntryInstr(if_false->block_id(), if_false->try_index());
2416 next = if_false->next(); 2434 next = if_false->next();
2417 } else if (!reachable_->Contains(if_false->preorder_number())) { 2435 } else if (!reachable_->Contains(if_false->preorder_number())) {
2418 ASSERT(branch->comparison()->IsStrictCompare()); 2436 ASSERT(branch->comparison()->IsStrictCompare());
2419 ASSERT(if_true->parallel_move() == NULL); 2437 ASSERT(if_true->parallel_move() == NULL);
2420 ASSERT(if_true->loop_info() == NULL); 2438 ASSERT(if_true->loop_info() == NULL);
2421 join = new JoinEntryInstr(if_true->try_index()); 2439 join = new JoinEntryInstr(if_true->block_id(), if_true->try_index());
2422 next = if_true->next(); 2440 next = if_true->next();
2423 } 2441 }
2424 2442
2425 if (join != NULL) { 2443 if (join != NULL) {
2426 // Replace the branch with a jump to the reachable successor. 2444 // Replace the branch with a jump to the reachable successor.
2427 // Drop the comparison, which does not have side effects as long 2445 // Drop the comparison, which does not have side effects as long
2428 // as it is a strict compare (the only one we can determine is 2446 // as it is a strict compare (the only one we can determine is
2429 // constant with the current analysis). 2447 // constant with the current analysis).
2430 GotoInstr* jump = new GotoInstr(join); 2448 GotoInstr* jump = new GotoInstr(join);
2431 // Removing the branch from the graph will leave the iterator in a 2449 // Removing the branch from the graph will leave the iterator in a
2432 // state where current is detached from the graph. Since current 2450 // state where current is detached from the graph. Since current
2433 // has no successors and neither does its replacement, that's 2451 // has no successors and neither does its replacement, that's
2434 // safe. 2452 // safe.
2435 Instruction* previous = branch->previous(); 2453 Instruction* previous = branch->previous();
2436 branch->set_previous(NULL); 2454 branch->set_previous(NULL);
2437 previous->set_next(jump); 2455 previous->set_next(jump);
2438 // Replace the false target entry with the new join entry. We will 2456 // Replace the false target entry with the new join entry. We will
2439 // recompute the dominators after this pass. 2457 // recompute the dominators after this pass.
2440 join->set_next(next); 2458 join->set_next(next);
2441 } 2459 }
2442 } 2460 }
2443 } 2461 }
2444 } 2462 }
2445 graph_->DiscoverBlocks(); 2463 graph_->DiscoverBlocks();
2446 GrowableArray<BitVector*> dominance_frontier; 2464 GrowableArray<BitVector*> dominance_frontier;
2447 graph_->ComputeDominators(&dominance_frontier); 2465 graph_->ComputeDominators(&dominance_frontier);
2448
2449 // Garbage collect phi inputs corresponding to unreachable predecessors.
2450 // This is required because we assume that predecessor and phi indexes
2451 // align. Note that this does not necessarily eliminate all useless phis
2452 // (e.g., it does not eliminate phis that were originally inserted solely
2453 // due to an assignment on the now-unreachable path).
2454 for (BlockIterator it = graph_->reverse_postorder_iterator();
2455 !it.Done();
2456 it.Advance()) {
2457 JoinEntryInstr* join = it.Current()->AsJoinEntry();
2458 if (join != NULL) join->EliminateUnreachablePhiInputs();
2459 }
2460
2461 graph_->ComputeUseLists(); 2466 graph_->ComputeUseLists();
2462 } 2467 }
2463 2468
2464 2469
2465 } // namespace dart 2470 } // namespace dart
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698