Revert "Handle HCheckInstanceType and HIsStringAndBranch in check elimination."
This reverts commit r21593 for breaking the Webkit tests. TBR=mvstanton@chromium.org Review URL: https://codereview.chromium.org/310593004 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@21594 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
1c17e61629
commit
dae3413cc4
@ -104,10 +104,6 @@ class HCheckTable : public ZoneObject {
|
||||
ReduceCompareObjectEqAndBranch(HCompareObjectEqAndBranch::cast(instr));
|
||||
break;
|
||||
}
|
||||
case HValue::kIsStringAndBranch: {
|
||||
ReduceIsStringAndBranch(HIsStringAndBranch::cast(instr));
|
||||
break;
|
||||
}
|
||||
case HValue::kTransitionElementsKind: {
|
||||
ReduceTransitionElementsKind(
|
||||
HTransitionElementsKind::cast(instr));
|
||||
@ -117,10 +113,6 @@ class HCheckTable : public ZoneObject {
|
||||
ReduceCheckHeapObject(HCheckHeapObject::cast(instr));
|
||||
break;
|
||||
}
|
||||
case HValue::kCheckInstanceType: {
|
||||
ReduceCheckInstanceType(HCheckInstanceType::cast(instr));
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// If the instruction changes maps uncontrollably, drop everything.
|
||||
if (instr->CheckChangesFlag(kOsrEntries)) {
|
||||
@ -133,7 +125,7 @@ class HCheckTable : public ZoneObject {
|
||||
}
|
||||
}
|
||||
// Improvements possible:
|
||||
// - eliminate redundant HCheckSmi instructions
|
||||
// - eliminate redundant HCheckSmi, HCheckInstanceType instructions
|
||||
// - track which values have been HCheckHeapObject'd
|
||||
}
|
||||
|
||||
@ -269,28 +261,6 @@ class HCheckTable : public ZoneObject {
|
||||
ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, re->state_);
|
||||
}
|
||||
learned = true;
|
||||
} else if (end->IsIsStringAndBranch()) {
|
||||
HIsStringAndBranch* cmp = HIsStringAndBranch::cast(end);
|
||||
HValue* object = cmp->value()->ActualValue();
|
||||
HCheckTableEntry* entry = copy->Find(object);
|
||||
if (is_true_branch) {
|
||||
// Learn on the true branch of if(IsString(x)).
|
||||
if (entry == NULL) {
|
||||
copy->Insert(object, NULL, string_maps(),
|
||||
HCheckTableEntry::CHECKED);
|
||||
} else {
|
||||
EnsureChecked(entry, object, cmp);
|
||||
entry->maps_ = entry->maps_->Intersect(string_maps(), zone);
|
||||
ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, entry->state_);
|
||||
}
|
||||
} else {
|
||||
// Learn on the false branch of if(IsString(x)).
|
||||
if (entry != NULL) {
|
||||
EnsureChecked(entry, object, cmp);
|
||||
entry->maps_ = entry->maps_->Subtract(string_maps(), zone);
|
||||
ASSERT_NE(HCheckTableEntry::UNCHECKED_STABLE, entry->state_);
|
||||
}
|
||||
}
|
||||
}
|
||||
// Learning on false branches requires storing negative facts.
|
||||
}
|
||||
@ -445,50 +415,6 @@ class HCheckTable : public ZoneObject {
|
||||
}
|
||||
}
|
||||
|
||||
void ReduceCheckInstanceType(HCheckInstanceType* instr) {
|
||||
HValue* value = instr->value()->ActualValue();
|
||||
HCheckTableEntry* entry = Find(value);
|
||||
if (entry == NULL) {
|
||||
if (instr->check() == HCheckInstanceType::IS_STRING) {
|
||||
Insert(value, NULL, string_maps(), HCheckTableEntry::CHECKED);
|
||||
}
|
||||
return;
|
||||
}
|
||||
UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(
|
||||
entry->maps_->size(), zone());
|
||||
for (int i = 0; i < entry->maps_->size(); ++i) {
|
||||
InstanceType type;
|
||||
Unique<Map> map = entry->maps_->at(i);
|
||||
{
|
||||
// This is safe, because maps don't move and their instance type does
|
||||
// not change.
|
||||
AllowHandleDereference allow_deref;
|
||||
type = map.handle()->instance_type();
|
||||
}
|
||||
if (instr->is_interval_check()) {
|
||||
InstanceType first_type, last_type;
|
||||
instr->GetCheckInterval(&first_type, &last_type);
|
||||
if (first_type <= type && type <= last_type) maps->Add(map, zone());
|
||||
} else {
|
||||
uint8_t mask, tag;
|
||||
instr->GetCheckMaskAndTag(&mask, &tag);
|
||||
if ((type & mask) == tag) maps->Add(map, zone());
|
||||
}
|
||||
}
|
||||
if (maps->size() == entry->maps_->size()) {
|
||||
TRACE(("Removing redundant CheckInstanceType #%d at B%d\n",
|
||||
instr->id(), instr->block()->block_id()));
|
||||
EnsureChecked(entry, value, instr);
|
||||
instr->DeleteAndReplaceWith(value);
|
||||
INC_STAT(removed_cit_);
|
||||
} else if (maps->size() != 0) {
|
||||
entry->maps_ = maps;
|
||||
if (entry->state_ == HCheckTableEntry::UNCHECKED_STABLE) {
|
||||
entry->state_ = HCheckTableEntry::CHECKED_STABLE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ReduceLoadNamedField(HLoadNamedField* instr) {
|
||||
// Reduce a load of the map field when it is known to be a constant.
|
||||
if (!instr->access().IsMap()) {
|
||||
@ -602,28 +528,6 @@ class HCheckTable : public ZoneObject {
|
||||
instr->block()->MarkSuccEdgeUnreachable(unreachable_succ);
|
||||
}
|
||||
|
||||
void ReduceIsStringAndBranch(HIsStringAndBranch* instr) {
|
||||
HValue* value = instr->value()->ActualValue();
|
||||
HCheckTableEntry* entry = Find(value);
|
||||
if (entry == NULL) return;
|
||||
EnsureChecked(entry, value, instr);
|
||||
int succ;
|
||||
if (entry->maps_->IsSubset(string_maps())) {
|
||||
TRACE(("Marking redundant IsStringAndBranch #%d at B%d as true\n",
|
||||
instr->id(), instr->block()->block_id()));
|
||||
succ = 0;
|
||||
} else {
|
||||
MapSet intersection = entry->maps_->Intersect(string_maps(), zone());
|
||||
if (intersection->size() > 0) return;
|
||||
TRACE(("Marking redundant IsStringAndBranch #%d at B%d as false\n",
|
||||
instr->id(), instr->block()->block_id()));
|
||||
succ = 1;
|
||||
}
|
||||
instr->set_known_successor_index(succ);
|
||||
int unreachable_succ = 1 - succ;
|
||||
instr->block()->MarkSuccEdgeUnreachable(unreachable_succ);
|
||||
}
|
||||
|
||||
void ReduceTransitionElementsKind(HTransitionElementsKind* instr) {
|
||||
HValue* object = instr->object()->ActualValue();
|
||||
HCheckTableEntry* entry = Find(object);
|
||||
@ -784,7 +688,6 @@ class HCheckTable : public ZoneObject {
|
||||
}
|
||||
|
||||
Zone* zone() const { return phase_->zone(); }
|
||||
MapSet string_maps() const { return phase_->string_maps(); }
|
||||
|
||||
friend class HCheckMapsEffects;
|
||||
friend class HCheckEliminationPhase;
|
||||
@ -891,7 +794,6 @@ void HCheckEliminationPhase::PrintStats() {
|
||||
PRINT_STAT(redundant);
|
||||
PRINT_STAT(removed);
|
||||
PRINT_STAT(removed_cho);
|
||||
PRINT_STAT(removed_cit);
|
||||
PRINT_STAT(narrowed);
|
||||
PRINT_STAT(loads);
|
||||
PRINT_STAT(empty);
|
||||
|
@ -16,20 +16,11 @@ namespace internal {
|
||||
class HCheckEliminationPhase : public HPhase {
|
||||
public:
|
||||
explicit HCheckEliminationPhase(HGraph* graph)
|
||||
: HPhase("H_Check Elimination", graph), aliasing_(),
|
||||
string_maps_(kStringMapsSize, zone()) {
|
||||
// Compute the set of string maps.
|
||||
#define ADD_STRING_MAP(type, size, name, Name) \
|
||||
string_maps_.Add(Unique<Map>::CreateImmovable( \
|
||||
graph->isolate()->factory()->name##_map()), zone());
|
||||
STRING_TYPE_LIST(ADD_STRING_MAP)
|
||||
#undef ADD_STRING_MAP
|
||||
ASSERT_EQ(kStringMapsSize, string_maps_.size());
|
||||
: HPhase("H_Check Elimination", graph), aliasing_() {
|
||||
#ifdef DEBUG
|
||||
redundant_ = 0;
|
||||
removed_ = 0;
|
||||
removed_cho_ = 0;
|
||||
removed_cit_ = 0;
|
||||
narrowed_ = 0;
|
||||
loads_ = 0;
|
||||
empty_ = 0;
|
||||
@ -44,20 +35,13 @@ class HCheckEliminationPhase : public HPhase {
|
||||
friend class HCheckTable;
|
||||
|
||||
private:
|
||||
const UniqueSet<Map>* string_maps() const { return &string_maps_; }
|
||||
|
||||
void PrintStats();
|
||||
|
||||
HAliasAnalyzer* aliasing_;
|
||||
#define COUNT(type, size, name, Name) + 1
|
||||
static const int kStringMapsSize = 0 STRING_TYPE_LIST(COUNT);
|
||||
#undef COUNT
|
||||
UniqueSet<Map> string_maps_;
|
||||
#ifdef DEBUG
|
||||
int redundant_;
|
||||
int removed_;
|
||||
int removed_cho_;
|
||||
int removed_cit_;
|
||||
int narrowed_;
|
||||
int loads_;
|
||||
int empty_;
|
||||
|
@ -3256,27 +3256,11 @@ bool HIsObjectAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
|
||||
|
||||
|
||||
bool HIsStringAndBranch::KnownSuccessorBlock(HBasicBlock** block) {
|
||||
if (known_successor_index() != kNoKnownSuccessorIndex) {
|
||||
*block = SuccessorAt(known_successor_index());
|
||||
return true;
|
||||
}
|
||||
if (FLAG_fold_constants && value()->IsConstant()) {
|
||||
*block = HConstant::cast(value())->HasStringValue()
|
||||
? FirstSuccessor() : SecondSuccessor();
|
||||
return true;
|
||||
}
|
||||
if (value()->type().IsString()) {
|
||||
*block = FirstSuccessor();
|
||||
return true;
|
||||
}
|
||||
if (value()->type().IsSmi() ||
|
||||
value()->type().IsNull() ||
|
||||
value()->type().IsBoolean() ||
|
||||
value()->type().IsUndefined() ||
|
||||
value()->type().IsJSObject()) {
|
||||
*block = SecondSuccessor();
|
||||
return true;
|
||||
}
|
||||
*block = NULL;
|
||||
return false;
|
||||
}
|
||||
|
@ -2909,8 +2909,6 @@ class HCheckInstanceType V8_FINAL : public HUnaryOperation {
|
||||
void GetCheckInterval(InstanceType* first, InstanceType* last);
|
||||
void GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag);
|
||||
|
||||
Check check() const { return check_; }
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(CheckInstanceType)
|
||||
|
||||
protected:
|
||||
@ -4427,12 +4425,6 @@ class HIsStringAndBranch V8_FINAL : public HUnaryControlInstruction {
|
||||
|
||||
virtual bool KnownSuccessorBlock(HBasicBlock** block) V8_OVERRIDE;
|
||||
|
||||
static const int kNoKnownSuccessorIndex = -1;
|
||||
int known_successor_index() const { return known_successor_index_; }
|
||||
void set_known_successor_index(int known_successor_index) {
|
||||
known_successor_index_ = known_successor_index;
|
||||
}
|
||||
|
||||
DECLARE_CONCRETE_INSTRUCTION(IsStringAndBranch)
|
||||
|
||||
protected:
|
||||
@ -4442,10 +4434,7 @@ class HIsStringAndBranch V8_FINAL : public HUnaryControlInstruction {
|
||||
HIsStringAndBranch(HValue* value,
|
||||
HBasicBlock* true_target = NULL,
|
||||
HBasicBlock* false_target = NULL)
|
||||
: HUnaryControlInstruction(value, true_target, false_target),
|
||||
known_successor_index_(kNoKnownSuccessorIndex) { }
|
||||
|
||||
int known_successor_index_;
|
||||
: HUnaryControlInstruction(value, true_target, false_target) {}
|
||||
};
|
||||
|
||||
|
||||
|
19
src/unique.h
19
src/unique.h
@ -275,25 +275,6 @@ class UniqueSet V8_FINAL : public ZoneObject {
|
||||
return out;
|
||||
}
|
||||
|
||||
// Returns a new set representing all elements from this set which are not in
|
||||
// that set. O(|this| * |that|).
|
||||
UniqueSet<T>* Subtract(const UniqueSet<T>* that, Zone* zone) const {
|
||||
if (that->size_ == 0) return this->Copy(zone);
|
||||
|
||||
UniqueSet<T>* out = new(zone) UniqueSet<T>(this->size_, zone);
|
||||
|
||||
int i = 0, j = 0;
|
||||
while (i < this->size_) {
|
||||
Unique<T> cand = this->array_[i];
|
||||
if (!that->Contains(cand)) {
|
||||
out->array_[j++] = cand;
|
||||
}
|
||||
}
|
||||
|
||||
out->size_ = j;
|
||||
return out;
|
||||
}
|
||||
|
||||
// Makes an exact copy of this set. O(|this|).
|
||||
UniqueSet<T>* Copy(Zone* zone) const {
|
||||
UniqueSet<T>* copy = new(zone) UniqueSet<T>(this->size_, zone);
|
||||
|
Loading…
Reference in New Issue
Block a user