| OLD | NEW |
| 1 // Copyright (c) 2016, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2016, 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/redundancy_elimination.h" | 5 #include "vm/redundancy_elimination.h" |
| 6 | 6 |
| 7 #include "vm/bit_vector.h" | 7 #include "vm/bit_vector.h" |
| 8 #include "vm/flow_graph.h" | 8 #include "vm/flow_graph.h" |
| 9 #include "vm/hash_map.h" | 9 #include "vm/hash_map.h" |
| 10 #include "vm/il_printer.h" | 10 #include "vm/il_printer.h" |
| (...skipping 2329 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2340 a->RemoveFromGraph(); | 2340 a->RemoveFromGraph(); |
| 2341 } | 2341 } |
| 2342 } | 2342 } |
| 2343 | 2343 |
| 2344 return true; | 2344 return true; |
| 2345 } | 2345 } |
| 2346 | 2346 |
| 2347 // Insert the given phi into the graph. Attempt to find an equal one in the | 2347 // Insert the given phi into the graph. Attempt to find an equal one in the |
| 2348 // target block first. | 2348 // target block first. |
| 2349 // Returns true if the phi was inserted and false if it was replaced. | 2349 // Returns true if the phi was inserted and false if it was replaced. |
| 2350 // TODO(fschneider): Generalize this to allow replacing a phi with a non-phi | |
| 2351 // definition as well so that we don't need Phi::HasReplacement anymore. | |
| 2352 bool EmitPhi(PhiInstr* phi) { | 2350 bool EmitPhi(PhiInstr* phi) { |
| 2353 for (PhiIterator it(phi->block()); !it.Done(); it.Advance()) { | 2351 for (PhiIterator it(phi->block()); !it.Done(); it.Advance()) { |
| 2354 if (ReplacePhiWith(phi, it.Current())) { | 2352 if (ReplacePhiWith(phi, it.Current())) { |
| 2355 return false; | 2353 return false; |
| 2356 } | 2354 } |
| 2357 } | 2355 } |
| 2358 | 2356 |
| 2359 phi->mark_alive(); | 2357 phi->mark_alive(); |
| 2360 phi->block()->InsertPhi(phi); | 2358 phi->block()->InsertPhi(phi); |
| 2361 return true; | 2359 return true; |
| (...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3432 it.Advance()) { | 3430 it.Advance()) { |
| 3433 JoinEntryInstr* join = it.Current()->AsJoinEntry(); | 3431 JoinEntryInstr* join = it.Current()->AsJoinEntry(); |
| 3434 if (join != NULL) { | 3432 if (join != NULL) { |
| 3435 if (join->phis_ == NULL) continue; | 3433 if (join->phis_ == NULL) continue; |
| 3436 | 3434 |
| 3437 // Eliminate dead phis and compact the phis_ array of the block. | 3435 // Eliminate dead phis and compact the phis_ array of the block. |
| 3438 intptr_t to_index = 0; | 3436 intptr_t to_index = 0; |
| 3439 for (intptr_t i = 0; i < join->phis_->length(); ++i) { | 3437 for (intptr_t i = 0; i < join->phis_->length(); ++i) { |
| 3440 PhiInstr* phi = (*join->phis_)[i]; | 3438 PhiInstr* phi = (*join->phis_)[i]; |
| 3441 if (phi != NULL) { | 3439 if (phi != NULL) { |
| 3442 Definition* replacement = NULL; | |
| 3443 if (!phi->is_alive()) { | 3440 if (!phi->is_alive()) { |
| 3444 phi->ReplaceUsesWith(flow_graph->constant_null()); | 3441 phi->ReplaceUsesWith(flow_graph->constant_null()); |
| 3445 phi->UnuseAllInputs(); | 3442 phi->UnuseAllInputs(); |
| 3446 (*join->phis_)[i] = NULL; | 3443 (*join->phis_)[i] = NULL; |
| 3447 if (FLAG_trace_optimization) { | 3444 if (FLAG_trace_optimization) { |
| 3448 THR_Print("Removing dead phi v%" Pd "\n", phi->ssa_temp_index()); | 3445 THR_Print("Removing dead phi v%" Pd "\n", phi->ssa_temp_index()); |
| 3449 } | 3446 } |
| 3450 } else if (phi->IsRedundant()) { | 3447 } else if (phi->IsRedundant()) { |
| 3451 phi->ReplaceUsesWith(phi->InputAt(0)->definition()); | 3448 phi->ReplaceUsesWith(phi->InputAt(0)->definition()); |
| 3452 phi->UnuseAllInputs(); | 3449 phi->UnuseAllInputs(); |
| 3453 (*join->phis_)[i] = NULL; | 3450 (*join->phis_)[i] = NULL; |
| 3454 if (FLAG_trace_optimization) { | 3451 if (FLAG_trace_optimization) { |
| 3455 THR_Print("Removing redundant phi v%" Pd "\n", | 3452 THR_Print("Removing redundant phi v%" Pd "\n", |
| 3456 phi->ssa_temp_index()); | 3453 phi->ssa_temp_index()); |
| 3457 } | |
| 3458 } else if (phi->HasReplacement(&replacement)) { | |
| 3459 phi->ReplaceUsesWith(replacement); | |
| 3460 phi->UnuseAllInputs(); | |
| 3461 (*join->phis_)[i] = NULL; | |
| 3462 if (FLAG_trace_optimization) { | |
| 3463 THR_Print("Replace redundant phi v%" Pd " with v%" Pd "\n", | |
| 3464 phi->ssa_temp_index(), | |
| 3465 replacement->ssa_temp_index()); | |
| 3466 } | 3454 } |
| 3467 } else { | 3455 } else { |
| 3468 (*join->phis_)[to_index++] = phi; | 3456 (*join->phis_)[to_index++] = phi; |
| 3469 } | 3457 } |
| 3470 } | 3458 } |
| 3471 } | 3459 } |
| 3472 if (to_index == 0) { | 3460 if (to_index == 0) { |
| 3473 join->phis_ = NULL; | 3461 join->phis_ = NULL; |
| 3474 } else { | 3462 } else { |
| 3475 join->phis_->TruncateTo(to_index); | 3463 join->phis_->TruncateTo(to_index); |
| 3476 } | 3464 } |
| 3477 } | 3465 } |
| 3478 } | 3466 } |
| 3479 } | 3467 } |
| 3480 | 3468 |
| 3481 | 3469 |
| 3482 } // namespace dart | 3470 } // namespace dart |
| OLD | NEW |