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

Unified Diff: runtime/vm/flow_graph_optimizer.cc

Issue 12340108: Remove dead phis as soon as they are discovered. (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 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 side-by-side diff with in-line comments
Download patch
Index: runtime/vm/flow_graph_optimizer.cc
diff --git a/runtime/vm/flow_graph_optimizer.cc b/runtime/vm/flow_graph_optimizer.cc
index 9cc2ec8ce37f5c90a741800473343e3307025d22..ca18612c032aec36b144f0616987ea8627e68525 100644
--- a/runtime/vm/flow_graph_optimizer.cc
+++ b/runtime/vm/flow_graph_optimizer.cc
@@ -383,8 +383,7 @@ void FlowGraphOptimizer::InsertConversionsFor(Definition* def) {
Instruction* deopt_target;
PhiInstr* phi = use->instruction()->AsPhi();
if (phi != NULL) {
- if (!phi->is_alive()) continue;
-
+ ASSERT(phi->is_alive());
// For phis conversions have to be inserted in the predecessor.
insert_before =
phi->block()->PredecessorAt(use->use_index())->last_instruction();
@@ -402,12 +401,10 @@ void FlowGraphOptimizer::SelectRepresentations() {
// Convervatively unbox all phis that were proven to be of type Double.
for (intptr_t i = 0; i < block_order_.length(); ++i) {
JoinEntryInstr* join_entry = block_order_[i]->AsJoinEntry();
- if (join_entry == NULL) continue;
-
- if (join_entry->phis() != NULL) {
- for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
- PhiInstr* phi = (*join_entry->phis())[i];
- if (phi == NULL) continue;
+ if (join_entry != NULL) {
+ for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
+ PhiInstr* phi = it.Current();
+ ASSERT(phi != NULL);
if (phi->Type()->ToCid() == kDoubleCid) {
phi->set_representation(kUnboxedDouble);
}
@@ -425,17 +422,15 @@ void FlowGraphOptimizer::SelectRepresentations() {
for (intptr_t i = 0; i < block_order_.length(); ++i) {
BlockEntryInstr* entry = block_order_[i];
-
JoinEntryInstr* join_entry = entry->AsJoinEntry();
- if ((join_entry != NULL) && (join_entry->phis() != NULL)) {
- for (intptr_t i = 0; i < join_entry->phis()->length(); ++i) {
- PhiInstr* phi = (*join_entry->phis())[i];
- if ((phi != NULL) && (phi->is_alive())) {
- InsertConversionsFor(phi);
- }
+ if (join_entry != NULL) {
+ for (PhiIterator it(join_entry); !it.Done(); it.Advance()) {
+ PhiInstr* phi = it.Current();
+ ASSERT(phi != NULL);
+ ASSERT(phi->is_alive());
+ InsertConversionsFor(phi);
}
}
-
for (ForwardInstructionIterator it(entry); !it.Done(); it.Advance()) {
Definition* def = it.Current()->AsDefinition();
if (def != NULL) {
@@ -2256,8 +2251,7 @@ void RangeAnalysis::RenameDominatedUses(Definition* def,
// Skip dead phis.
PhiInstr* phi = use->instruction()->AsPhi();
- if ((phi != NULL) && !phi->is_alive()) continue;
-
+ ASSERT((phi == NULL) || phi->is_alive());
if (IsDominatedUse(dom, use)) {
use->BindTo(other);
}
@@ -3376,13 +3370,19 @@ class LoadOptimizer : public ValueObject {
return true;
}
- // Emit non-redundant phis created during ComputeOutValues and ForwardLoads.
+ // Phis have not yet been inserted into the graph but they have uses of
+ // their inputs. Insert the non-redundant ones and clear the input uses
+ // of the redundant ones.
void EmitPhis() {
for (intptr_t i = 0; i < phis_.length(); i++) {
PhiInstr* phi = phis_[i];
if ((phi->input_use_list() != NULL) && !EliminateRedundantPhi(phi)) {
phi->mark_alive();
phi->block()->InsertPhi(phi);
+ } else {
+ for (intptr_t j = phi->InputCount() - 1; j >= 0; --j) {
+ phi->InputAt(j)->RemoveFromUseList();
+ }
}
}
}
@@ -4251,41 +4251,47 @@ void ConstantPropagator::Transform() {
// Predecessors will be recomputed (in block id order) after removing
// unreachable code so we merely have to keep the phi inputs in order.
ZoneGrowableArray<PhiInstr*>* phis = join->phis();
- if (phis != NULL) {
+ if ((phis != NULL) && !phis->is_empty()) {
intptr_t pred_count = join->PredecessorCount();
intptr_t live_count = 0;
for (intptr_t pred_idx = 0; pred_idx < pred_count; ++pred_idx) {
if (reachable_->Contains(
join->PredecessorAt(pred_idx)->preorder_number())) {
if (live_count < pred_idx) {
- for (intptr_t phi_idx = 0; phi_idx < phis->length(); ++phi_idx) {
- PhiInstr* phi = (*phis)[phi_idx];
- if (phi == NULL) continue;
+ for (PhiIterator it(join); !it.Done(); it.Advance()) {
+ PhiInstr* phi = it.Current();
+ ASSERT(phi != NULL);
phi->SetInputAt(live_count, phi->InputAt(pred_idx));
}
}
++live_count;
} else {
- for (intptr_t phi_idx = 0; phi_idx < phis->length(); ++phi_idx) {
- PhiInstr* phi = (*phis)[phi_idx];
- if (phi == NULL) continue;
+ for (PhiIterator it(join); !it.Done(); it.Advance()) {
+ PhiInstr* phi = it.Current();
+ ASSERT(phi != NULL);
phi->InputAt(pred_idx)->RemoveFromUseList();
}
}
}
if (live_count < pred_count) {
- for (intptr_t phi_idx = 0; phi_idx < phis->length(); ++phi_idx) {
- PhiInstr* phi = (*phis)[phi_idx];
- if (phi == NULL) continue;
+ intptr_t to_idx = 0;
+ for (intptr_t from_idx = 0; from_idx < phis->length(); ++from_idx) {
+ PhiInstr* phi = (*phis)[from_idx];
+ ASSERT(phi != NULL);
if (FLAG_remove_redundant_phis && (live_count == 1)) {
Vyacheslav Egorov (Google) 2013/02/27 21:53:02 Do we have any code that kills truly redundant phi
Kevin Millikin (Google) 2013/02/28 08:12:02 I don't think so. I wonder, do they arise?
Value* input = phi->InputAt(0);
phi->ReplaceUsesWith(input->definition());
input->RemoveFromUseList();
- (*phis)[phi_idx] = NULL;
} else {
phi->inputs_.TruncateTo(live_count);
+ (*phis)[to_idx++] = phi;
}
}
+ if (to_idx == 0) {
+ join->phis_ = NULL;
+ } else {
+ phis->TruncateTo(to_idx);
+ }
}
}
}

Powered by Google App Engine
This is Rietveld 408576698