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

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

Issue 10964012: Revert "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
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/growable_array.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) 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 2366 matching lines...) Expand 10 before | Expand all | Expand 10 after
2377 // instructions, previous pointers, predecessors, etc. after eliminating 2377 // instructions, previous pointers, predecessors, etc. after eliminating
2378 // unreachable code. We do not maintain those properties during the 2378 // unreachable code. We do not maintain those properties during the
2379 // transformation. 2379 // transformation.
2380 for (BlockIterator b = graph_->reverse_postorder_iterator(); 2380 for (BlockIterator b = graph_->reverse_postorder_iterator();
2381 !b.Done(); 2381 !b.Done();
2382 b.Advance()) { 2382 b.Advance()) {
2383 BlockEntryInstr* block = b.Current(); 2383 BlockEntryInstr* block = b.Current();
2384 if (!reachable_->Contains(block->preorder_number())) { 2384 if (!reachable_->Contains(block->preorder_number())) {
2385 continue; 2385 continue;
2386 } 2386 }
2387
2388 JoinEntryInstr* join = block->AsJoinEntry();
2389 if (join != NULL) {
2390 // Remove phi inputs corresponding to unreachable predecessor blocks.
2391 // Predecessors will be recomputed (in block id order) after removing
2392 // unreachable code so we merely have to keep the phi inputs in order.
2393 ZoneGrowableArray<PhiInstr*>* phis = join->phis();
2394 if (phis != NULL) {
2395 intptr_t pred_count = join->PredecessorCount();
2396 intptr_t live_count = 0;
2397 for (intptr_t pred_idx = 0; pred_idx < pred_count; ++pred_idx) {
2398 if (reachable_->Contains(
2399 join->PredecessorAt(pred_idx)->preorder_number())) {
2400 if (live_count < pred_idx) {
2401 for (intptr_t phi_idx = 0; phi_idx < phis->length(); ++phi_idx) {
2402 PhiInstr* phi = (*phis)[phi_idx];
2403 if (phi == NULL) continue;
2404 phi->inputs_[live_count] = phi->inputs_[pred_idx];
2405 }
2406 }
2407 ++live_count;
2408 }
2409 }
2410 if (live_count < pred_count) {
2411 for (intptr_t phi_idx = 0; phi_idx < phis->length(); ++phi_idx) {
2412 PhiInstr* phi = (*phis)[phi_idx];
2413 if (phi == NULL) continue;
2414 phi->inputs_.TruncateTo(live_count);
2415 }
2416 }
2417 }
2418 }
2419
2420 for (ForwardInstructionIterator i(block); !i.Done(); i.Advance()) { 2387 for (ForwardInstructionIterator i(block); !i.Done(); i.Advance()) {
2421 Definition* defn = i.Current()->AsDefinition(); 2388 Definition* defn = i.Current()->AsDefinition();
2422 BranchInstr* branch = i.Current()->AsBranch(); 2389 BranchInstr* branch = i.Current()->AsBranch();
2423 if (defn != NULL) { 2390 if (defn != NULL) {
2424 if (IsConstant(defn->constant_value())) { 2391 if (IsConstant(defn->constant_value())) {
2425 if (!defn->IsConstant() && 2392 if (!defn->IsConstant() &&
2426 !defn->IsPushArgument() && 2393 !defn->IsPushArgument() &&
2427 !defn->IsStoreLocal() && 2394 !defn->IsStoreLocal() &&
2428 !defn->IsStoreIndexed() && 2395 !defn->IsStoreIndexed() &&
2429 !defn->IsStoreInstanceField() && 2396 !defn->IsStoreInstanceField() &&
2430 !defn->IsStoreStaticField() && 2397 !defn->IsStoreStaticField() &&
2431 !defn->IsStoreVMField()) { 2398 !defn->IsStoreVMField()) {
2432 // TODO(kmillikin): propagate constants to replace instructions 2399 // TODO(kmillikin): propagate constants to replace instructions
2433 // without side effects. 2400 // without side effects.
2434 } 2401 }
2435 } 2402 }
2436 } else if (branch != NULL) { 2403 } else if (branch != NULL) {
2437 TargetEntryInstr* if_true = branch->true_successor(); 2404 TargetEntryInstr* if_true = branch->true_successor();
2438 TargetEntryInstr* if_false = branch->false_successor(); 2405 TargetEntryInstr* if_false = branch->false_successor();
2439 JoinEntryInstr* join = NULL; 2406 JoinEntryInstr* join = NULL;
2440 Instruction* next = NULL; 2407 Instruction* next = NULL;
2441 2408
2442 if (!reachable_->Contains(if_true->preorder_number())) { 2409 if (!reachable_->Contains(if_true->preorder_number())) {
2443 ASSERT(reachable_->Contains(if_false->preorder_number())); 2410 ASSERT(reachable_->Contains(if_false->preorder_number()));
2444 ASSERT(branch->comparison()->IsStrictCompare()); 2411 ASSERT(branch->comparison()->IsStrictCompare());
2445 ASSERT(if_false->parallel_move() == NULL); 2412 ASSERT(if_false->parallel_move() == NULL);
2446 ASSERT(if_false->loop_info() == NULL); 2413 ASSERT(if_false->loop_info() == NULL);
2447 join = 2414 join = new JoinEntryInstr(if_false->try_index());
2448 new JoinEntryInstr(if_false->block_id(), if_false->try_index());
2449 next = if_false->next(); 2415 next = if_false->next();
2450 } else if (!reachable_->Contains(if_false->preorder_number())) { 2416 } else if (!reachable_->Contains(if_false->preorder_number())) {
2451 ASSERT(branch->comparison()->IsStrictCompare()); 2417 ASSERT(branch->comparison()->IsStrictCompare());
2452 ASSERT(if_true->parallel_move() == NULL); 2418 ASSERT(if_true->parallel_move() == NULL);
2453 ASSERT(if_true->loop_info() == NULL); 2419 ASSERT(if_true->loop_info() == NULL);
2454 join = new JoinEntryInstr(if_true->block_id(), if_true->try_index()); 2420 join = new JoinEntryInstr(if_true->try_index());
2455 next = if_true->next(); 2421 next = if_true->next();
2456 } 2422 }
2457 2423
2458 if (join != NULL) { 2424 if (join != NULL) {
2459 // Replace the branch with a jump to the reachable successor. 2425 // Replace the branch with a jump to the reachable successor.
2460 // Drop the comparison, which does not have side effects as long 2426 // Drop the comparison, which does not have side effects as long
2461 // as it is a strict compare (the only one we can determine is 2427 // as it is a strict compare (the only one we can determine is
2462 // constant with the current analysis). 2428 // constant with the current analysis).
2463 GotoInstr* jump = new GotoInstr(join); 2429 GotoInstr* jump = new GotoInstr(join);
2464 // Removing the branch from the graph will leave the iterator in a 2430 // Removing the branch from the graph will leave the iterator in a
2465 // state where current is detached from the graph. Since current 2431 // state where current is detached from the graph. Since current
2466 // has no successors and neither does its replacement, that's 2432 // has no successors and neither does its replacement, that's
2467 // safe. 2433 // safe.
2468 Instruction* previous = branch->previous(); 2434 Instruction* previous = branch->previous();
2469 branch->set_previous(NULL); 2435 branch->set_previous(NULL);
2470 previous->set_next(jump); 2436 previous->set_next(jump);
2471 // Replace the false target entry with the new join entry. We will 2437 // Replace the false target entry with the new join entry. We will
2472 // recompute the dominators after this pass. 2438 // recompute the dominators after this pass.
2473 join->set_next(next); 2439 join->set_next(next);
2474 } 2440 }
2475 } 2441 }
2476 } 2442 }
2477 } 2443 }
2478 graph_->DiscoverBlocks(); 2444 graph_->DiscoverBlocks();
2479 GrowableArray<BitVector*> dominance_frontier; 2445 GrowableArray<BitVector*> dominance_frontier;
2480 graph_->ComputeDominators(&dominance_frontier); 2446 graph_->ComputeDominators(&dominance_frontier);
2447
2448 // Garbage collect phi inputs corresponding to unreachable predecessors.
2449 // This is required because we assume that predecessor and phi indexes
2450 // align. Note that this does not necessarily eliminate all useless phis
2451 // (e.g., it does not eliminate phis that were originally inserted solely
2452 // due to an assignment on the now-unreachable path).
2453 for (BlockIterator it = graph_->reverse_postorder_iterator();
2454 !it.Done();
2455 it.Advance()) {
2456 JoinEntryInstr* join = it.Current()->AsJoinEntry();
2457 if (join != NULL) join->EliminateUnreachablePhiInputs();
2458 }
2459
2481 graph_->ComputeUseLists(); 2460 graph_->ComputeUseLists();
2482 } 2461 }
2483 2462
2484 2463
2485 } // namespace dart 2464 } // namespace dart
OLDNEW
« no previous file with comments | « runtime/vm/flow_graph_builder.cc ('k') | runtime/vm/growable_array.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698