Index: src/hydrogen-check-elimination.cc |
diff --git a/src/hydrogen-check-elimination.cc b/src/hydrogen-check-elimination.cc |
index d5715a61ecce5059ded5b5bae02d7368b9c0235a..5fdb3e3f3c48fa1260005eeeab7ec7e6ae537ebd 100644 |
--- a/src/hydrogen-check-elimination.cc |
+++ b/src/hydrogen-check-elimination.cc |
@@ -50,7 +50,6 @@ struct HCheckTableEntry { |
HValue* object_; // The object being approximated. NULL => invalid entry. |
HInstruction* check_; // The last check instruction. |
MapSet maps_; // The set of known maps for the object. |
- bool is_stable_; |
}; |
@@ -104,10 +103,9 @@ class HCheckTable : public ZoneObject { |
} |
default: { |
// If the instruction changes maps uncontrollably, drop everything. |
- if (instr->CheckChangesFlag(kOsrEntries)) { |
- Reset(); |
- } else if (instr->CheckChangesFlag(kMaps)) { |
- KillUnstableEntries(); |
+ if (instr->CheckChangesFlag(kMaps) || |
+ instr->CheckChangesFlag(kOsrEntries)) { |
+ Kill(); |
} |
} |
// Improvements possible: |
@@ -156,7 +154,6 @@ class HCheckTable : public ZoneObject { |
if (old_entry->check_ != NULL && |
old_entry->check_->block()->Dominates(succ)) { |
new_entry->check_ = old_entry->check_; |
- new_entry->is_stable_ = old_entry->is_stable_; |
} else { |
// Leave it NULL till we meet a new check instruction for this object |
// in the control flow. |
@@ -178,8 +175,7 @@ class HCheckTable : public ZoneObject { |
HCheckTableEntry* pred_entry = copy->Find(phi_operand); |
if (pred_entry != NULL) { |
// Create an entry for a phi in the table. |
- copy->Insert(phi, NULL, pred_entry->maps_->Copy(phase_->zone()), |
- pred_entry->is_stable_); |
+ copy->Insert(phi, NULL, pred_entry->maps_->Copy(phase_->zone())); |
} |
} |
} |
@@ -197,13 +193,12 @@ class HCheckTable : public ZoneObject { |
if (is_true_branch) { |
// Learn on the true branch of if(CompareMap(x)). |
if (entry == NULL) { |
- copy->Insert(object, cmp, cmp->map(), cmp->is_stable()); |
+ copy->Insert(object, cmp, cmp->map()); |
} else { |
MapSet list = new(phase_->zone()) UniqueSet<Map>(); |
list->Add(cmp->map(), phase_->zone()); |
entry->maps_ = list; |
entry->check_ = cmp; |
- entry->is_stable_ = cmp->is_stable(); |
} |
} else { |
// Learn on the false branch of if(CompareMap(x)). |
@@ -222,10 +217,10 @@ class HCheckTable : public ZoneObject { |
HCheckTableEntry* re = copy->Find(right); |
if (le == NULL) { |
if (re != NULL) { |
- copy->Insert(left, NULL, re->maps_->Copy(zone), re->is_stable_); |
+ copy->Insert(left, NULL, re->maps_->Copy(zone)); |
} |
} else if (re == NULL) { |
- copy->Insert(right, NULL, le->maps_->Copy(zone), le->is_stable_); |
+ copy->Insert(right, NULL, le->maps_->Copy(zone)); |
} else { |
MapSet intersect = le->maps_->Intersect(re->maps_, zone); |
le->maps_ = intersect; |
@@ -252,7 +247,8 @@ class HCheckTable : public ZoneObject { |
HBasicBlock* pred_block, Zone* zone) { |
if (that->size_ == 0) { |
// If the other state is empty, simply reset. |
- Reset(); |
+ size_ = 0; |
+ cursor_ = 0; |
} else { |
int pred_index = succ->PredecessorIndexOf(pred_block); |
bool compact = false; |
@@ -275,8 +271,6 @@ class HCheckTable : public ZoneObject { |
} else { |
this_entry->maps_ = |
this_entry->maps_->Union(that_entry->maps_, phase_->zone()); |
- this_entry->is_stable_ = |
- this_entry->is_stable_ && that_entry->is_stable_; |
if (this_entry->check_ != that_entry->check_) { |
this_entry->check_ = NULL; |
} |
@@ -357,8 +351,7 @@ class HCheckTable : public ZoneObject { |
} |
} else { |
// No entry; insert a new one. |
- Insert(object, instr, instr->map_set().Copy(phase_->zone()), |
- instr->is_stable()); |
+ Insert(object, instr, instr->map_set().Copy(phase_->zone())); |
} |
} |
@@ -420,8 +413,7 @@ class HCheckTable : public ZoneObject { |
} |
} else { |
// No prior information. |
- // TODO(verwaest): Tag map constants with stability. |
- Insert(object, instr, map, false); |
+ Insert(object, instr, map); |
} |
} |
@@ -438,14 +430,12 @@ class HCheckTable : public ZoneObject { |
if (instr->has_transition()) { |
// This store transitions the object to a new map. |
Kill(object); |
- Insert(object, NULL, MapConstant(instr->transition()), |
- instr->is_stable()); |
+ Insert(object, NULL, MapConstant(instr->transition())); |
} else if (IsMapAccess(instr->access())) { |
// This is a store directly to the map field of the object. |
Kill(object); |
if (!instr->value()->IsConstant()) return; |
- // TODO(verwaest): Tag with stability. |
- Insert(object, NULL, MapConstant(instr->value()), false); |
+ Insert(object, NULL, MapConstant(instr->value())); |
} else { |
// If the instruction changes maps, it should be handled above. |
CHECK(!instr->CheckChangesFlag(kMaps)); |
@@ -495,26 +485,12 @@ class HCheckTable : public ZoneObject { |
} |
} |
- // Reset the table. |
- void Reset() { |
+ // Kill everything in the table. |
+ void Kill() { |
size_ = 0; |
cursor_ = 0; |
} |
- // Kill everything in the table. |
- void KillUnstableEntries() { |
- bool compact = false; |
- for (int i = 0; i < size_; i++) { |
- HCheckTableEntry* entry = &entries_[i]; |
- ASSERT(entry->object_ != NULL); |
- if (!entry->is_stable_) { |
- entry->object_ = NULL; |
- compact = true; |
- } |
- } |
- if (compact) Compact(); |
- } |
- |
// Kill everything in the table that may alias {object}. |
void Kill(HValue* object) { |
bool compact = false; |
@@ -596,24 +572,17 @@ class HCheckTable : public ZoneObject { |
return entry == NULL ? NULL : entry->maps_; |
} |
- void Insert(HValue* object, |
- HInstruction* check, |
- Unique<Map> map, |
- bool is_stable) { |
+ void Insert(HValue* object, HInstruction* check, Unique<Map> map) { |
MapSet list = new(phase_->zone()) UniqueSet<Map>(); |
list->Add(map, phase_->zone()); |
- Insert(object, check, list, is_stable); |
+ Insert(object, check, list); |
} |
- void Insert(HValue* object, |
- HInstruction* check, |
- MapSet maps, |
- bool is_stable) { |
+ void Insert(HValue* object, HInstruction* check, MapSet maps) { |
HCheckTableEntry* entry = &entries_[cursor_++]; |
entry->object_ = object; |
entry->check_ = check; |
entry->maps_ = maps; |
- entry->is_stable_ = is_stable; |
// If the table becomes full, wrap around and overwrite older entries. |
if (cursor_ == kMaxTrackedObjects) cursor_ = 0; |
if (size_ < kMaxTrackedObjects) size_++; |
@@ -643,7 +612,8 @@ class HCheckTable : public ZoneObject { |
class HCheckMapsEffects : public ZoneObject { |
public: |
explicit HCheckMapsEffects(Zone* zone) |
- : stores_(5, zone) { } |
+ : maps_stored_(false), |
+ stores_(5, zone) { } |
inline bool Disabled() { |
return false; // Effects are _not_ disabled. |
@@ -651,22 +621,27 @@ class HCheckMapsEffects : public ZoneObject { |
// Process a possibly side-effecting instruction. |
void Process(HInstruction* instr, Zone* zone) { |
- if (instr->IsStoreNamedField()) { |
- stores_.Add(HStoreNamedField::cast(instr), zone); |
- } else { |
- flags_.Add(instr->ChangesFlags()); |
+ switch (instr->opcode()) { |
+ case HValue::kStoreNamedField: { |
+ stores_.Add(HStoreNamedField::cast(instr), zone); |
+ break; |
+ } |
+ case HValue::kOsrEntry: { |
+ // Kill everything. Loads must not be hoisted past the OSR entry. |
+ maps_stored_ = true; |
+ } |
+ default: { |
+ maps_stored_ |= (instr->CheckChangesFlag(kMaps) | |
+ instr->CheckChangesFlag(kElementsKind)); |
+ } |
} |
} |
// Apply these effects to the given check elimination table. |
void Apply(HCheckTable* table) { |
- if (flags_.Contains(kOsrEntries)) { |
- table->Reset(); |
- return; |
- } |
- if (flags_.Contains(kMaps) || flags_.Contains(kElementsKind)) { |
+ if (maps_stored_) { |
// Uncontrollable map modifications; kill everything. |
- table->KillUnstableEntries(); |
+ table->Kill(); |
return; |
} |
@@ -681,14 +656,14 @@ class HCheckMapsEffects : public ZoneObject { |
// Union these effects with the other effects. |
void Union(HCheckMapsEffects* that, Zone* zone) { |
- flags_.Add(that->flags_); |
+ maps_stored_ |= that->maps_stored_; |
for (int i = 0; i < that->stores_.length(); i++) { |
stores_.Add(that->stores_[i], zone); |
} |
} |
private: |
- GVNFlagSet flags_; |
+ bool maps_stored_ : 1; |
ZoneList<HStoreNamedField*> stores_; |
}; |
@@ -705,7 +680,7 @@ void HCheckEliminationPhase::Run() { |
} else { |
// Perform only local analysis. |
for (int i = 0; i < graph()->blocks()->length(); i++) { |
- table->Reset(); |
+ table->Kill(); |
engine.AnalyzeOneBlock(graph()->blocks()->at(i), table); |
} |
} |