summaryrefslogtreecommitdiff
path: root/deps/v8/src/hydrogen-load-elimination.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/hydrogen-load-elimination.cc')
-rw-r--r--deps/v8/src/hydrogen-load-elimination.cc96
1 files changed, 44 insertions, 52 deletions
diff --git a/deps/v8/src/hydrogen-load-elimination.cc b/deps/v8/src/hydrogen-load-elimination.cc
index 222811678b..0c7de85169 100644
--- a/deps/v8/src/hydrogen-load-elimination.cc
+++ b/deps/v8/src/hydrogen-load-elimination.cc
@@ -76,7 +76,9 @@ class HLoadEliminationTable : public ZoneObject {
FieldOf(l->access()),
l->object()->ActualValue()->id()));
HValue* result = load(l);
- if (result != instr) {
+ if (result != instr &&
+ result->type().Equals(instr->type()) &&
+ result->representation().Equals(instr->representation())) {
// The load can be replaced with a previous load or a value.
TRACE((" replace L%d -> v%d\n", instr->id(), result->id()));
instr->DeleteAndReplaceWith(result);
@@ -98,33 +100,26 @@ class HLoadEliminationTable : public ZoneObject {
}
break;
}
- case HValue::kTransitionElementsKind: {
- HTransitionElementsKind* t = HTransitionElementsKind::cast(instr);
- HValue* object = t->object()->ActualValue();
- KillFieldInternal(object, FieldOf(JSArray::kElementsOffset), NULL);
- KillFieldInternal(object, FieldOf(JSObject::kMapOffset), NULL);
- break;
- }
default: {
- if (instr->CheckChangesFlag(kInobjectFields)) {
+ if (instr->CheckGVNFlag(kChangesInobjectFields)) {
TRACE((" kill-all i%d\n", instr->id()));
Kill();
break;
}
- if (instr->CheckChangesFlag(kMaps)) {
+ if (instr->CheckGVNFlag(kChangesMaps)) {
TRACE((" kill-maps i%d\n", instr->id()));
KillOffset(JSObject::kMapOffset);
}
- if (instr->CheckChangesFlag(kElementsKind)) {
+ if (instr->CheckGVNFlag(kChangesElementsKind)) {
TRACE((" kill-elements-kind i%d\n", instr->id()));
KillOffset(JSObject::kMapOffset);
KillOffset(JSObject::kElementsOffset);
}
- if (instr->CheckChangesFlag(kElementsPointer)) {
+ if (instr->CheckGVNFlag(kChangesElementsPointer)) {
TRACE((" kill-elements i%d\n", instr->id()));
KillOffset(JSObject::kElementsOffset);
}
- if (instr->CheckChangesFlag(kOsrEntries)) {
+ if (instr->CheckGVNFlag(kChangesOsrEntries)) {
TRACE((" kill-osr i%d\n", instr->id()));
Kill();
}
@@ -139,32 +134,8 @@ class HLoadEliminationTable : public ZoneObject {
return this;
}
- // Support for global analysis with HFlowEngine: Merge given state with
- // the other incoming state.
- static HLoadEliminationTable* Merge(HLoadEliminationTable* succ_state,
- HBasicBlock* succ_block,
- HLoadEliminationTable* pred_state,
- HBasicBlock* pred_block,
- Zone* zone) {
- ASSERT(pred_state != NULL);
- if (succ_state == NULL) {
- return pred_state->Copy(succ_block, pred_block, zone);
- } else {
- return succ_state->Merge(succ_block, pred_state, pred_block, zone);
- }
- }
-
- // Support for global analysis with HFlowEngine: Given state merged with all
- // the other incoming states, prepare it for use.
- static HLoadEliminationTable* Finish(HLoadEliminationTable* state,
- HBasicBlock* block,
- Zone* zone) {
- ASSERT(state != NULL);
- return state;
- }
-
- private:
- // Copy state to successor block.
+ // Support for global analysis with HFlowEngine: Copy state to successor
+ // block.
HLoadEliminationTable* Copy(HBasicBlock* succ, HBasicBlock* from_block,
Zone* zone) {
HLoadEliminationTable* copy =
@@ -180,7 +151,8 @@ class HLoadEliminationTable : public ZoneObject {
return copy;
}
- // Merge this state with the other incoming state.
+ // Support for global analysis with HFlowEngine: Merge this state with
+ // the other incoming state.
HLoadEliminationTable* Merge(HBasicBlock* succ, HLoadEliminationTable* that,
HBasicBlock* that_block, Zone* zone) {
if (that->fields_.length() < fields_.length()) {
@@ -460,7 +432,11 @@ class HLoadEliminationTable : public ZoneObject {
class HLoadEliminationEffects : public ZoneObject {
public:
explicit HLoadEliminationEffects(Zone* zone)
- : zone_(zone), stores_(5, zone) { }
+ : zone_(zone),
+ maps_stored_(false),
+ fields_stored_(false),
+ elements_stored_(false),
+ stores_(5, zone) { }
inline bool Disabled() {
return false; // Effects are _not_ disabled.
@@ -468,25 +444,37 @@ class HLoadEliminationEffects : 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;
+ fields_stored_ = true;
+ elements_stored_ = true;
+ }
+ default: {
+ fields_stored_ |= instr->CheckGVNFlag(kChangesInobjectFields);
+ maps_stored_ |= instr->CheckGVNFlag(kChangesMaps);
+ maps_stored_ |= instr->CheckGVNFlag(kChangesElementsKind);
+ elements_stored_ |= instr->CheckGVNFlag(kChangesElementsKind);
+ elements_stored_ |= instr->CheckGVNFlag(kChangesElementsPointer);
+ }
}
}
// Apply these effects to the given load elimination table.
void Apply(HLoadEliminationTable* table) {
- // Loads must not be hoisted past the OSR entry, therefore we kill
- // everything if we see an OSR entry.
- if (flags_.Contains(kInobjectFields) || flags_.Contains(kOsrEntries)) {
+ if (fields_stored_) {
table->Kill();
return;
}
- if (flags_.Contains(kElementsKind) || flags_.Contains(kMaps)) {
+ if (maps_stored_) {
table->KillOffset(JSObject::kMapOffset);
}
- if (flags_.Contains(kElementsKind) || flags_.Contains(kElementsPointer)) {
+ if (elements_stored_) {
table->KillOffset(JSObject::kElementsOffset);
}
@@ -498,7 +486,9 @@ class HLoadEliminationEffects : public ZoneObject {
// Union these effects with the other effects.
void Union(HLoadEliminationEffects* that, Zone* zone) {
- flags_.Add(that->flags_);
+ maps_stored_ |= that->maps_stored_;
+ fields_stored_ |= that->fields_stored_;
+ elements_stored_ |= that->elements_stored_;
for (int i = 0; i < that->stores_.length(); i++) {
stores_.Add(that->stores_[i], zone);
}
@@ -506,7 +496,9 @@ class HLoadEliminationEffects : public ZoneObject {
private:
Zone* zone_;
- GVNFlagSet flags_;
+ bool maps_stored_ : 1;
+ bool fields_stored_ : 1;
+ bool elements_stored_ : 1;
ZoneList<HStoreNamedField*> stores_;
};