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

Unified Diff: src/hydrogen-load-elimination.cc

Issue 185653004: Experimental parser: merge to r19637 (Closed) Base URL: https://v8.googlecode.com/svn/branches/experimental/parser
Patch Set: Created 6 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
« no previous file with comments | « src/hydrogen-instructions.cc ('k') | src/hydrogen-representation-changes.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen-load-elimination.cc
diff --git a/src/hydrogen-load-elimination.cc b/src/hydrogen-load-elimination.cc
index f2e993b18dea2305884acd01274f85edab887260..f84eac046b5d88297ba9d75eda72c57e356037af 100644
--- a/src/hydrogen-load-elimination.cc
+++ b/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,26 +100,33 @@ 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->CheckGVNFlag(kChangesInobjectFields)) {
+ if (instr->CheckChangesFlag(kInobjectFields)) {
TRACE((" kill-all i%d\n", instr->id()));
Kill();
break;
}
- if (instr->CheckGVNFlag(kChangesMaps)) {
+ if (instr->CheckChangesFlag(kMaps)) {
TRACE((" kill-maps i%d\n", instr->id()));
KillOffset(JSObject::kMapOffset);
}
- if (instr->CheckGVNFlag(kChangesElementsKind)) {
+ if (instr->CheckChangesFlag(kElementsKind)) {
TRACE((" kill-elements-kind i%d\n", instr->id()));
KillOffset(JSObject::kMapOffset);
KillOffset(JSObject::kElementsOffset);
}
- if (instr->CheckGVNFlag(kChangesElementsPointer)) {
+ if (instr->CheckChangesFlag(kElementsPointer)) {
TRACE((" kill-elements i%d\n", instr->id()));
KillOffset(JSObject::kElementsOffset);
}
- if (instr->CheckGVNFlag(kChangesOsrEntries)) {
+ if (instr->CheckChangesFlag(kOsrEntries)) {
TRACE((" kill-osr i%d\n", instr->id()));
Kill();
}
@@ -132,8 +141,34 @@ class HLoadEliminationTable : public ZoneObject {
return this;
}
- // Support for global analysis with HFlowEngine: Copy state to sucessor block.
- HLoadEliminationTable* Copy(HBasicBlock* succ, Zone* zone) {
+ // 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.
+ HLoadEliminationTable* Copy(HBasicBlock* succ, HBasicBlock* from_block,
+ Zone* zone) {
HLoadEliminationTable* copy =
new(zone) HLoadEliminationTable(zone, aliasing_);
copy->EnsureFields(fields_.length());
@@ -147,10 +182,9 @@ class HLoadEliminationTable : public ZoneObject {
return copy;
}
- // Support for global analysis with HFlowEngine: Merge this state with
- // the other incoming state.
- HLoadEliminationTable* Merge(HBasicBlock* succ,
- HLoadEliminationTable* that, Zone* zone) {
+ // 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()) {
// Drop fields not in the other table.
fields_.Rewind(that->fields_.length());
@@ -176,6 +210,10 @@ class HLoadEliminationTable : public ZoneObject {
approx = approx->next_;
}
}
+ if (FLAG_trace_load_elimination) {
+ TRACE((" merge-to B%d\n", succ->block_id()));
+ Print();
+ }
return this;
}
@@ -187,6 +225,10 @@ class HLoadEliminationTable : public ZoneObject {
// load or store for this object and field exists, return the new value with
// which the load should be replaced. Otherwise, return {instr}.
HValue* load(HLoadNamedField* instr) {
+ // There must be no loads from non observable in-object properties.
+ ASSERT(!instr->access().IsInobject() ||
+ instr->access().existing_inobject_property());
+
int field = FieldOf(instr->access());
if (field < 0) return instr;
@@ -197,9 +239,12 @@ class HLoadEliminationTable : public ZoneObject {
// Load is not redundant. Fill out a new entry.
approx->last_value_ = instr;
return instr;
- } else {
+ } else if (approx->last_value_->block()->EqualToOrDominates(
+ instr->block())) {
// Eliminate the load. Reuse previously stored value or load instruction.
return approx->last_value_;
+ } else {
+ return instr;
}
}
@@ -208,6 +253,12 @@ class HLoadEliminationTable : public ZoneObject {
// the stored values are the same), return NULL indicating that this store
// instruction is redundant. Otherwise, return {instr}.
HValue* store(HStoreNamedField* instr) {
+ if (instr->access().IsInobject() &&
+ !instr->access().existing_inobject_property()) {
+ TRACE((" skipping non existing property initialization store\n"));
+ return instr;
+ }
+
int field = FieldOf(instr->access());
if (field < 0) return KillIfMisaligned(instr);
@@ -411,11 +462,7 @@ class HLoadEliminationTable : public ZoneObject {
class HLoadEliminationEffects : public ZoneObject {
public:
explicit HLoadEliminationEffects(Zone* zone)
- : zone_(zone),
- maps_stored_(false),
- fields_stored_(false),
- elements_stored_(false),
- stores_(5, zone) { }
+ : zone_(zone), stores_(5, zone) { }
inline bool Disabled() {
return false; // Effects are _not_ disabled.
@@ -423,37 +470,25 @@ class HLoadEliminationEffects : public ZoneObject {
// Process a possibly side-effecting instruction.
void Process(HInstruction* instr, Zone* zone) {
- 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);
- }
+ if (instr->IsStoreNamedField()) {
+ stores_.Add(HStoreNamedField::cast(instr), zone_);
+ } else {
+ flags_.Add(instr->ChangesFlags());
}
}
// Apply these effects to the given load elimination table.
void Apply(HLoadEliminationTable* table) {
- if (fields_stored_) {
+ // 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)) {
table->Kill();
return;
}
- if (maps_stored_) {
+ if (flags_.Contains(kElementsKind) || flags_.Contains(kMaps)) {
table->KillOffset(JSObject::kMapOffset);
}
- if (elements_stored_) {
+ if (flags_.Contains(kElementsKind) || flags_.Contains(kElementsPointer)) {
table->KillOffset(JSObject::kElementsOffset);
}
@@ -465,9 +500,7 @@ class HLoadEliminationEffects : public ZoneObject {
// Union these effects with the other effects.
void Union(HLoadEliminationEffects* that, Zone* zone) {
- maps_stored_ |= that->maps_stored_;
- fields_stored_ |= that->fields_stored_;
- elements_stored_ |= that->elements_stored_;
+ flags_.Add(that->flags_);
for (int i = 0; i < that->stores_.length(); i++) {
stores_.Add(that->stores_[i], zone);
}
@@ -475,9 +508,7 @@ class HLoadEliminationEffects : public ZoneObject {
private:
Zone* zone_;
- bool maps_stored_ : 1;
- bool fields_stored_ : 1;
- bool elements_stored_ : 1;
+ GVNFlagSet flags_;
ZoneList<HStoreNamedField*> stores_;
};
« no previous file with comments | « src/hydrogen-instructions.cc ('k') | src/hydrogen-representation-changes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698