Split GVN flags from flags in Hydrogen instructions.
authordanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 20 Jan 2012 14:08:20 +0000 (14:08 +0000)
committerdanno@chromium.org <danno@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Fri, 20 Jan 2012 14:08:20 +0000 (14:08 +0000)
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

src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen.cc
src/hydrogen.h
src/utils.h

index 887e80a..ee45ae5 100644 (file)
@@ -416,18 +416,18 @@ void HValue::PrintRangeTo(StringStream* stream) {
 
 
 void HValue::PrintChangesTo(StringStream* stream) {
-  int changes_flags = ChangesFlags();
-  if (changes_flags == 0) return;
+  GVNFlagSet changes_flags = ChangesFlags();
+  if (changes_flags.IsEmpty()) return;
   stream->Add(" changes[");
-  if (changes_flags == AllSideEffects()) {
+  if (changes_flags == AllSideEffectsFlagSet()) {
     stream->Add("*");
   } else {
     bool add_comma = false;
-#define PRINT_DO(type)                         \
-    if (changes_flags & (1 << kChanges##type)) { \
-      if (add_comma) stream->Add(",");           \
-      add_comma = true;                          \
-      stream->Add(#type);                        \
+#define PRINT_DO(type)                            \
+    if (changes_flags.Contains(kChanges##type)) { \
+      if (add_comma) stream->Add(",");            \
+      add_comma = true;                           \
+      stream->Add(#type);                         \
     }
     GVN_FLAG_LIST(PRINT_DO);
 #undef PRINT_DO
@@ -1408,7 +1408,7 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
   SetOperandAt(0, context);
   SetOperandAt(1, object);
   set_representation(Representation::Tagged());
-  SetFlag(kDependsOnMaps);
+  SetGVNFlag(kDependsOnMaps);
   for (int i = 0;
        i < types->length() && types_.length() < kMaxLoadPolymorphism;
        ++i) {
@@ -1420,9 +1420,9 @@ HLoadNamedFieldPolymorphic::HLoadNamedFieldPolymorphic(HValue* context,
         case FIELD: {
           int index = lookup.GetLocalFieldIndexFromMap(*map);
           if (index < 0) {
-            SetFlag(kDependsOnInobjectFields);
+            SetGVNFlag(kDependsOnInobjectFields);
           } else {
-            SetFlag(kDependsOnBackingStoreFields);
+            SetGVNFlag(kDependsOnBackingStoreFields);
           }
           types_.Add(types->at(i));
           break;
index 5082e4d..b959017 100644 (file)
@@ -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) {
index 56da2dc..a113fda 100644 (file)
@@ -1110,10 +1110,10 @@ HValueMap::HValueMap(Zone* zone, const HValueMap* other)
 }
 
 
-void HValueMap::Kill(int flags) {
-  int depends_flags = HValue::ConvertChangesToDependsFlags(flags);
-  if ((present_flags_ & depends_flags) == 0) return;
-  present_flags_ = 0;
+void HValueMap::Kill(GVNFlagSet flags) {
+  GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(flags);
+  if (!present_flags_.ContainsAnyOf(depends_flags)) return;
+  present_flags_.RemoveAll();
   for (int i = 0; i < array_size_; ++i) {
     HValue* value = array_[i].value;
     if (value != NULL) {
@@ -1122,7 +1122,8 @@ void HValueMap::Kill(int flags) {
       int next;
       for (int current = array_[i].next; current != kNil; 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.
           count_--;
           lists_[current].next = free_list_head_;
@@ -1131,13 +1132,14 @@ void HValueMap::Kill(int flags) {
           // Keep it.
           lists_[current].next = kept;
           kept = current;
-          present_flags_ |= lists_[current].value->flags();
+          present_flags_.Add(value->gvn_flags());
         }
       }
       array_[i].next = kept;
 
       // 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_--;
         int head = array_[i].next;
         if (head == kNil) {
@@ -1149,7 +1151,7 @@ void HValueMap::Kill(int flags) {
           free_list_head_ = head;
         }
       } 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 {
         loop_side_effects_(graph->blocks()->length()),
         visited_on_paths_(graph->zone(), graph->blocks()->length()) {
     ASSERT(info->isolate()->heap()->allow_allocation(false));
-    block_side_effects_.AddBlock(0, graph_->blocks()->length());
-    loop_side_effects_.AddBlock(0, graph_->blocks()->length());
+    block_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length());
+    loop_side_effects_.AddBlock(GVNFlagSet(), graph_->blocks()->length());
   }
   ~HGlobalValueNumberer() {
     ASSERT(!info_->isolate()->heap()->allow_allocation(true));
@@ -1367,14 +1369,15 @@ class HGlobalValueNumberer BASE_EMBEDDED {
   bool Analyze();
 
  private:
-  int CollectSideEffectsOnPathsToDominatedBlock(HBasicBlock* dominator,
-                                                HBasicBlock* dominated);
+  GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock(
+      HBasicBlock* dominator,
+      HBasicBlock* dominated);
   void AnalyzeBlock(HBasicBlock* block, HValueMap* map);
   void ComputeBlockSideEffects();
   void LoopInvariantCodeMotion();
   void ProcessLoopBlock(HBasicBlock* block,
                         HBasicBlock* before_loop,
-                        int loop_kills);
+                        GVNFlagSet loop_kills);
   bool AllowCodeMotion();
   bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
 
@@ -1387,10 +1390,10 @@ class HGlobalValueNumberer BASE_EMBEDDED {
   bool removed_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.
-  ZoneList<int> loop_side_effects_;
+  ZoneList<GVNFlagSet> loop_side_effects_;
 
   // Used when collecting side effects on paths from dominator to
   // dominated.
@@ -1415,23 +1418,24 @@ void HGlobalValueNumberer::ComputeBlockSideEffects() {
     HBasicBlock* block = graph_->blocks()->at(i);
     HInstruction* instr = block->first();
     int id = block->block_id();
-    int side_effects = 0;
+    GVNFlagSet side_effects;
     while (instr != NULL) {
-      side_effects |= instr->ChangesFlags();
+      side_effects.Add(instr->ChangesFlags());
       instr = instr->next();
     }
-    block_side_effects_[id] |= side_effects;
+    block_side_effects_[id].Add(side_effects);
 
     // Loop headers are part of their loop.
     if (block->IsLoopHeader()) {
-      loop_side_effects_[id] |= side_effects;
+      loop_side_effects_[id].Add(side_effects);
     }
 
     // Propagate loop side effects upwards.
     if (block->HasParentLoopHeader()) {
       int header_id = block->parent_loop_header()->block_id();
-      loop_side_effects_[header_id] |=
-          block->IsLoopHeader() ? loop_side_effects_[id] : side_effects;
+      loop_side_effects_[header_id].Add(block->IsLoopHeader()
+                                        ? loop_side_effects_[id]
+                                        : side_effects);
     }
   }
 }
@@ -1441,10 +1445,10 @@ void HGlobalValueNumberer::LoopInvariantCodeMotion() {
   for (int i = graph_->blocks()->length() - 1; i >= 0; --i) {
     HBasicBlock* block = graph_->blocks()->at(i);
     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",
                block->block_id(),
-               side_effects);
+               side_effects.ToIntegral());
 
       HBasicBlock* last = block->loop_information()->GetLastBackEdge();
       for (int j = block->block_id(); j <= last->block_id(); ++j) {
@@ -1457,17 +1461,17 @@ void HGlobalValueNumberer::LoopInvariantCodeMotion() {
 
 void HGlobalValueNumberer::ProcessLoopBlock(HBasicBlock* block,
                                             HBasicBlock* loop_header,
-                                            int loop_kills) {
+                                            GVNFlagSet loop_kills) {
   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",
            block->block_id(),
-           depends_flags);
+           depends_flags.ToIntegral());
   HInstruction* instr = block->first();
   while (instr != NULL) {
     HInstruction* next = instr->next();
     if (instr->CheckFlag(HValue::kUseGVN) &&
-        (instr->flags() & depends_flags) == 0) {
+        !instr->gvn_flags().ContainsAnyOf(depends_flags)) {
       TraceGVN("Checking instruction %d (%s)\n",
                instr->id(),
                instr->Mnemonic());
@@ -1503,20 +1507,20 @@ bool HGlobalValueNumberer::ShouldMove(HInstruction* instr,
 }
 
 
-int HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock(
+GVNFlagSet HGlobalValueNumberer::CollectSideEffectsOnPathsToDominatedBlock(
     HBasicBlock* dominator, HBasicBlock* dominated) {
-  int side_effects = 0;
+  GVNFlagSet side_effects;
   for (int i = 0; i < dominated->predecessors()->length(); ++i) {
     HBasicBlock* block = dominated->predecessors()->at(i);
     if (dominator->block_id() < block->block_id() &&
         block->block_id() < dominated->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()) {
-        side_effects |= loop_side_effects_[block->block_id()];
+        side_effects.Add(loop_side_effects_[block->block_id()]);
       }
-      side_effects |= CollectSideEffectsOnPathsToDominatedBlock(
-          dominator, block);
+      side_effects.Add(CollectSideEffectsOnPathsToDominatedBlock(
+          dominator, block));
     }
   }
   return side_effects;
@@ -1537,8 +1541,8 @@ void HGlobalValueNumberer::AnalyzeBlock(HBasicBlock* block, HValueMap* map) {
   HInstruction* instr = block->first();
   while (instr != NULL) {
     HInstruction* next = instr->next();
-    int flags = instr->ChangesFlags();
-    if (flags != 0) {
+    GVNFlagSet flags = instr->ChangesFlags();
+    if (!flags.IsEmpty()) {
       // Clear all instructions in the map that are affected by side effects.
       map->Kill(flags);
       TraceGVN("Instruction %d kills\n", instr->id());
@@ -3597,7 +3601,7 @@ HInstruction* HGraphBuilder::BuildStoreNamedField(HValue* object,
     instr->set_transition(transition);
     // TODO(fschneider): Record the new map type of the object in the IR to
     // enable elimination of redundant checks after the transition store.
-    instr->SetFlag(HValue::kChangesMaps);
+    instr->SetGVNFlag(kChangesMaps);
   }
   return instr;
 }
index 9705859..b77e975 100644 (file)
@@ -1,4 +1,4 @@
-// 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
 // modification, are permitted provided that the following conditions are
 // met:
@@ -1056,10 +1056,10 @@ class HValueMap: public ZoneObject {
     Resize(kInitialSize);
   }
 
-  void Kill(int flags);
+  void Kill(GVNFlagSet flags);
 
   void Add(HValue* value) {
-    present_flags_ |= value->flags();
+    present_flags_.Add(value->gvn_flags());
     Insert(value);
   }
 
@@ -1092,7 +1092,8 @@ class HValueMap: public ZoneObject {
   int array_size_;
   int lists_size_;
   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
   // with a given hash.  Colliding elements are stored in linked lists.
   HValueMapListElement* lists_;  // The linked lists containing hash collisions.
index 17bf06f..1d40c98 100644 (file)
@@ -1,4 +1,4 @@
-// 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
 // modification, are permitted provided that the following conditions are
 // met:
@@ -931,9 +931,17 @@ class EnumSet {
   explicit EnumSet(T bits = 0) : bits_(bits) {}
   bool IsEmpty() const { return bits_ == 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(const EnumSet& set) { bits_ |= set.bits_; }
   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_; }
+  bool operator==(const EnumSet& set) { return bits_ == set.bits_; }
 
  private:
   T Mask(E element) const {