Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index f6c47f31dbe83934de00a230eb9099fc12dcacf0..20e84033ce683ecc63c7ec73475beb13409afaf6 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -644,7 +644,7 @@ void HGraph::Canonicalize() { |
HInstruction* instr = blocks()->at(i)->first(); |
while (instr != NULL) { |
HValue* value = instr->Canonicalize(); |
- if (value != instr) instr->ReplaceAndDelete(value); |
+ if (value != instr) instr->DeleteAndReplaceWith(value); |
instr = instr->next(); |
} |
} |
@@ -726,9 +726,9 @@ void HGraph::AssignDominators() { |
void HGraph::EliminateRedundantPhis() { |
HPhase phase("Redundant phi elimination", this); |
- // Worklist of phis that can potentially be eliminated. Initialized |
- // with all phi nodes. When elimination of a phi node modifies |
- // another phi node the modified phi node is added to the worklist. |
+ // Worklist of phis that can potentially be eliminated. Initialized with |
+ // all phi nodes. When elimination of a phi node modifies another phi node |
+ // the modified phi node is added to the worklist. |
ZoneList<HPhi*> worklist(blocks_.length()); |
for (int i = 0; i < blocks_.length(); ++i) { |
worklist.AddAll(*blocks_[i]->phis()); |
@@ -742,18 +742,14 @@ void HGraph::EliminateRedundantPhis() { |
if (block == NULL) continue; |
// Get replacement value if phi is redundant. |
- HValue* value = phi->GetRedundantReplacement(); |
- |
- if (value != NULL) { |
- // Iterate through uses finding the ones that should be |
- // replaced. |
- SmallPointerList<HValue>* uses = phi->uses(); |
- while (!uses->is_empty()) { |
- HValue* use = uses->RemoveLast(); |
- if (use != NULL) { |
- phi->ReplaceAtUse(use, value); |
- if (use->IsPhi()) worklist.Add(HPhi::cast(use)); |
- } |
+ HValue* replacement = phi->GetRedundantReplacement(); |
+ |
+ if (replacement != NULL) { |
+ // Iterate through the uses and replace them all. |
+ for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
+ HValue* value = it.value(); |
+ value->SetOperandAt(it.index(), replacement); |
+ if (value->IsPhi()) worklist.Add(HPhi::cast(value)); |
} |
block->RemovePhi(phi); |
} |
@@ -831,8 +827,8 @@ void HGraph::InferTypes(ZoneList<HValue*>* worklist) { |
HValue* current = worklist->RemoveLast(); |
in_worklist.Remove(current->id()); |
if (current->UpdateInferredType()) { |
- for (int j = 0; j < current->uses()->length(); j++) { |
- HValue* use = current->uses()->at(j); |
+ for (HUseIterator it(current->uses()); !it.Done(); it.Advance()) { |
+ HValue* use = it.value(); |
if (!in_worklist.Contains(use->id())) { |
in_worklist.Add(use->id()); |
worklist->Add(use); |
@@ -1445,7 +1441,7 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { |
instr->Mnemonic(), |
other->id(), |
other->Mnemonic()); |
- instr->ReplaceAndDelete(other); |
+ instr->DeleteAndReplaceWith(other); |
} else { |
map->Add(instr); |
} |
@@ -1529,12 +1525,12 @@ void HInferRepresentation::InferBasedOnInputs(HValue* current) { |
} |
-void HInferRepresentation::AddDependantsToWorklist(HValue* current) { |
- for (int i = 0; i < current->uses()->length(); ++i) { |
- AddToWorklist(current->uses()->at(i)); |
+void HInferRepresentation::AddDependantsToWorklist(HValue* value) { |
+ for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) { |
+ AddToWorklist(it.value()); |
} |
- for (int i = 0; i < current->OperandCount(); ++i) { |
- AddToWorklist(current->OperandAt(i)); |
+ for (int i = 0; i < value->OperandCount(); ++i) { |
+ AddToWorklist(value->OperandAt(i)); |
} |
} |
@@ -1543,37 +1539,30 @@ void HInferRepresentation::AddDependantsToWorklist(HValue* current) { |
// given as the parameter has a benefit in terms of less necessary type |
// conversions. If there is a benefit, then the representation of the value is |
// specialized. |
-void HInferRepresentation::InferBasedOnUses(HValue* current) { |
- Representation r = current->representation(); |
- if (r.IsSpecialization() || current->HasNoUses()) return; |
- ASSERT(current->CheckFlag(HValue::kFlexibleRepresentation)); |
- Representation new_rep = TryChange(current); |
+void HInferRepresentation::InferBasedOnUses(HValue* value) { |
+ Representation r = value->representation(); |
+ if (r.IsSpecialization() || value->HasNoUses()) return; |
+ ASSERT(value->CheckFlag(HValue::kFlexibleRepresentation)); |
+ Representation new_rep = TryChange(value); |
if (!new_rep.IsNone()) { |
- if (!current->representation().Equals(new_rep)) { |
- current->ChangeRepresentation(new_rep); |
- AddDependantsToWorklist(current); |
+ if (!value->representation().Equals(new_rep)) { |
+ value->ChangeRepresentation(new_rep); |
+ AddDependantsToWorklist(value); |
} |
} |
} |
-Representation HInferRepresentation::TryChange(HValue* current) { |
+Representation HInferRepresentation::TryChange(HValue* value) { |
// Array of use counts for each representation. |
- int use_count[Representation::kNumRepresentations]; |
- for (int i = 0; i < Representation::kNumRepresentations; i++) { |
- use_count[i] = 0; |
- } |
+ int use_count[Representation::kNumRepresentations] = { 0 }; |
- for (int i = 0; i < current->uses()->length(); ++i) { |
- HValue* use = current->uses()->at(i); |
- int index = use->LookupOperandIndex(0, current); |
- Representation req_rep = use->RequiredInputRepresentation(index); |
- if (req_rep.IsNone()) continue; |
- if (use->IsPhi()) { |
- HPhi* phi = HPhi::cast(use); |
- phi->AddIndirectUsesTo(&use_count[0]); |
- } |
- use_count[req_rep.kind()]++; |
+ for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) { |
+ HValue* use = it.value(); |
+ Representation rep = use->RequiredInputRepresentation(it.index()); |
+ if (rep.IsNone()) continue; |
+ if (use->IsPhi()) HPhi::cast(use)->AddIndirectUsesTo(&use_count[0]); |
+ ++use_count[rep.kind()]; |
} |
int tagged_count = use_count[Representation::kTagged]; |
int double_count = use_count[Representation::kDouble]; |
@@ -1581,7 +1570,7 @@ Representation HInferRepresentation::TryChange(HValue* current) { |
int non_tagged_count = double_count + int32_count; |
// If a non-loop phi has tagged uses, don't convert it to untagged. |
- if (current->IsPhi() && !current->block()->IsLoopHeader()) { |
+ if (value->IsPhi() && !value->block()->IsLoopHeader()) { |
if (tagged_count > 0) return Representation::None(); |
} |
@@ -1602,41 +1591,39 @@ Representation HInferRepresentation::TryChange(HValue* current) { |
void HInferRepresentation::Analyze() { |
HPhase phase("Infer representations", graph_); |
- // (1) Initialize bit vectors and count real uses. Each phi |
- // gets a bit-vector of length <number of phis>. |
+ // (1) Initialize bit vectors and count real uses. Each phi gets a |
+ // bit-vector of length <number of phis>. |
const ZoneList<HPhi*>* phi_list = graph_->phi_list(); |
- int num_phis = phi_list->length(); |
- ScopedVector<BitVector*> connected_phis(num_phis); |
- for (int i = 0; i < num_phis; i++) { |
+ int phi_count = phi_list->length(); |
+ ScopedVector<BitVector*> connected_phis(phi_count); |
+ for (int i = 0; i < phi_count; ++i) { |
phi_list->at(i)->InitRealUses(i); |
- connected_phis[i] = new(zone()) BitVector(num_phis); |
+ connected_phis[i] = new(zone()) BitVector(phi_count); |
connected_phis[i]->Add(i); |
} |
- // (2) Do a fixed point iteration to find the set of connected phis. |
- // A phi is connected to another phi if its value is used either |
- // directly or indirectly through a transitive closure of the def-use |
- // relation. |
+ // (2) Do a fixed point iteration to find the set of connected phis. A |
+ // phi is connected to another phi if its value is used either directly or |
+ // indirectly through a transitive closure of the def-use relation. |
bool change = true; |
while (change) { |
change = false; |
- for (int i = 0; i < num_phis; i++) { |
+ for (int i = 0; i < phi_count; ++i) { |
HPhi* phi = phi_list->at(i); |
- for (int j = 0; j < phi->uses()->length(); j++) { |
- HValue* use = phi->uses()->at(j); |
+ for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
+ HValue* use = it.value(); |
if (use->IsPhi()) { |
- int phi_use = HPhi::cast(use)->phi_id(); |
- if (connected_phis[i]->UnionIsChanged(*connected_phis[phi_use])) { |
- change = true; |
- } |
+ int id = HPhi::cast(use)->phi_id(); |
+ change = change || |
+ connected_phis[i]->UnionIsChanged(*connected_phis[id]); |
} |
} |
} |
} |
- // (3) Sum up the non-phi use counts of all connected phis. |
- // Don't include the non-phi uses of the phi itself. |
- for (int i = 0; i < num_phis; i++) { |
+ // (3) Sum up the non-phi use counts of all connected phis. Don't include |
+ // the non-phi uses of the phi itself. |
+ for (int i = 0; i < phi_count; ++i) { |
HPhi* phi = phi_list->at(i); |
for (BitVector::Iterator it(connected_phis.at(i)); |
!it.Done(); |
@@ -1746,17 +1733,16 @@ void HGraph::PropagateMinusZeroChecks(HValue* value, BitVector* visited) { |
void HGraph::InsertRepresentationChangeForUse(HValue* value, |
- HValue* use, |
+ HValue* use_value, |
+ int use_index, |
Representation to) { |
// Insert the representation change right before its use. For phi-uses we |
// insert at the end of the corresponding predecessor. |
HInstruction* next = NULL; |
- if (use->IsPhi()) { |
- int index = 0; |
- while (use->OperandAt(index) != value) ++index; |
- next = use->block()->predecessors()->at(index)->end(); |
+ if (use_value->IsPhi()) { |
+ next = use_value->block()->predecessors()->at(use_index)->end(); |
} else { |
- next = HInstruction::cast(use); |
+ next = HInstruction::cast(use_value); |
} |
// For constants we try to make the representation change at compile |
@@ -1764,7 +1750,7 @@ void HGraph::InsertRepresentationChangeForUse(HValue* value, |
// information we treat constants like normal instructions and insert the |
// change instructions for them. |
HInstruction* new_value = NULL; |
- bool is_truncating = use->CheckFlag(HValue::kTruncatingToInt32); |
+ bool is_truncating = use_value->CheckFlag(HValue::kTruncatingToInt32); |
if (value->IsConstant()) { |
HConstant* constant = HConstant::cast(value); |
// Try to create a new copy of the constant with the new representation. |
@@ -1779,89 +1765,26 @@ void HGraph::InsertRepresentationChangeForUse(HValue* value, |
} |
new_value->InsertBefore(next); |
- value->ReplaceFirstAtUse(use, new_value, to); |
-} |
- |
- |
-int CompareConversionUses(HValue* a, |
- HValue* b, |
- Representation a_rep, |
- Representation b_rep) { |
- if (a_rep.kind() > b_rep.kind()) { |
- // Make sure specializations are separated in the result array. |
- return 1; |
- } |
- // Put truncating conversions before non-truncating conversions. |
- bool a_truncate = a->CheckFlag(HValue::kTruncatingToInt32); |
- bool b_truncate = b->CheckFlag(HValue::kTruncatingToInt32); |
- if (a_truncate != b_truncate) { |
- return a_truncate ? -1 : 1; |
- } |
- // Sort by increasing block ID. |
- return a->block()->block_id() - b->block()->block_id(); |
+ use_value->SetOperandAt(use_index, new_value); |
} |
-void HGraph::InsertRepresentationChangesForValue( |
- HValue* current, |
- ZoneList<HValue*>* to_convert, |
- ZoneList<Representation>* to_convert_reps) { |
- Representation r = current->representation(); |
+void HGraph::InsertRepresentationChangesForValue(HValue* value) { |
+ Representation r = value->representation(); |
if (r.IsNone()) return; |
- if (current->uses()->is_empty()) return; |
- |
- // Collect the representation changes in a sorted list. This allows |
- // us to avoid duplicate changes without searching the list. |
- ASSERT(to_convert->is_empty()); |
- ASSERT(to_convert_reps->is_empty()); |
- for (int i = 0; i < current->uses()->length(); ++i) { |
- HValue* use = current->uses()->at(i); |
- // The occurrences index means the index within the operand array of "use" |
- // at which "current" is used. While iterating through the use array we |
- // also have to iterate over the different occurrence indices. |
- int occurrence_index = 0; |
- if (use->UsesMultipleTimes(current)) { |
- occurrence_index = current->uses()->CountOccurrences(use, 0, i - 1); |
- if (FLAG_trace_representation) { |
- PrintF("Instruction %d is used multiple times at %d; occurrence=%d\n", |
- current->id(), |
- use->id(), |
- occurrence_index); |
- } |
- } |
- int operand_index = use->LookupOperandIndex(occurrence_index, current); |
- Representation req = use->RequiredInputRepresentation(operand_index); |
- if (req.IsNone() || req.Equals(r)) continue; |
- int index = 0; |
- while (index < to_convert->length() && |
- CompareConversionUses(to_convert->at(index), |
- use, |
- to_convert_reps->at(index), |
- req) < 0) { |
- ++index; |
- } |
- if (FLAG_trace_representation) { |
- PrintF("Inserting a representation change to %s of %d for use at %d\n", |
- req.Mnemonic(), |
- current->id(), |
- use->id()); |
- } |
- to_convert->InsertAt(index, use); |
- to_convert_reps->InsertAt(index, req); |
- } |
+ if (value->HasNoUses()) return; |
- for (int i = 0; i < to_convert->length(); ++i) { |
- HValue* use = to_convert->at(i); |
- Representation r_to = to_convert_reps->at(i); |
- InsertRepresentationChangeForUse(current, use, r_to); |
+ for (HUseIterator it(value->uses()); !it.Done(); it.Advance()) { |
+ HValue* use_value = it.value(); |
+ int use_index = it.index(); |
+ Representation req = use_value->RequiredInputRepresentation(use_index); |
+ if (req.IsNone() || req.Equals(r)) continue; |
+ InsertRepresentationChangeForUse(value, use_value, use_index, req); |
} |
- |
- if (current->uses()->is_empty()) { |
- ASSERT(current->IsConstant()); |
- current->Delete(); |
+ if (value->HasNoUses()) { |
+ ASSERT(value->IsConstant()); |
+ value->DeleteAndReplaceWith(NULL); |
} |
- to_convert->Rewind(0); |
- to_convert_reps->Rewind(0); |
} |
@@ -1886,8 +1809,8 @@ void HGraph::InsertRepresentationChanges() { |
for (int i = 0; i < phi_list()->length(); i++) { |
HPhi* phi = phi_list()->at(i); |
if (!phi->CheckFlag(HValue::kTruncatingToInt32)) continue; |
- for (int j = 0; j < phi->uses()->length(); j++) { |
- HValue* use = phi->uses()->at(j); |
+ for (HUseIterator it(phi->uses()); !it.Done(); it.Advance()) { |
+ HValue* use = it.value(); |
if (!use->CheckFlag(HValue::kTruncatingToInt32)) { |
phi->ClearFlag(HValue::kTruncatingToInt32); |
change = true; |
@@ -1897,19 +1820,17 @@ void HGraph::InsertRepresentationChanges() { |
} |
} |
- ZoneList<HValue*> value_list(4); |
- ZoneList<Representation> rep_list(4); |
for (int i = 0; i < blocks_.length(); ++i) { |
// Process phi instructions first. |
- for (int j = 0; j < blocks_[i]->phis()->length(); j++) { |
- HPhi* phi = blocks_[i]->phis()->at(j); |
- InsertRepresentationChangesForValue(phi, &value_list, &rep_list); |
+ const ZoneList<HPhi*>* phis = blocks_[i]->phis(); |
+ for (int j = 0; j < phis->length(); j++) { |
+ InsertRepresentationChangesForValue(phis->at(j)); |
} |
// Process normal instructions. |
HInstruction* current = blocks_[i]->first(); |
while (current != NULL) { |
- InsertRepresentationChangesForValue(current, &value_list, &rep_list); |
+ InsertRepresentationChangesForValue(current); |
current = current->next(); |
} |
} |
@@ -5943,7 +5864,7 @@ void HTracer::Trace(const char* name, HGraph* graph, LChunk* chunk) { |
HInstruction* instruction = current->first(); |
while (instruction != NULL) { |
int bci = 0; |
- int uses = instruction->uses()->length(); |
+ int uses = instruction->UseCount(); |
trace_.Add("%d %d ", bci, uses); |
instruction->PrintNameTo(&trace_); |
trace_.Add(" "); |