Index: src/hydrogen-instructions.h |
diff --git a/src/hydrogen-instructions.h b/src/hydrogen-instructions.h |
index 5082e4d3ff038b938868559af6ecb1724811e0d3..b959017e5f95111f39e63ec395d6b0ea4ac10e8b 100644 |
--- a/src/hydrogen-instructions.h |
+++ b/src/hydrogen-instructions.h |
@@ -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 { |
public: |
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 { |
- // Declare global value numbering flags. |
- #define DECLARE_DO(type) kChanges##type, kDependsOn##type, |
- GVN_FLAG_LIST(DECLARE_DO) |
- #undef DECLARE_DO |
kFlexibleRepresentation, |
// Participate in Global Value Numbering, i.e. elimination of |
// unnecessary recomputations. If an instruction sets this flag, it must |
@@ -523,8 +531,8 @@ class HValue: public ZoneObject { |
static const int kChangesToDependsFlagsLeftShift = 1; |
- static int ConvertChangesToDependsFlags(int flags) { |
- return flags << kChangesToDependsFlagsLeftShift; |
+ static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) { |
+ return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift); |
} |
static HValue* cast(HValue* value) { return value; } |
@@ -622,16 +630,32 @@ class HValue: public ZoneObject { |
void ClearFlag(Flag f) { flags_ &= ~(1 << f); } |
bool CheckFlag(Flag f) const { return (flags_ & (1 << f)) != 0; } |
- void SetAllSideEffects() { flags_ |= AllSideEffects(); } |
- void ClearAllSideEffects() { flags_ &= ~AllSideEffects(); } |
- bool HasSideEffects() const { return (flags_ & AllSideEffects()) != 0; } |
+ GVNFlagSet gvn_flags() const { return gvn_flags_; } |
+ void SetGVNFlag(GVNFlag f) { gvn_flags_.Add(f); } |
+ 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 { |
- return (flags_ & ObservableSideEffects()) != 0; |
+ return gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet()); |
} |
- int ChangesFlags() const { return flags_ & ChangesFlagsMask(); } |
- int ObservableChangesFlags() const { |
- return flags_ & ChangesFlagsMask() & ObservableSideEffects(); |
+ GVNFlagSet ChangesFlags() const { |
+ GVNFlagSet result = gvn_flags_; |
+ 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_; } |
@@ -697,25 +721,28 @@ class HValue: public ZoneObject { |
representation_ = r; |
} |
- private: |
- static int ChangesFlagsMask() { |
- int result = 0; |
+ static GVNFlagSet AllChangesFlagSet() { |
+ GVNFlagSet result; |
// Create changes mask. |
-#define ADD_FLAG(type) result |= (1 << kChanges##type); |
+#define ADD_FLAG(type) result.Add(kChanges##type); |
GVN_FLAG_LIST(ADD_FLAG) |
#undef ADD_FLAG |
return result; |
} |
// A flag mask to mark an instruction as having arbitrary side effects. |
- static int AllSideEffects() { |
- return ChangesFlagsMask() & ~(1 << kChangesOsrEntries); |
+ static GVNFlagSet AllSideEffectsFlagSet() { |
+ GVNFlagSet result = AllChangesFlagSet(); |
+ result.Remove(kChangesOsrEntries); |
+ return result; |
} |
// 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); |
- static int ObservableSideEffects() { |
- return ChangesFlagsMask() & ~(1 << kChangesElementsKind); |
+ static GVNFlagSet AllObservableSideEffectsFlagSet() { |
+ GVNFlagSet result = AllChangesFlagSet(); |
+ result.Remove(kChangesElementsKind); |
+ return result; |
} |
// Remove the matching use from the use list if present. Returns the |
@@ -735,6 +762,7 @@ class HValue: public ZoneObject { |
HUseListNode* use_list_; |
Range* range_; |
int flags_; |
+ GVNFlagSet gvn_flags_; |
DISALLOW_COPY_AND_ASSIGN(HValue); |
}; |
@@ -772,7 +800,7 @@ class HInstruction: public HValue { |
: next_(NULL), |
previous_(NULL), |
position_(RelocInfo::kNoPosition) { |
- SetFlag(kDependsOnOsrEntries); |
+ SetGVNFlag(kDependsOnOsrEntries); |
} |
virtual void DeleteFromGraph() { Unlink(); } |
@@ -1716,8 +1744,8 @@ class HJSArrayLength: public HTemplateInstruction<2> { |
SetOperandAt(1, typecheck); |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnArrayLengths); |
- SetFlag(kDependsOnMaps); |
+ SetGVNFlag(kDependsOnArrayLengths); |
+ SetGVNFlag(kDependsOnMaps); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -1741,7 +1769,7 @@ class HFixedArrayBaseLength: public HUnaryOperation { |
explicit HFixedArrayBaseLength(HValue* value) : HUnaryOperation(value) { |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnArrayLengths); |
+ SetGVNFlag(kDependsOnArrayLengths); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -1760,7 +1788,7 @@ class HElementsKind: public HUnaryOperation { |
explicit HElementsKind(HValue* value) : HUnaryOperation(value) { |
set_representation(Representation::Integer32()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnElementsKind); |
+ SetGVNFlag(kDependsOnElementsKind); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -1886,8 +1914,8 @@ class HLoadElements: public HUnaryOperation { |
explicit HLoadElements(HValue* value) : HUnaryOperation(value) { |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnMaps); |
- SetFlag(kDependsOnElementsKind); |
+ SetGVNFlag(kDependsOnMaps); |
+ SetGVNFlag(kDependsOnElementsKind); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -1937,7 +1965,7 @@ class HCheckMap: public HTemplateInstruction<2> { |
SetOperandAt(1, typecheck != NULL ? typecheck : value); |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnMaps); |
+ SetGVNFlag(kDependsOnMaps); |
has_element_transitions_ = |
map->LookupElementsTransitionMap(FAST_DOUBLE_ELEMENTS, NULL) != NULL || |
map->LookupElementsTransitionMap(FAST_ELEMENTS, NULL) != NULL; |
@@ -2105,7 +2133,7 @@ class HCheckPrototypeMaps: public HTemplateInstruction<0> { |
HCheckPrototypeMaps(Handle<JSObject> prototype, Handle<JSObject> holder) |
: prototype_(prototype), holder_(holder) { |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnMaps); |
+ SetGVNFlag(kDependsOnMaps); |
} |
#ifdef DEBUG |
@@ -3255,7 +3283,7 @@ class HSar: public HBitwiseBinaryOperation { |
class HOsrEntry: public HTemplateInstruction<0> { |
public: |
explicit HOsrEntry(int ast_id) : ast_id_(ast_id) { |
- SetFlag(kChangesOsrEntries); |
+ SetGVNFlag(kChangesOsrEntries); |
} |
int ast_id() const { return ast_id_; } |
@@ -3343,7 +3371,7 @@ class HLoadGlobalCell: public HTemplateInstruction<0> { |
: cell_(cell), details_(details) { |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnGlobalVars); |
+ SetGVNFlag(kDependsOnGlobalVars); |
} |
Handle<JSGlobalPropertyCell> cell() const { return cell_; } |
@@ -3422,7 +3450,7 @@ class HStoreGlobalCell: public HUnaryOperation { |
: HUnaryOperation(value), |
cell_(cell), |
details_(details) { |
- SetFlag(kChangesGlobalVars); |
+ SetGVNFlag(kChangesGlobalVars); |
} |
Handle<JSGlobalPropertyCell> cell() const { return cell_; } |
@@ -3513,7 +3541,7 @@ class HLoadContextSlot: public HUnaryOperation { |
} |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnContextSlots); |
+ SetGVNFlag(kDependsOnContextSlots); |
} |
int slot_index() const { return slot_index_; } |
@@ -3566,7 +3594,7 @@ class HStoreContextSlot: public HTemplateInstruction<2> { |
: slot_index_(slot_index), mode_(mode) { |
SetOperandAt(0, context); |
SetOperandAt(1, value); |
- SetFlag(kChangesContextSlots); |
+ SetGVNFlag(kChangesContextSlots); |
} |
HValue* context() { return OperandAt(0); } |
@@ -3608,11 +3636,11 @@ class HLoadNamedField: public HUnaryOperation { |
offset_(offset) { |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnMaps); |
+ SetGVNFlag(kDependsOnMaps); |
if (is_in_object) { |
- SetFlag(kDependsOnInobjectFields); |
+ SetGVNFlag(kDependsOnInobjectFields); |
} else { |
- SetFlag(kDependsOnBackingStoreFields); |
+ SetGVNFlag(kDependsOnBackingStoreFields); |
} |
} |
@@ -3706,7 +3734,7 @@ class HLoadFunctionPrototype: public HUnaryOperation { |
: HUnaryOperation(function) { |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnCalls); |
+ SetGVNFlag(kDependsOnCalls); |
} |
HValue* function() { return OperandAt(0); } |
@@ -3728,7 +3756,7 @@ class HLoadKeyedFastElement: public HTemplateInstruction<2> { |
SetOperandAt(0, obj); |
SetOperandAt(1, key); |
set_representation(Representation::Tagged()); |
- SetFlag(kDependsOnArrayElements); |
+ SetGVNFlag(kDependsOnArrayElements); |
SetFlag(kUseGVN); |
} |
@@ -3759,7 +3787,7 @@ class HLoadKeyedFastDoubleElement: public HTemplateInstruction<2> { |
SetOperandAt(0, elements); |
SetOperandAt(1, key); |
set_representation(Representation::Double()); |
- SetFlag(kDependsOnDoubleArrayElements); |
+ SetGVNFlag(kDependsOnDoubleArrayElements); |
SetFlag(kUseGVN); |
} |
@@ -3796,9 +3824,9 @@ class HLoadKeyedSpecializedArrayElement: public HTemplateInstruction<2> { |
} else { |
set_representation(Representation::Integer32()); |
} |
- SetFlag(kDependsOnSpecializedArrayElements); |
+ SetGVNFlag(kDependsOnSpecializedArrayElements); |
// Native code could change the specialized array. |
- SetFlag(kDependsOnCalls); |
+ SetGVNFlag(kDependsOnCalls); |
SetFlag(kUseGVN); |
} |
@@ -3868,9 +3896,9 @@ class HStoreNamedField: public HTemplateInstruction<2> { |
SetOperandAt(0, obj); |
SetOperandAt(1, val); |
if (is_in_object_) { |
- SetFlag(kChangesInobjectFields); |
+ SetGVNFlag(kChangesInobjectFields); |
} else { |
- SetFlag(kChangesBackingStoreFields); |
+ SetGVNFlag(kChangesBackingStoreFields); |
} |
} |
@@ -3945,7 +3973,7 @@ class HStoreKeyedFastElement: public HTemplateInstruction<3> { |
SetOperandAt(0, obj); |
SetOperandAt(1, key); |
SetOperandAt(2, val); |
- SetFlag(kChangesArrayElements); |
+ SetGVNFlag(kChangesArrayElements); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -3987,7 +4015,7 @@ class HStoreKeyedFastDoubleElement: public HTemplateInstruction<3> { |
SetOperandAt(0, elements); |
SetOperandAt(1, key); |
SetOperandAt(2, val); |
- SetFlag(kChangesDoubleArrayElements); |
+ SetGVNFlag(kChangesDoubleArrayElements); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -4021,7 +4049,7 @@ class HStoreKeyedSpecializedArrayElement: public HTemplateInstruction<3> { |
HValue* val, |
ElementsKind elements_kind) |
: elements_kind_(elements_kind) { |
- SetFlag(kChangesSpecializedArrayElements); |
+ SetGVNFlag(kChangesSpecializedArrayElements); |
SetOperandAt(0, external_elements); |
SetOperandAt(1, key); |
SetOperandAt(2, val); |
@@ -4099,7 +4127,8 @@ class HTransitionElementsKind: public HTemplateInstruction<1> { |
transitioned_map_(transitioned_map) { |
SetOperandAt(0, object); |
SetFlag(kUseGVN); |
- SetFlag(kChangesElementsKind); |
+ SetGVNFlag(kChangesMaps); |
+ SetGVNFlag(kChangesElementsKind); |
set_representation(Representation::Tagged()); |
} |
@@ -4134,7 +4163,7 @@ class HStringAdd: public HBinaryOperation { |
: HBinaryOperation(context, left, right) { |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnMaps); |
+ SetGVNFlag(kDependsOnMaps); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -4160,7 +4189,7 @@ class HStringCharCodeAt: public HTemplateInstruction<3> { |
SetOperandAt(2, index); |
set_representation(Representation::Integer32()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnMaps); |
+ SetGVNFlag(kDependsOnMaps); |
} |
virtual Representation RequiredInputRepresentation(int index) { |
@@ -4215,7 +4244,7 @@ class HStringLength: public HUnaryOperation { |
explicit HStringLength(HValue* string) : HUnaryOperation(string) { |
set_representation(Representation::Tagged()); |
SetFlag(kUseGVN); |
- SetFlag(kDependsOnMaps); |
+ SetGVNFlag(kDependsOnMaps); |
} |
virtual Representation RequiredInputRepresentation(int index) { |