Commit 8d741a9a authored by danno@chromium.org's avatar danno@chromium.org

Split GVN flags from flags in Hydrogen instructions.

BUG=
TEST=

Review URL: https://chromiumcodereview.appspot.com/9233005

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@10460 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent c6166560
...@@ -416,18 +416,18 @@ void HValue::PrintRangeTo(StringStream* stream) { ...@@ -416,18 +416,18 @@ void HValue::PrintRangeTo(StringStream* stream) {
void HValue::PrintChangesTo(StringStream* stream) { void HValue::PrintChangesTo(StringStream* stream) {
int changes_flags = ChangesFlags(); GVNFlagSet changes_flags = ChangesFlags();
if (changes_flags == 0) return; if (changes_flags.IsEmpty()) return;
stream->Add(" changes["); stream->Add(" changes[");
if (changes_flags == AllSideEffects()) { if (changes_flags == AllSideEffectsFlagSet()) {
stream->Add("*"); stream->Add("*");
} else { } else {
bool add_comma = false; bool add_comma = false;
#define PRINT_DO(type) \ #define PRINT_DO(type) \
if (changes_flags & (1 << kChanges##type)) { \ if (changes_flags.Contains(kChanges##type)) { \
if (add_comma) stream->Add(","); \ if (add_comma) stream->Add(","); \
add_comma = true; \ add_comma = true; \
stream->Add(#type); \ stream->Add(#type); \
} }
GVN_FLAG_LIST(PRINT_DO); GVN_FLAG_LIST(PRINT_DO);
#undef PRINT_DO #undef PRINT_DO
...@@ -1408,7 +1408,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, ...@@ -1408,7 +1408,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
SetOperandAt(0, context); SetOperandAt(0, context);
SetOperandAt(1, object); SetOperandAt(1, object);
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
for (int i = 0; for (int i = 0;
i < types->length() && types_.length() < kMaxLoadPolymorphism; i < types->length() && types_.length() < kMaxLoadPolymorphism;
++i) { ++i) {
...@@ -1420,9 +1420,9 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context, ...@@ -1420,9 +1420,9 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
case FIELD: { case FIELD: {
int index = lookup.GetLocalFieldIndexFromMap(*map); int index = lookup.GetLocalFieldIndexFromMap(*map);
if (index < 0) { if (index < 0) {
SetFlag(kDependsOnInobjectFields); SetGVNFlag(kDependsOnInobjectFields);
} else { } else {
SetFlag(kDependsOnBackingStoreFields); SetGVNFlag(kDependsOnBackingStoreFields);
} }
types_.Add(types->at(i)); types_.Add(types->at(i));
break; break;
......
...@@ -492,18 +492,26 @@ class HUseIterator BASE_EMBEDDED { ...@@ -492,18 +492,26 @@ class HUseIterator BASE_EMBEDDED {
}; };
// There must be one corresponding kDepends flag for every kChanges flag and
// the order of the kChanges flags must be exactly the same as of the kDepends
// flags.
enum GVNFlag {
// Declare global value numbering flags.
#define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
GVN_FLAG_LIST(DECLARE_FLAG)
#undef DECLARE_FLAG
kAfterLastFlag,
kLastFlag = kAfterLastFlag - 1
};
typedef EnumSet<GVNFlag> GVNFlagSet;
class HValue: public ZoneObject { class HValue: public ZoneObject {
public: public:
static const int kNoNumber = -1; static const int kNoNumber = -1;
// There must be one corresponding kDepends flag for every kChanges flag and
// the order of the kChanges flags must be exactly the same as of the kDepends
// flags.
enum Flag { enum Flag {
// Declare global value numbering flags.
#define DECLARE_DO(type) kChanges##type, kDependsOn##type,
GVN_FLAG_LIST(DECLARE_DO)
#undef DECLARE_DO
kFlexibleRepresentation, kFlexibleRepresentation,
// Participate in Global Value Numbering, i.e. elimination of // Participate in Global Value Numbering, i.e. elimination of
// unnecessary recomputations. If an instruction sets this flag, it must // unnecessary recomputations. If an instruction sets this flag, it must
...@@ -523,8 +531,8 @@ class HValue: public ZoneObject { ...@@ -523,8 +531,8 @@ class HValue: public ZoneObject {
static const int kChangesToDependsFlagsLeftShift = 1; static const int kChangesToDependsFlagsLeftShift = 1;
static int ConvertChangesToDependsFlags(int flags) { static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
return flags << kChangesToDependsFlagsLeftShift; return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
} }
static HValue* cast(HValue* value) { return value; } static HValue* cast(HValue* value) { return value; }
...@@ -622,16 +630,32 @@ class HValue: public ZoneObject { ...@@ -622,16 +630,32 @@ class HValue: public ZoneObject {
void ClearFlag(Flag f) { flags_ &= ~(1 << f); } void ClearFlag(Flag f) { flags_ &= ~(1 << f); }
bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; } bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; }
void SetAllSideEffects() { flags_ |= AllSideEffects(); } GVNFlagSet gvn_flags() const { return gvn_flags_; }
void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); } void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); }
bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; } void ClearGVNFlag(GVNFlag f) { gvn_flags_.Remove(f); }
bool CheckGVNFlag(GVNFlag f) const { return gvn_flags_.Contains(f); }
void SetAllSideEffects() { gvn_flags_.Add(AllSideEffectsFlagSet()); }
void ClearAllSideEffects() {
gvn_flags_.Remove(AllSideEffectsFlagSet());
}
bool HasSideEffects() const {
return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
}
bool HasObservableSideEffects() const { bool HasObservableSideEffects() const {
return (flags_ & ObservableSideEffects()) != 0; return gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
} }
int ChangesFlags() const { return flags_ & ChangesFlagsMask(); } GVNFlagSet ChangesFlags() const {
int ObservableChangesFlags() const { GVNFlagSet result = gvn_flags_;
return flags_ & ChangesFlagsMask() & ObservableSideEffects(); result.Intersect(AllChangesFlagSet());
return result;
}
GVNFlagSet ObservableChangesFlags() const {
GVNFlagSet result = gvn_flags_;
result.Intersect(AllChangesFlagSet());
result.Intersect(AllObservableSideEffectsFlagSet());
return result;
} }
Range* range() const { return range_; } Range* range() const { return range_; }
...@@ -697,25 +721,28 @@ class HValue: public ZoneObject { ...@@ -697,25 +721,28 @@ class HValue: public ZoneObject {
representation_ = r; representation_ = r;
} }
private: static GVNFlagSet AllChangesFlagSet() {
static int ChangesFlagsMask() { GVNFlagSet result;
int result = 0;
// Create changes mask. // Create changes mask.
#define ADD_FLAG(type) result |= (1 << kChanges##type); #define ADD_FLAG(type) result.Add(kChanges##type);
GVN_FLAG_LIST(ADD_FLAG) GVN_FLAG_LIST(ADD_FLAG)
#undef ADD_FLAG #undef ADD_FLAG
return result; return result;
} }
// A flag mask to mark an instruction as having arbitrary side effects. // A flag mask to mark an instruction as having arbitrary side effects.
static int AllSideEffects() { static GVNFlagSet AllSideEffectsFlagSet() {
return ChangesFlagsMask() & ~(1 << kChangesOsrEntries); GVNFlagSet result = AllChangesFlagSet();
result.Remove(kChangesOsrEntries);
return result;
} }
// A flag mask of all side effects that can make observable changes in // A flag mask of all side effects that can make observable changes in
// an executing program (i.e. are not safe to repeat, move or remove); // an executing program (i.e. are not safe to repeat, move or remove);
static int ObservableSideEffects() { static GVNFlagSet AllObservableSideEffectsFlagSet() {
return ChangesFlagsMask() & ~(1 << kChangesElementsKind); GVNFlagSet result = AllChangesFlagSet();
result.Remove(kChangesElementsKind);
return result;
} }
// Remove the matching use from the use list if present. Returns the // Remove the matching use from the use list if present. Returns the
...@@ -735,6 +762,7 @@ class HValue: public ZoneObject { ...@@ -735,6 +762,7 @@ class HValue: public ZoneObject {
HUseListNode* use_list_; HUseListNode* use_list_;
Range* range_; Range* range_;
int flags_; int flags_;
GVNFlagSet gvn_flags_;
DISALLOW_COPY_AND_ASSIGN(HValue); DISALLOW_COPY_AND_ASSIGN(HValue);
}; };
...@@ -772,7 +800,7 @@ class HInstruction: public HValue { ...@@ -772,7 +800,7 @@ class HInstruction: public HValue {
: next_(NULL), : next_(NULL),
previous_(NULL), previous_(NULL),
position_(RelocInfo::kNoPosition) { position_(RelocInfo::kNoPosition) {
SetFlag(kDependsOnOsrEntries); SetGVNFlag(kDependsOnOsrEntries);
} }
virtual void DeleteFromGraph() { Unlink(); } virtual void DeleteFromGraph() { Unlink(); }
...@@ -1716,8 +1744,8 @@ class HJSArrayLength: public HTemplateInstruction<2> { ...@@ -1716,8 +1744,8 @@ class HJSArrayLength: public HTemplateInstruction<2> {
SetOperandAt(1, typecheck); SetOperandAt(1, typecheck);
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnArrayLengths); SetGVNFlag(kDependsOnArrayLengths);
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -1741,7 +1769,7 @@ class HFixedArrayBaseLength: public HUnaryOperation { ...@@ -1741,7 +1769,7 @@ class HFixedArrayBaseLength: public HUnaryOperation {
explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) { explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) {
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnArrayLengths); SetGVNFlag(kDependsOnArrayLengths);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -1760,7 +1788,7 @@ class HElementsKind: public HUnaryOperation { ...@@ -1760,7 +1788,7 @@ class HElementsKind: public HUnaryOperation {
explicit HElementsKind(HValue* value) : HUnaryOperation(value) { explicit HElementsKind(HValue* value) : HUnaryOperation(value) {
set_representation(Representation::Integer32()); set_representation(Representation::Integer32());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnElementsKind); SetGVNFlag(kDependsOnElementsKind);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -1886,8 +1914,8 @@ class HLoadElements: public HUnaryOperation { ...@@ -1886,8 +1914,8 @@ class HLoadElements: public HUnaryOperation {
explicit HLoadElements(HValue* value) : HUnaryOperation(value) { explicit HLoadElements(HValue* value) : HUnaryOperation(value) {
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
SetFlag(kDependsOnElementsKind); SetGVNFlag(kDependsOnElementsKind);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -1937,7 +1965,7 @@ class HCheckMap: public HTemplateInstruction<2> { ...@@ -1937,7 +1965,7 @@ class HCheckMap: public HTemplateInstruction<2> {
SetOperandAt(1, typecheck != NULL ? typecheck : value); SetOperandAt(1, typecheck != NULL ? typecheck : value);
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
has_element_transitions_ = has_element_transitions_ =
map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL) != NULL || map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL) != NULL ||
map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL) != NULL; map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL) != NULL;
...@@ -2105,7 +2133,7 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> { ...@@ -2105,7 +2133,7 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> {
HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder) HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder)
: prototype_(prototype), holder_(holder) { : prototype_(prototype), holder_(holder) {
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
} }
#ifdef DEBUG #ifdef DEBUG
...@@ -3255,7 +3283,7 @@ class HSar: public HBitwiseBinaryOperation { ...@@ -3255,7 +3283,7 @@ class HSar: public HBitwiseBinaryOperation {
class HOsrEntry: public HTemplateInstruction<0> { class HOsrEntry: public HTemplateInstruction<0> {
public: public:
explicit HOsrEntry(int ast_id) : ast_id_(ast_id) { explicit HOsrEntry(int ast_id) : ast_id_(ast_id) {
SetFlag(kChangesOsrEntries); SetGVNFlag(kChangesOsrEntries);
} }
int ast_id() const { return ast_id_; } int ast_id() const { return ast_id_; }
...@@ -3343,7 +3371,7 @@ class HLoadGlobalCell: public HTemplateInstruction<0> { ...@@ -3343,7 +3371,7 @@ class HLoadGlobalCell: public HTemplateInstruction<0> {
: cell_(cell), details_(details) { : cell_(cell), details_(details) {
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnGlobalVars); SetGVNFlag(kDependsOnGlobalVars);
} }
Handle<JSGlobalPropertyCell> cell() const { return cell_; } Handle<JSGlobalPropertyCell> cell() const { return cell_; }
...@@ -3422,7 +3450,7 @@ class HStoreGlobalCell: public HUnaryOperation { ...@@ -3422,7 +3450,7 @@ class HStoreGlobalCell: public HUnaryOperation {
: HUnaryOperation(value), : HUnaryOperation(value),
cell_(cell), cell_(cell),
details_(details) { details_(details) {
SetFlag(kChangesGlobalVars); SetGVNFlag(kChangesGlobalVars);
} }
Handle<JSGlobalPropertyCell> cell() const { return cell_; } Handle<JSGlobalPropertyCell> cell() const { return cell_; }
...@@ -3513,7 +3541,7 @@ class HLoadContextSlot: public HUnaryOperation { ...@@ -3513,7 +3541,7 @@ class HLoadContextSlot: public HUnaryOperation {
} }
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnContextSlots); SetGVNFlag(kDependsOnContextSlots);
} }
int slot_index() const { return slot_index_; } int slot_index() const { return slot_index_; }
...@@ -3566,7 +3594,7 @@ class HStoreContextSlot: public HTemplateInstruction<2> { ...@@ -3566,7 +3594,7 @@ class HStoreContextSlot: public HTemplateInstruction<2> {
: slot_index_(slot_index), mode_(mode) { : slot_index_(slot_index), mode_(mode) {
SetOperandAt(0, context); SetOperandAt(0, context);
SetOperandAt(1, value); SetOperandAt(1, value);
SetFlag(kChangesContextSlots); SetGVNFlag(kChangesContextSlots);
} }
HValue* context() { return OperandAt(0); } HValue* context() { return OperandAt(0); }
...@@ -3608,11 +3636,11 @@ class HLoadNamedField: public HUnaryOperation { ...@@ -3608,11 +3636,11 @@ class HLoadNamedField: public HUnaryOperation {
offset_(offset) { offset_(offset) {
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
if (is_in_object) { if (is_in_object) {
SetFlag(kDependsOnInobjectFields); SetGVNFlag(kDependsOnInobjectFields);
} else { } else {
SetFlag(kDependsOnBackingStoreFields); SetGVNFlag(kDependsOnBackingStoreFields);
} }
} }
...@@ -3706,7 +3734,7 @@ class HLoadFunctionPrototype: public HUnaryOperation { ...@@ -3706,7 +3734,7 @@ class HLoadFunctionPrototype: public HUnaryOperation {
: HUnaryOperation(function) { : HUnaryOperation(function) {
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnCalls); SetGVNFlag(kDependsOnCalls);
} }
HValue* function() { return OperandAt(0); } HValue* function() { return OperandAt(0); }
...@@ -3728,7 +3756,7 @@ class HLoadKeyedFastElement: public HTemplateInstruction<2> { ...@@ -3728,7 +3756,7 @@ class HLoadKeyedFastElement: public HTemplateInstruction<2> {
SetOperandAt(0, obj); SetOperandAt(0, obj);
SetOperandAt(1, key); SetOperandAt(1, key);
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kDependsOnArrayElements); SetGVNFlag(kDependsOnArrayElements);
SetFlag(kUseGVN); SetFlag(kUseGVN);
} }
...@@ -3759,7 +3787,7 @@ class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { ...@@ -3759,7 +3787,7 @@ class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> {
SetOperandAt(0, elements); SetOperandAt(0, elements);
SetOperandAt(1, key); SetOperandAt(1, key);
set_representation(Representation::Double()); set_representation(Representation::Double());
SetFlag(kDependsOnDoubleArrayElements); SetGVNFlag(kDependsOnDoubleArrayElements);
SetFlag(kUseGVN); SetFlag(kUseGVN);
} }
...@@ -3796,9 +3824,9 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { ...@@ -3796,9 +3824,9 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> {
} else { } else {
set_representation(Representation::Integer32()); set_representation(Representation::Integer32());
} }
SetFlag(kDependsOnSpecializedArrayElements); SetGVNFlag(kDependsOnSpecializedArrayElements);
// Native code could change the specialized array. // Native code could change the specialized array.
SetFlag(kDependsOnCalls); SetGVNFlag(kDependsOnCalls);
SetFlag(kUseGVN); SetFlag(kUseGVN);
} }
...@@ -3868,9 +3896,9 @@ class HStoreNamedField: public HTemplateInstruction<2> { ...@@ -3868,9 +3896,9 @@ class HStoreNamedField: public HTemplateInstruction<2> {
SetOperandAt(0, obj); SetOperandAt(0, obj);
SetOperandAt(1, val); SetOperandAt(1, val);
if (is_in_object_) { if (is_in_object_) {
SetFlag(kChangesInobjectFields); SetGVNFlag(kChangesInobjectFields);
} else { } else {
SetFlag(kChangesBackingStoreFields); SetGVNFlag(kChangesBackingStoreFields);
} }
} }
...@@ -3945,7 +3973,7 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> { ...@@ -3945,7 +3973,7 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> {
SetOperandAt(0, obj); SetOperandAt(0, obj);
SetOperandAt(1, key); SetOperandAt(1, key);
SetOperandAt(2, val); SetOperandAt(2, val);
SetFlag(kChangesArrayElements); SetGVNFlag(kChangesArrayElements);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -3987,7 +4015,7 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> { ...@@ -3987,7 +4015,7 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> {
SetOperandAt(0, elements); SetOperandAt(0, elements);
SetOperandAt(1, key); SetOperandAt(1, key);
SetOperandAt(2, val); SetOperandAt(2, val);
SetFlag(kChangesDoubleArrayElements); SetGVNFlag(kChangesDoubleArrayElements);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -4021,7 +4049,7 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { ...@@ -4021,7 +4049,7 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> {
HValue* val, HValue* val,
ElementsKind elements_kind) ElementsKind elements_kind)
: elements_kind_(elements_kind) { : elements_kind_(elements_kind) {
SetFlag(kChangesSpecializedArrayElements); SetGVNFlag(kChangesSpecializedArrayElements);
SetOperandAt(0, external_elements); SetOperandAt(0, external_elements);
SetOperandAt(1, key); SetOperandAt(1, key);
SetOperandAt(2, val); SetOperandAt(2, val);
...@@ -4099,7 +4127,8 @@ class HTransitionElementsKind: public HTemplateInstruction<1> { ...@@ -4099,7 +4127,8 @@ class HTransitionElementsKind: public HTemplateInstruction<1> {
transitioned_map_(transitioned_map) { transitioned_map_(transitioned_map) {
SetOperandAt(0, object); SetOperandAt(0, object);
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kChangesElementsKind); SetGVNFlag(kChangesMaps);
SetGVNFlag(kChangesElementsKind);
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
} }
...@@ -4134,7 +4163,7 @@ class HStringAdd: public HBinaryOperation { ...@@ -4134,7 +4163,7 @@ class HStringAdd: public HBinaryOperation {
: HBinaryOperation(context, left, right) { : HBinaryOperation(context, left, right) {
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -4160,7 +4189,7 @@ class HStringCharCodeAt: public HTemplateInstruction<3> { ...@@ -4160,7 +4189,7 @@ class HStringCharCodeAt: public HTemplateInstruction<3> {
SetOperandAt(2, index); SetOperandAt(2, index);
set_representation(Representation::Integer32()); set_representation(Representation::Integer32());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
...@@ -4215,7 +4244,7 @@ class HStringLength: public HUnaryOperation { ...@@ -4215,7 +4244,7 @@ class HStringLength: public HUnaryOperation {
explicit HStringLength(HValue* string) : HUnaryOperation(string) { explicit HStringLength(HValue* string) : HUnaryOperation(string) {
set_representation(Representation::Tagged()); set_representation(Representation::Tagged());
SetFlag(kUseGVN); SetFlag(kUseGVN);
SetFlag(kDependsOnMaps); SetGVNFlag(kDependsOnMaps);
} }
virtual Representation RequiredInputRepresentation(int index) { virtual Representation RequiredInputRepresentation(int index) {
......
...@@ -1110,10 +1110,10 @@ HValueMap::HValueMap(Zone* zone, const HValueMap* other) ...@@ -1110,10 +1110,10 @@ HValueMap::HValueMap(Zone* zone, const HValueMap* other)
} }
void HValueMap::Kill(int flags) { void HValueMap::Kill(GVNFlagSet flags) {
int depends_flags = HValue::ConvertChangesToDependsFlags(flags); GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(flags);
if ((present_flags_ & depends_flags) == 0) return; if (!present_flags_.ContainsAnyOf(depends_flags)) return;
present_flags_ = 0; present_flags_.RemoveAll();
for (int i = 0; i < array_size_; ++i) { for (int i = 0; i < array_size_; ++i) {
HValue* value = array_[i].value; HValue* value = array_[i].value;
if (value != NULL) { if (value != NULL) {
...@@ -1122,7 +1122,8 @@ void HValueMap::Kill(int flags) { ...@@ -1122,7 +1122,8 @@ void HValueMap::Kill(int flags) {
int next; int next;
for (int current = array_[i].next; current != kNil; current = next) { for (int current = array_[i].next; current != kNil; current = next) {
next = lists_[current].next; next = lists_[current].next;
if ((lists_[current].value->flags() & depends_flags) != 0) { HValue* value = lists_[current].value;
if (value->gvn_flags().ContainsAnyOf(depends_flags)) {
// Drop it. // Drop it.
count_--; count_--;
lists_[current].next = free_list_head_; lists_[current].next = free_list_head_;
...@@ -1131,13 +1132,14 @@ void HValueMap::Kill(int flags) { ...@@ -1131,13 +1132,14 @@ void HValueMap::Kill(int flags) {
// Keep it. // Keep it.
lists_[current].next = kept; lists_[current].next = kept;
kept = current; kept = current;
present_flags_ |= lists_[current].value->flags(); present_flags_.Add(value->gvn_flags());
} }
} }
array_[i].next = kept; array_[i].next = kept;
// Now possibly drop directly indexed element. // Now possibly drop directly indexed element.
if ((array_[i].value->flags() & depends_flags) != 0) { // Drop it. value = array_[i].value;
if (value->gvn_flags().ContainsAnyOf(depends_flags)) { // Drop it.
count_--; count_--;
int head = array_[i].next; int head = array_[i].next;
if (head == kNil) { if (head == kNil) {
...@@ -1149,7 +1151,7 @@ void HValueMap::Kill(int flags) { ...@@ -1149,7 +1151,7 @@ void HValueMap::Kill(int flags) {
free_list_head_ = head; free_list_head_ = head;
} }
} else { } else {
present_flags_ |= array_[i].value->flags(); // Keep it. present_flags_.Add(value->gvn_flags()); // Keep it.
} }
} }
} }
...@@ -1356,8 +1358,8 @@ class HGlobalValueNumberer BASE_EMBEDDED { ...@@ -1356,8 +1358,8 @@ class HGlobalValueNumberer BASE_EMBEDDED {
loop_side_effects_(graph->blocks()->length()), loop_side_effects_(graph->blocks()->length()),
visited_on_paths_(graph->zone(), graph->blocks()->length()) { visited_on_paths_(graph->zone(), graph->blocks()->length()) {
ASSERT(info->isolate()->heap()->allow_allocation(false)); ASSERT(info->isolate()->heap()->allow_allocation(false));
block_side_effects_.AddBlock(0, graph_->blocks()->length()); block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length());
loop_side_effects_.AddBlock(0, graph_->blocks()->length()); loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length());
} }
~HGlobalValueNumberer() { ~HGlobalValueNumberer() {
ASSERT(!info_->isolate()->heap()->allow_allocation(true)); ASSERT(!info_->isolate()->heap()->allow_allocation(true));
...@@ -1367,14 +1369,15 @@ class HGlobalValueNumberer BASE_EMBEDDED { ...@@ -1367,14 +1369,15 @@ class HGlobalValueNumberer BASE_EMBEDDED {
bool Analyze(); bool Analyze();
private: private:
int CollectSideEffectsOnPathsToDominatedBlock(HBasicBlock* dominator, GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock(
HBasicBlock* dominated); HBasicBlock* dominator,
HBasicBlock* dominated);
void AnalyzeBlock(HBasicBlock* block, HValueMap* map); void AnalyzeBlock(HBasicBlock* block, HValueMap* map);
void ComputeBlockSideEffects(); void ComputeBlockSideEffects();
void LoopInvariantCodeMotion(); void LoopInvariantCodeMotion();
void ProcessLoopBlock(HBasicBlock* block, void ProcessLoopBlock(HBasicBlock* block,
HBasicBlock* before_loop, HBasicBlock* before_loop,
int loop_kills); GVNFlagSet loop_kills);
bool AllowCodeMotion(); bool AllowCodeMotion();
bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header); bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
...@@ -1387,10 +1390,10 @@ class HGlobalValueNumberer BASE_EMBEDDED { ...@@ -1387,10 +1390,10 @@ class HGlobalValueNumberer BASE_EMBEDDED {
bool removed_side_effects_; bool removed_side_effects_;
// A map of block IDs to their side effects. // A map of block IDs to their side effects.
ZoneList<int> block_side_effects_; ZoneList<GVNFlagSet> block_side_effects_;
// A map of loop header block IDs to their loop's side effects. // A map of loop header block IDs to their loop's side effects.
ZoneList<int> loop_side_effects_; ZoneList<GVNFlagSet> loop_side_effects_;
// Used when collecting side effects on paths from dominator to // Used when collecting side effects on paths from dominator to
// dominated. // dominated.
...@@ -1415,23 +1418,24 @@ void HGlobalValueNumberer::ComputeBlockSideEffects() { ...@@ -1415,23 +1418,24 @@ void HGlobalValueNumberer::ComputeBlockSideEffects() {
HBasicBlock* block = graph_->blocks()->at(i); HBasicBlock* block = graph_->blocks()->at(i);
HInstruction* instr = block->first(); HInstruction* instr = block->first();
int id = block->block_id(); int id = block->block_id();
int side_effects = 0; GVNFlagSet side_effects;
while (instr != NULL) { while (instr != NULL) {
side_effects |= instr->ChangesFlags(); side_effects.Add(instr->ChangesFlags());
instr = instr->next(); instr = instr->next();
} }
block_side_effects_[id] |= side_effects; block_side_effects_[id].Add(side_effects);
// Loop headers are part of their loop. // Loop headers are part of their loop.
if (block->IsLoopHeader()) { if (block->IsLoopHeader()) {
loop_side_effects_[id] |= side_effects; loop_side_effects_[id].Add(side_effects);
} }
// Propagate loop side effects upwards. // Propagate loop side effects upwards.
if (block->HasParentLoopHeader()) { if (block->HasParentLoopHeader()) {
int header_id = block->parent_loop_header()->block_id(); int header_id = block->parent_loop_header()->block_id();
loop_side_effects_[header_id] |= loop_side_effects_[header_id].Add(block->IsLoopHeader()
block->IsLoopHeader() ? loop_side_effects_[id] : side_effects; ? loop_side_effects_[id]
: side_effects);
} }
} }
} }
...@@ -1441,10 +1445,10 @@ void HGlobalValueNumberer::LoopInvariantCodeMotion() { ...@@ -1441,10 +1445,10 @@ void HGlobalValueNumberer::LoopInvariantCodeMotion() {
for (int i = graph_->blocks()->length() - 1; i >= 0; --i) { for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
HBasicBlock* block = graph_->blocks()->at(i); HBasicBlock* block = graph_->blocks()->at(i);
if (block->IsLoopHeader()) { if (block->IsLoopHeader()) {
int side_effects = loop_side_effects_[block->block_id()]; GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n", TraceGVN("Try loop invariant motion for block B%d effects=0x%x\n",
block->block_id(), block->block_id(),
side_effects); side_effects.ToIntegral());
HBasicBlock* last = block->loop_information()->GetLastBackEdge(); HBasicBlock* last = block->loop_information()->GetLastBackEdge();
for (int j = block->block_id(); j <= last->block_id(); ++j) { for (int j = block->block_id(); j <= last->block_id(); ++j) {
...@@ -1457,17 +1461,17 @@ void HGlobalValueNumberer::LoopInvariantCodeMotion() { ...@@ -1457,17 +1461,17 @@ void HGlobalValueNumberer::LoopInvariantCodeMotion() {
void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block, void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block,
HBasicBlock* loop_header, HBasicBlock* loop_header,
int loop_kills) { GVNFlagSet loop_kills) {
HBasicBlock* pre_header = loop_header->predecessors()->at(0); HBasicBlock* pre_header = loop_header->predecessors()->at(0);
int depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills); GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n", TraceGVN("Loop invariant motion for B%d depends_flags=0x%x\n",
block->block_id(), block->block_id(),
depends_flags); depends_flags.ToIntegral());
HInstruction* instr = block->first(); HInstruction* instr = block->first();
while (instr != NULL) { while (instr != NULL) {
HInstruction* next = instr->next(); HInstruction* next = instr->next();
if (instr->CheckFlag(HValue::kUseGVN) && if (instr->CheckFlag(HValue::kUseGVN) &&
(instr->flags() & depends_flags) == 0) { !instr->gvn_flags().ContainsAnyOf(depends_flags)) {
TraceGVN("Checking instruction %d (%s)\n", TraceGVN("Checking instruction %d (%s)\n",
instr->id(), instr->id(),
instr->Mnemonic()); instr->Mnemonic());
...@@ -1503,20 +1507,20 @@ bool HGlobalValueNumberer::ShouldMove(HInstruction* instr, ...@@ -1503,20 +1507,20 @@ bool HGlobalValueNumberer::ShouldMove(HInstruction* instr,
} }
int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock( GVNFlagSet HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock(
HBasicBlock* dominator, HBasicBlock* dominated) { HBasicBlock* dominator, HBasicBlock* dominated) {
int side_effects = 0; GVNFlagSet side_effects;
for (int i = 0; i < dominated->predecessors()->length(); ++i) { for (int i = 0; i < dominated->predecessors()->length(); ++i) {
HBasicBlock* block = dominated->predecessors()->at(i); HBasicBlock* block = dominated->predecessors()->at(i);
if (dominator->block_id() < block->block_id() && if (dominator->block_id() < block->block_id() &&
block->block_id() < dominated->block_id() && block->block_id() < dominated->block_id() &&
visited_on_paths_.Add(block->block_id())) { visited_on_paths_.Add(block->block_id())) {
side_effects |= block_side_effects_[block->block_id()]; side_effects.Add(block_side_effects_[block->block_id()]);
if (block->IsLoopHeader()) { if (block->IsLoopHeader()) {
side_effects |= loop_side_effects_[block->block_id()]; side_effects.Add(loop_side_effects_[block->block_id()]);
} }
side_effects |= CollectSideEffectsOnPathsToDominatedBlock( side_effects.Add(CollectSideEffectsOnPathsToDominatedBlock(
dominator, block); dominator, block));
} }
} }
return side_effects; return side_effects;
...@@ -1537,8 +1541,8 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) { ...@@ -1537,8 +1541,8 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) {
HInstruction* instr = block->first(); HInstruction* instr = block->first();
while (instr != NULL) { while (instr != NULL) {
HInstruction* next = instr->next(); HInstruction* next = instr->next();
int flags = instr->ChangesFlags(); GVNFlagSet flags = instr->ChangesFlags();
if (flags != 0) { if (!flags.IsEmpty()) {
// Clear all instructions in the map that are affected by side effects. // Clear all instructions in the map that are affected by side effects.
map->Kill(flags); map->Kill(flags);
TraceGVN("Instruction %d kills\n", instr->id()); TraceGVN("Instruction %d kills\n", instr->id());
...@@ -3597,7 +3601,7 @@ HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object, ...@@ -3597,7 +3601,7 @@ HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
instr->set_transition(transition); instr->set_transition(transition);
// TODO(fschneider): Record the new map type of the object in the IR to // TODO(fschneider): Record the new map type of the object in the IR to
// enable elimination of redundant checks after the transition store. // enable elimination of redundant checks after the transition store.
instr->SetFlag(HValue::kChangesMaps); instr->SetGVNFlag(kChangesMaps);
} }
return instr; return instr;
} }
......
// Copyright 2011 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -1056,10 +1056,10 @@ class HValueMap: public ZoneObject { ...@@ -1056,10 +1056,10 @@ class HValueMap: public ZoneObject {
Resize(kInitialSize); Resize(kInitialSize);
} }
void Kill(int flags); void Kill(GVNFlagSet flags);
void Add(HValue* value) { void Add(HValue* value) {
present_flags_ |= value->flags(); present_flags_.Add(value->gvn_flags());
Insert(value); Insert(value);
} }
...@@ -1092,7 +1092,8 @@ class HValueMap: public ZoneObject { ...@@ -1092,7 +1092,8 @@ class HValueMap: public ZoneObject {
int array_size_; int array_size_;
int lists_size_; int lists_size_;
int count_; // The number of values stored in the HValueMap. int count_; // The number of values stored in the HValueMap.
int present_flags_; // All flags that are in any value in the HValueMap. GVNFlagSet present_flags_; // All flags that are in any value in the
// HValueMap.
HValueMapListElement* array_; // Primary store - contains the first value HValueMapListElement* array_; // Primary store - contains the first value
// with a given hash. Colliding elements are stored in linked lists. // with a given hash. Colliding elements are stored in linked lists.
HValueMapListElement* lists_; // The linked lists containing hash collisions. HValueMapListElement* lists_; // The linked lists containing hash collisions.
......
// Copyright 2011 the V8 project authors. All rights reserved. // Copyright 2012 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
...@@ -931,9 +931,17 @@ class EnumSet { ...@@ -931,9 +931,17 @@ class EnumSet {
explicit EnumSet(T bits = 0) : bits_(bits) {} explicit EnumSet(T bits = 0) : bits_(bits) {}
bool IsEmpty() const { return bits_ == 0; } bool IsEmpty() const { return bits_ == 0; }
bool Contains(E element) const { return (bits_ & Mask(element)) != 0; } bool Contains(E element) const { return (bits_ & Mask(element)) != 0; }
bool ContainsAnyOf(const EnumSet& set) const {
return (bits_ & set.bits_) != 0;
}
void Add(E element) { bits_ |= Mask(element); } void Add(E element) { bits_ |= Mask(element); }
void Add(const EnumSet& set) { bits_ |= set.bits_; }
void Remove(E element) { bits_ &= ~Mask(element); } void Remove(E element) { bits_ &= ~Mask(element); }
void Remove(const EnumSet& set) { bits_ &= ~set.bits_; }
void RemoveAll() { bits_ = 0; }
void Intersect(const EnumSet& set) { bits_ &= set.bits_; }
T ToIntegral() const { return bits_; } T ToIntegral() const { return bits_; }
bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
private: private:
T Mask(E element) const { T Mask(E element) const {
......
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