Commit 2b60325d authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

[Sheriff] Revert "Check elimination temporarily disabled.", "Fix for buildbot...

[Sheriff] Revert "Check elimination temporarily disabled.", "Fix for buildbot failure after r19102." and "Check elimination improvement: propagation of state through phis is supported, CheckMap narrowing implemented."

This reverts commit r19102, r19105 and r19170 for breaking the
Chrome browser_tests. Will reland once fixed.

R=ishell@chromium.org

Review URL: https://codereview.chromium.org/130053007

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19179 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent bda84eaf
......@@ -308,7 +308,7 @@ DEFINE_bool(array_index_dehoisting, true,
DEFINE_bool(analyze_environment_liveness, true,
"analyze liveness of environment slots and zap dead values")
DEFINE_bool(load_elimination, true, "use load elimination")
DEFINE_bool(check_elimination, false, "use check elimination")
DEFINE_bool(check_elimination, true, "use check elimination")
DEFINE_bool(dead_code_elimination, true, "use dead code elimination")
DEFINE_bool(fold_constants, true, "use constant folding")
DEFINE_bool(trace_dead_code_elimination, false, "trace dead code elimination")
......
......@@ -48,12 +48,12 @@ typedef UniqueSet<Map>* MapSet;
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.
HValue* check_; // The last check instruction.
MapSet maps_; // The set of known maps for the object.
};
// The main data structure used during check elimination, which stores a
// The main datastructure used during check elimination, which stores a
// set of known maps for each object.
class HCheckTable : public ZoneObject {
public:
......@@ -130,23 +130,6 @@ class HCheckTable : public ZoneObject {
copy->cursor_ = cursor_;
copy->size_ = size_;
// Create entries for succ block's phis.
if (succ->phis()->length() > 0) {
int pred_index = succ->PredecessorIndexOf(from_block);
for (int phi_index = 0;
phi_index < succ->phis()->length();
++phi_index) {
HPhi* phi = succ->phis()->at(phi_index);
HValue* phi_operand = phi->OperandAt(pred_index);
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()));
}
}
}
// Branch-sensitive analysis for certain comparisons may add more facts
// to the state for the successor on the true branch.
bool learned = false;
......@@ -202,28 +185,17 @@ class HCheckTable : public ZoneObject {
// Global analysis: Merge this state with the other incoming state.
HCheckTable* Merge(HBasicBlock* succ, HCheckTable* that,
HBasicBlock* pred_block, Zone* zone) {
if (pred_block->IsReachable()) {
HBasicBlock* that_block, Zone* zone) {
if (that_block->IsReachable()) {
if (that->size_ == 0) {
// If the other state is empty, simply reset.
size_ = 0;
cursor_ = 0;
} else {
int pred_index = succ->PredecessorIndexOf(pred_block);
bool compact = false;
for (int i = 0; i < size_; i++) {
HCheckTableEntry* this_entry = &entries_[i];
HCheckTableEntry* that_entry;
if (this_entry->object_->IsPhi() &&
this_entry->object_->block() == succ) {
HPhi* phi = HPhi::cast(this_entry->object_);
HValue* phi_operand = phi->OperandAt(pred_index);
that_entry = that->Find(phi_operand);
} else {
that_entry = that->Find(this_entry->object_);
}
HCheckTableEntry* that_entry = that->Find(this_entry->object_);
if (that_entry == NULL) {
this_entry->object_ = NULL;
compact = true;
......@@ -241,7 +213,7 @@ class HCheckTable : public ZoneObject {
}
if (FLAG_trace_check_elimination) {
PrintF("B%d checkmaps-table merged with B%d table:\n",
succ->block_id(), pred_block->block_id());
succ->block_id(), that_block->block_id());
Print();
}
return this;
......@@ -272,43 +244,14 @@ class HCheckTable : public ZoneObject {
}
return;
}
MapSet intersection = i->Intersect(a, phase_->zone());
if (intersection->size() == 0) {
i = i->Intersect(a, phase_->zone());
if (i->size() == 0) {
// Intersection is empty; probably megamorphic, which is likely to
// deopt anyway, so just leave things as they are.
INC_STAT(empty_);
} else {
// Update set of maps in the entry.
entry->maps_ = intersection;
if (intersection->size() != i->size()) {
// Narrow set of maps in the second check maps instruction.
HGraph* graph = instr->block()->graph();
HCheckMaps* new_check_maps =
HCheckMaps::New(graph->zone(), NULL, instr->value(),
intersection, instr->typecheck(),
instr->has_migration_target());
if (entry->check_ != NULL &&
entry->check_->block() == instr->block()) {
// There is a check in the same block so replace it with a more
// strict check and eliminate the second check entirely.
new_check_maps->InsertBefore(entry->check_);
entry->check_->DeleteAndReplaceWith(new_check_maps);
TRACE(("Check #%d narrowed to #%d\n",
entry->check_->id(), new_check_maps->id()));
} else {
new_check_maps->InsertBefore(instr);
}
TRACE(("CheckMaps #%d for #%d narrowed to #%d:\n",
instr->id(), instr->value()->id(), new_check_maps->id()));
instr->DeleteAndReplaceWith(new_check_maps);
entry->check_ = new_check_maps;
if (FLAG_trace_check_elimination) {
Print();
}
INC_STAT(narrowed_);
}
// TODO(titzer): replace the first check with a more strict check
INC_STAT(narrowed_);
}
} else {
// No entry; insert a new one.
......@@ -483,9 +426,7 @@ class HCheckTable : public ZoneObject {
for (int i = 0; i < size_; i++) {
HCheckTableEntry* entry = &entries_[i];
ASSERT(entry->object_ != NULL);
PrintF(" checkmaps-table @%d: %s #%d ", i,
entry->object_->IsPhi() ? "phi" : "object",
entry->object_->id());
PrintF(" checkmaps-table @%d: object #%d ", i, entry->object_->id());
if (entry->check_ != NULL) {
PrintF("check #%d ", entry->check_->id());
}
......
......@@ -2649,32 +2649,16 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
public:
static HCheckMaps* New(Zone* zone, HValue* context, HValue* value,
Handle<Map> map, CompilationInfo* info,
HValue* typecheck = NULL);
HValue *typecheck = NULL);
static HCheckMaps* New(Zone* zone, HValue* context,
HValue* value, SmallMapList* maps,
HValue* typecheck = NULL) {
HValue *typecheck = NULL) {
HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
for (int i = 0; i < maps->length(); i++) {
check_map->Add(maps->at(i), zone);
}
return check_map;
}
// HCheckMaps creation method safe for using during concurrent compilation
// (does not dereference maps handles).
static HCheckMaps* New(Zone* zone, HValue* context,
HValue* value, UniqueSet<Map>* maps,
HValue* typecheck,
bool has_migration_target) {
HCheckMaps* check_map = new(zone) HCheckMaps(value, zone, typecheck);
for (int i = 0; i < maps->size(); i++) {
check_map->map_set_.Add(maps->at(i), zone);
}
if (has_migration_target) {
check_map->has_migration_target_ = true;
check_map->SetGVNFlag(kChangesNewSpacePromotion);
}
return check_map;
}
bool CanOmitMapChecks() { return omit_; }
......@@ -2687,7 +2671,6 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
virtual void PrintDataTo(StringStream* stream) V8_OVERRIDE;
HValue* value() { return OperandAt(0); }
HValue* typecheck() { return OperandAt(1); }
Unique<Map> first_map() const { return map_set_.at(0); }
UniqueSet<Map> map_set() const { return map_set_; }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment