Improve inobject field tracking during GVN.
authorbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 11 Feb 2014 06:41:06 +0000 (06:41 +0000)
committerbmeurer@chromium.org <bmeurer@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Tue, 11 Feb 2014 06:41:06 +0000 (06:41 +0000)
Now stores to inobject fields do no longer prevent hoisting
and combining of loads from other inobject fields.

R=mstarzinger@chromium.org

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

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19247 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/hydrogen-check-elimination.cc
src/hydrogen-gvn.cc
src/hydrogen-gvn.h
src/hydrogen-instructions.cc
src/hydrogen-instructions.h
src/hydrogen-load-elimination.cc
src/hydrogen.cc

index 5d1323b..dafb632 100644 (file)
@@ -103,8 +103,8 @@ class HCheckTable : public ZoneObject {
       }
       default: {
         // If the instruction changes maps uncontrollably, drop everything.
-        if (instr->CheckGVNFlag(kChangesMaps) ||
-            instr->CheckGVNFlag(kChangesOsrEntries)) {
+        if (instr->CheckChangesFlag(kMaps) ||
+            instr->CheckChangesFlag(kOsrEntries)) {
           Kill();
         }
       }
@@ -387,7 +387,7 @@ class HCheckTable : public ZoneObject {
       Insert(object, MapConstant(instr->value()));
     } else {
       // If the instruction changes maps, it should be handled above.
-      CHECK(!instr->CheckGVNFlag(kChangesMaps));
+      CHECK(!instr->CheckChangesFlag(kMaps));
     }
   }
 
@@ -571,8 +571,8 @@ class HCheckMapsEffects : public ZoneObject {
         maps_stored_ = true;
       }
       default: {
-        maps_stored_ |= (instr->CheckGVNFlag(kChangesMaps) |
-                         instr->CheckGVNFlag(kChangesElementsKind));
+        maps_stored_ |= (instr->CheckChangesFlag(kMaps) |
+                         instr->CheckChangesFlag(kElementsKind));
       }
     }
   }
index bc83689..6bf5a1b 100644 (file)
 namespace v8 {
 namespace internal {
 
-class HValueMap: public ZoneObject {
+class HInstructionMap V8_FINAL : public ZoneObject {
  public:
-  explicit HValueMap(Zone* zone)
+  HInstructionMap(Zone* zone, SideEffectsTracker* side_effects_tracker)
       : array_size_(0),
         lists_size_(0),
         count_(0),
-        present_flags_(0),
         array_(NULL),
         lists_(NULL),
-        free_list_head_(kNil) {
+        free_list_head_(kNil),
+        side_effects_tracker_(side_effects_tracker) {
     ResizeLists(kInitialSize, zone);
     Resize(kInitialSize, zone);
   }
 
-  void Kill(GVNFlagSet flags);
+  void Kill(SideEffects side_effects);
 
-  void Add(HValue* value, Zone* zone) {
-    present_flags_.Add(value->gvn_flags());
-    Insert(value, zone);
+  void Add(HInstruction* instr, Zone* zone) {
+    present_depends_on_.Add(side_effects_tracker_->ComputeDependsOn(instr));
+    Insert(instr, zone);
   }
 
-  HValue* Lookup(HValue* value) const;
+  HInstruction* Lookup(HInstruction* instr) const;
 
-  HValueMap* Copy(Zone* zone) const {
-    return new(zone) HValueMap(zone, this);
+  HInstructionMap* Copy(Zone* zone) const {
+    return new(zone) HInstructionMap(zone, this);
   }
 
   bool IsEmpty() const { return count_ == 0; }
 
  private:
-  // A linked list of HValue* values.  Stored in arrays.
-  struct HValueMapListElement {
-    HValue* value;
+  // A linked list of HInstruction* values.  Stored in arrays.
+  struct HInstructionMapListElement {
+    HInstruction* instr;
     int next;  // Index in the array of the next list element.
   };
   static const int kNil = -1;  // The end of a linked list
@@ -72,34 +72,36 @@ class HValueMap: public ZoneObject {
   // Must be a power of 2.
   static const int kInitialSize = 16;
 
-  HValueMap(Zone* zone, const HValueMap* other);
+  HInstructionMap(Zone* zone, const HInstructionMap* other);
 
   void Resize(int new_size, Zone* zone);
   void ResizeLists(int new_size, Zone* zone);
-  void Insert(HValue* value, Zone* zone);
+  void Insert(HInstruction* instr, Zone* zone);
   uint32_t Bound(uint32_t value) const { return value & (array_size_ - 1); }
 
   int array_size_;
   int lists_size_;
-  int count_;  // The number of values stored in the HValueMap.
-  GVNFlagSet present_flags_;  // All flags that are in any value in the
-                              // HValueMap.
-  HValueMapListElement* array_;  // Primary store - contains the first value
+  int count_;  // The number of values stored in the HInstructionMap.
+  SideEffects present_depends_on_;
+  HInstructionMapListElement* 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.
+  HInstructionMapListElement* lists_;
+  // The linked lists containing hash collisions.
   int free_list_head_;  // Unused elements in lists_ are on the free list.
+  SideEffectsTracker* side_effects_tracker_;
 };
 
 
-class HSideEffectMap BASE_EMBEDDED {
+class HSideEffectMap V8_FINAL BASE_EMBEDDED {
  public:
   HSideEffectMap();
   explicit HSideEffectMap(HSideEffectMap* other);
   HSideEffectMap& operator= (const HSideEffectMap& other);
 
-  void Kill(GVNFlagSet flags);
+  void Kill(SideEffects side_effects);
 
-  void Store(GVNFlagSet flags, HInstruction* instr);
+  void Store(SideEffects side_effects, HInstruction* instr);
 
   bool IsEmpty() const { return count_ == 0; }
 
@@ -152,35 +154,36 @@ void TraceGVN(const char* msg, ...) {
   }
 
 
-HValueMap::HValueMap(Zone* zone, const HValueMap* other)
+HInstructionMap::HInstructionMap(Zone* zone, const HInstructionMap* other)
     : array_size_(other->array_size_),
       lists_size_(other->lists_size_),
       count_(other->count_),
-      present_flags_(other->present_flags_),
-      array_(zone->NewArray<HValueMapListElement>(other->array_size_)),
-      lists_(zone->NewArray<HValueMapListElement>(other->lists_size_)),
-      free_list_head_(other->free_list_head_) {
+      present_depends_on_(other->present_depends_on_),
+      array_(zone->NewArray<HInstructionMapListElement>(other->array_size_)),
+      lists_(zone->NewArray<HInstructionMapListElement>(other->lists_size_)),
+      free_list_head_(other->free_list_head_),
+      side_effects_tracker_(other->side_effects_tracker_) {
   OS::MemCopy(
-      array_, other->array_, array_size_ * sizeof(HValueMapListElement));
+      array_, other->array_, array_size_ * sizeof(HInstructionMapListElement));
   OS::MemCopy(
-      lists_, other->lists_, lists_size_ * sizeof(HValueMapListElement));
+      lists_, other->lists_, lists_size_ * sizeof(HInstructionMapListElement));
 }
 
 
-void HValueMap::Kill(GVNFlagSet flags) {
-  GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(flags);
-  if (!present_flags_.ContainsAnyOf(depends_flags)) return;
-  present_flags_.RemoveAll();
+void HInstructionMap::Kill(SideEffects changes) {
+  if (!present_depends_on_.ContainsAnyOf(changes)) return;
+  present_depends_on_.RemoveAll();
   for (int i = 0; i < array_size_; ++i) {
-    HValue* value = array_[i].value;
-    if (value != NULL) {
+    HInstruction* instr = array_[i].instr;
+    if (instr != NULL) {
       // Clear list of collisions first, so we know if it becomes empty.
       int kept = kNil;  // List of kept elements.
       int next;
       for (int current = array_[i].next; current != kNil; current = next) {
         next = lists_[current].next;
-        HValue* value = lists_[current].value;
-        if (value->gvn_flags().ContainsAnyOf(depends_flags)) {
+        HInstruction* instr = lists_[current].instr;
+        SideEffects depends_on = side_effects_tracker_->ComputeDependsOn(instr);
+        if (depends_on.ContainsAnyOf(changes)) {
           // Drop it.
           count_--;
           lists_[current].next = free_list_head_;
@@ -189,40 +192,41 @@ void HValueMap::Kill(GVNFlagSet flags) {
           // Keep it.
           lists_[current].next = kept;
           kept = current;
-          present_flags_.Add(value->gvn_flags());
+          present_depends_on_.Add(depends_on);
         }
       }
       array_[i].next = kept;
 
       // Now possibly drop directly indexed element.
-      value = array_[i].value;
-      if (value->gvn_flags().ContainsAnyOf(depends_flags)) {  // Drop it.
+      instr = array_[i].instr;
+      SideEffects depends_on = side_effects_tracker_->ComputeDependsOn(instr);
+      if (depends_on.ContainsAnyOf(changes)) {  // Drop it.
         count_--;
         int head = array_[i].next;
         if (head == kNil) {
-          array_[i].value = NULL;
+          array_[i].instr = NULL;
         } else {
-          array_[i].value = lists_[head].value;
+          array_[i].instr = lists_[head].instr;
           array_[i].next = lists_[head].next;
           lists_[head].next = free_list_head_;
           free_list_head_ = head;
         }
       } else {
-        present_flags_.Add(value->gvn_flags());  // Keep it.
+        present_depends_on_.Add(depends_on);  // Keep it.
       }
     }
   }
 }
 
 
-HValue* HValueMap::Lookup(HValue* value) const {
-  uint32_t hash = static_cast<uint32_t>(value->Hashcode());
+HInstruction* HInstructionMap::Lookup(HInstruction* instr) const {
+  uint32_t hash = static_cast<uint32_t>(instr->Hashcode());
   uint32_t pos = Bound(hash);
-  if (array_[pos].value != NULL) {
-    if (array_[pos].value->Equals(value)) return array_[pos].value;
+  if (array_[pos].instr != NULL) {
+    if (array_[pos].instr->Equals(instr)) return array_[pos].instr;
     int next = array_[pos].next;
     while (next != kNil) {
-      if (lists_[next].value->Equals(value)) return lists_[next].value;
+      if (lists_[next].instr->Equals(instr)) return lists_[next].instr;
       next = lists_[next].next;
     }
   }
@@ -230,7 +234,7 @@ HValue* HValueMap::Lookup(HValue* value) const {
 }
 
 
-void HValueMap::Resize(int new_size, Zone* zone) {
+void HInstructionMap::Resize(int new_size, Zone* zone) {
   ASSERT(new_size > count_);
   // Hashing the values into the new array has no more collisions than in the
   // old hash map, so we can use the existing lists_ array, if we are careful.
@@ -240,33 +244,33 @@ void HValueMap::Resize(int new_size, Zone* zone) {
     ResizeLists(lists_size_ << 1, zone);
   }
 
-  HValueMapListElement* new_array =
-      zone->NewArray<HValueMapListElement>(new_size);
-  memset(new_array, 0, sizeof(HValueMapListElement) * new_size);
+  HInstructionMapListElement* new_array =
+      zone->NewArray<HInstructionMapListElement>(new_size);
+  memset(new_array, 0, sizeof(HInstructionMapListElement) * new_size);
 
-  HValueMapListElement* old_array = array_;
+  HInstructionMapListElement* old_array = array_;
   int old_size = array_size_;
 
   int old_count = count_;
   count_ = 0;
-  // Do not modify present_flags_.  It is currently correct.
+  // Do not modify present_depends_on_.  It is currently correct.
   array_size_ = new_size;
   array_ = new_array;
 
   if (old_array != NULL) {
     // Iterate over all the elements in lists, rehashing them.
     for (int i = 0; i < old_size; ++i) {
-      if (old_array[i].value != NULL) {
+      if (old_array[i].instr != NULL) {
         int current = old_array[i].next;
         while (current != kNil) {
-          Insert(lists_[current].value, zone);
+          Insert(lists_[current].instr, zone);
           int next = lists_[current].next;
           lists_[current].next = free_list_head_;
           free_list_head_ = current;
           current = next;
         }
-        // Rehash the directly stored value.
-        Insert(old_array[i].value, zone);
+        // Rehash the directly stored instruction.
+        Insert(old_array[i].instr, zone);
       }
     }
   }
@@ -275,21 +279,22 @@ void HValueMap::Resize(int new_size, Zone* zone) {
 }
 
 
-void HValueMap::ResizeLists(int new_size, Zone* zone) {
+void HInstructionMap::ResizeLists(int new_size, Zone* zone) {
   ASSERT(new_size > lists_size_);
 
-  HValueMapListElement* new_lists =
-      zone->NewArray<HValueMapListElement>(new_size);
-  memset(new_lists, 0, sizeof(HValueMapListElement) * new_size);
+  HInstructionMapListElement* new_lists =
+      zone->NewArray<HInstructionMapListElement>(new_size);
+  memset(new_lists, 0, sizeof(HInstructionMapListElement) * new_size);
 
-  HValueMapListElement* old_lists = lists_;
+  HInstructionMapListElement* old_lists = lists_;
   int old_size = lists_size_;
 
   lists_size_ = new_size;
   lists_ = new_lists;
 
   if (old_lists != NULL) {
-    OS::MemCopy(lists_, old_lists, old_size * sizeof(HValueMapListElement));
+    OS::MemCopy(
+        lists_, old_lists, old_size * sizeof(HInstructionMapListElement));
   }
   for (int i = old_size; i < lists_size_; ++i) {
     lists_[i].next = free_list_head_;
@@ -298,15 +303,15 @@ void HValueMap::ResizeLists(int new_size, Zone* zone) {
 }
 
 
-void HValueMap::Insert(HValue* value, Zone* zone) {
-  ASSERT(value != NULL);
+void HInstructionMap::Insert(HInstruction* instr, Zone* zone) {
+  ASSERT(instr != NULL);
   // Resizing when half of the hashtable is filled up.
   if (count_ >= array_size_ >> 1) Resize(array_size_ << 1, zone);
   ASSERT(count_ < array_size_);
   count_++;
-  uint32_t pos = Bound(static_cast<uint32_t>(value->Hashcode()));
-  if (array_[pos].value == NULL) {
-    array_[pos].value = value;
+  uint32_t pos = Bound(static_cast<uint32_t>(instr->Hashcode()));
+  if (array_[pos].instr == NULL) {
+    array_[pos].instr = instr;
     array_[pos].next = kNil;
   } else {
     if (free_list_head_ == kNil) {
@@ -315,9 +320,9 @@ void HValueMap::Insert(HValue* value, Zone* zone) {
     int new_element_pos = free_list_head_;
     ASSERT(new_element_pos != kNil);
     free_list_head_ = lists_[free_list_head_].next;
-    lists_[new_element_pos].value = value;
+    lists_[new_element_pos].instr = instr;
     lists_[new_element_pos].next = array_[pos].next;
-    ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].value != NULL);
+    ASSERT(array_[pos].next == kNil || lists_[array_[pos].next].instr != NULL);
     array_[pos].next = new_element_pos;
   }
 }
@@ -341,10 +346,9 @@ HSideEffectMap& HSideEffectMap::operator= (const HSideEffectMap& other) {
 }
 
 
-void HSideEffectMap::Kill(GVNFlagSet flags) {
+void HSideEffectMap::Kill(SideEffects side_effects) {
   for (int i = 0; i < kNumberOfTrackedSideEffects; i++) {
-    GVNFlag changes_flag = HValue::ChangesFlagFromInt(i);
-    if (flags.Contains(changes_flag)) {
+    if (side_effects.ContainsFlag(GVNFlagFromInt(i))) {
       if (data_[i] != NULL) count_--;
       data_[i] = NULL;
     }
@@ -352,10 +356,9 @@ void HSideEffectMap::Kill(GVNFlagSet flags) {
 }
 
 
-void HSideEffectMap::Store(GVNFlagSet flags, HInstruction* instr) {
+void HSideEffectMap::Store(SideEffects side_effects, HInstruction* instr) {
   for (int i = 0; i < kNumberOfTrackedSideEffects; i++) {
-    GVNFlag changes_flag = HValue::ChangesFlagFromInt(i);
-    if (flags.Contains(changes_flag)) {
+    if (side_effects.ContainsFlag(GVNFlagFromInt(i))) {
       if (data_[i] == NULL) count_++;
       data_[i] = instr;
     }
@@ -363,6 +366,96 @@ void HSideEffectMap::Store(GVNFlagSet flags, HInstruction* instr) {
 }
 
 
+SideEffects SideEffectsTracker::ComputeChanges(HInstruction* instr) {
+  SideEffects result(instr->ChangesFlags());
+  if (result.ContainsFlag(kInobjectFields)) {
+    int index;
+    if (instr->IsStoreNamedField() &&
+        ComputeInobjectField(HStoreNamedField::cast(instr)->access(), &index)) {
+      result.RemoveFlag(kInobjectFields);
+      result.AddSpecial(index);
+    } else {
+      result.AddAllSpecial();
+    }
+  }
+  return result;
+}
+
+
+SideEffects SideEffectsTracker::ComputeDependsOn(HInstruction* instr) {
+  SideEffects result(instr->DependsOnFlags());
+  if (result.ContainsFlag(kInobjectFields)) {
+    int index;
+    if (instr->IsLoadNamedField() &&
+        ComputeInobjectField(HLoadNamedField::cast(instr)->access(), &index)) {
+      result.RemoveFlag(kInobjectFields);
+      result.AddSpecial(index);
+    } else {
+      result.AddAllSpecial();
+    }
+  }
+  return result;
+}
+
+
+void SideEffectsTracker::PrintSideEffectsTo(StringStream* stream,
+                                          SideEffects side_effects) const {
+  const char* separator = "";
+  stream->Add("[");
+  for (int bit = 0; bit < kNumberOfFlags; ++bit) {
+    GVNFlag flag = GVNFlagFromInt(bit);
+    if (side_effects.ContainsFlag(flag)) {
+      stream->Add(separator);
+      separator = ", ";
+      switch (flag) {
+#define DECLARE_FLAG(Type)      \
+        case k##Type:           \
+          stream->Add(#Type);   \
+          break;
+GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
+GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
+#undef DECLARE_FLAG
+        default:
+            break;
+      }
+    }
+  }
+  for (int index = 0; index < num_inobject_fields_; ++index) {
+    if (side_effects.ContainsSpecial(index)) {
+      stream->Add(separator);
+      separator = ", ";
+      inobject_fields_[index].PrintTo(stream);
+    }
+  }
+  stream->Add("]");
+}
+
+
+bool SideEffectsTracker::ComputeInobjectField(HObjectAccess access,
+                                              int* index) {
+  for (int i = 0; i < num_inobject_fields_; ++i) {
+    if (access.Equals(inobject_fields_[i])) {
+      *index = i;
+      return true;
+    }
+  }
+  if (num_inobject_fields_ < SideEffects::kNumberOfSpecials) {
+    if (FLAG_trace_gvn) {
+      HeapStringAllocator allocator;
+      StringStream stream(&allocator);
+      stream.Add("Tracking inobject field access ");
+      access.PrintTo(&stream);
+      stream.Add(" (mapped to special index %d)\n", num_inobject_fields_);
+      stream.OutputToStdOut();
+    }
+    *index = num_inobject_fields_;
+    inobject_fields_[num_inobject_fields_++] = access;
+    return true;
+  }
+  return false;
+}
+
+
 HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph)
     : HPhase("H_Global value numbering", graph),
       removed_side_effects_(false),
@@ -370,10 +463,10 @@ HGlobalValueNumberingPhase::HGlobalValueNumberingPhase(HGraph* graph)
       loop_side_effects_(graph->blocks()->length(), zone()),
       visited_on_paths_(graph->blocks()->length(), zone()) {
   ASSERT(!AllowHandleAllocation::IsAllowed());
-  block_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(),
-                                zone());
-  loop_side_effects_.AddBlock(GVNFlagSet(), graph->blocks()->length(),
-                              zone());
+  block_side_effects_.AddBlock(
+      SideEffects(), graph->blocks()->length(), zone());
+  loop_side_effects_.AddBlock(
+      SideEffects(), graph->blocks()->length(), zone());
 }
 
 
@@ -409,12 +502,12 @@ void HGlobalValueNumberingPhase::ComputeBlockSideEffects() {
   for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
     // Compute side effects for the block.
     HBasicBlock* block = graph()->blocks()->at(i);
-    GVNFlagSet side_effects;
+    SideEffects side_effects;
     if (block->IsReachable() && !block->IsDeoptimizing()) {
       int id = block->block_id();
       for (HInstructionIterator it(block); !it.Done(); it.Advance()) {
         HInstruction* instr = it.Current();
-        side_effects.Add(instr->ChangesFlags());
+        side_effects.Add(side_effects_tracker_.ComputeChanges(instr));
       }
       block_side_effects_[id].Add(side_effects);
 
@@ -438,103 +531,22 @@ void HGlobalValueNumberingPhase::ComputeBlockSideEffects() {
 }
 
 
-SmartArrayPointer<char> GetGVNFlagsString(GVNFlagSet flags) {
-  char underlying_buffer[kNumberOfFlags * 128];
-  Vector<char> buffer(underlying_buffer, sizeof(underlying_buffer));
-#if DEBUG
-  int offset = 0;
-  const char* separator = "";
-  const char* comma = ", ";
-  buffer[0] = 0;
-  uint32_t set_depends_on = 0;
-  uint32_t set_changes = 0;
-  for (int bit = 0; bit < kNumberOfFlags; ++bit) {
-    if (flags.Contains(static_cast<GVNFlag>(bit))) {
-      if (bit % 2 == 0) {
-        set_changes++;
-      } else {
-        set_depends_on++;
-      }
-    }
-  }
-  bool positive_changes = set_changes < (kNumberOfFlags / 2);
-  bool positive_depends_on = set_depends_on < (kNumberOfFlags / 2);
-  if (set_changes > 0) {
-    if (positive_changes) {
-      offset += OS::SNPrintF(buffer + offset, "changes [");
-    } else {
-      offset += OS::SNPrintF(buffer + offset, "changes all except [");
-    }
-    for (int bit = 0; bit < kNumberOfFlags; ++bit) {
-      if (flags.Contains(static_cast<GVNFlag>(bit)) == positive_changes) {
-        switch (static_cast<GVNFlag>(bit)) {
-#define DECLARE_FLAG(type)                                       \
-          case kChanges##type:                                   \
-            offset += OS::SNPrintF(buffer + offset, separator);  \
-            offset += OS::SNPrintF(buffer + offset, #type);      \
-            separator = comma;                                   \
-            break;
-GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
-GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
-#undef DECLARE_FLAG
-          default:
-              break;
-        }
-      }
-    }
-    offset += OS::SNPrintF(buffer + offset, "]");
-  }
-  if (set_depends_on > 0) {
-    separator = "";
-    if (set_changes > 0) {
-      offset += OS::SNPrintF(buffer + offset, ", ");
-    }
-    if (positive_depends_on) {
-      offset += OS::SNPrintF(buffer + offset, "depends on [");
-    } else {
-      offset += OS::SNPrintF(buffer + offset, "depends on all except [");
-    }
-    for (int bit = 0; bit < kNumberOfFlags; ++bit) {
-      if (flags.Contains(static_cast<GVNFlag>(bit)) == positive_depends_on) {
-        switch (static_cast<GVNFlag>(bit)) {
-#define DECLARE_FLAG(type)                                       \
-          case kDependsOn##type:                                 \
-            offset += OS::SNPrintF(buffer + offset, separator);  \
-            offset += OS::SNPrintF(buffer + offset, #type);      \
-            separator = comma;                                   \
-            break;
-GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
-GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
-#undef DECLARE_FLAG
-          default:
-            break;
-        }
-      }
-    }
-    offset += OS::SNPrintF(buffer + offset, "]");
-  }
-#else
-  OS::SNPrintF(buffer, "0x%08X", flags.ToIntegral());
-#endif
-  size_t string_len = strlen(underlying_buffer) + 1;
-  ASSERT(string_len <= sizeof(underlying_buffer));
-  char* result = new char[strlen(underlying_buffer) + 1];
-  OS::MemCopy(result, underlying_buffer, string_len);
-  return SmartArrayPointer<char>(result);
-}
-
-
 void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() {
   TRACE_GVN_1("Using optimistic loop invariant code motion: %s\n",
               graph()->use_optimistic_licm() ? "yes" : "no");
   for (int i = graph()->blocks()->length() - 1; i >= 0; --i) {
     HBasicBlock* block = graph()->blocks()->at(i);
     if (block->IsLoopHeader()) {
-      GVNFlagSet side_effects = loop_side_effects_[block->block_id()];
-      TRACE_GVN_2("Try loop invariant motion for block B%d %s\n",
-                  block->block_id(),
-                  GetGVNFlagsString(side_effects).get());
-
+      SideEffects side_effects = loop_side_effects_[block->block_id()];
+      if (FLAG_trace_gvn) {
+        HeapStringAllocator allocator;
+        StringStream stream(&allocator);
+        stream.Add("Try loop invariant motion for block B%d changes ",
+                   block->block_id());
+        side_effects_tracker_.PrintSideEffectsTo(&stream, side_effects);
+        stream.Add("\n");
+        stream.OutputToStdOut();
+      }
       HBasicBlock* last = block->loop_information()->GetLastBackEdge();
       for (int j = block->block_id(); j <= last->block_id(); ++j) {
         ProcessLoopBlock(graph()->blocks()->at(j), block, side_effects);
@@ -547,22 +559,37 @@ void HGlobalValueNumberingPhase::LoopInvariantCodeMotion() {
 void HGlobalValueNumberingPhase::ProcessLoopBlock(
     HBasicBlock* block,
     HBasicBlock* loop_header,
-    GVNFlagSet loop_kills) {
+    SideEffects loop_kills) {
   HBasicBlock* pre_header = loop_header->predecessors()->at(0);
-  GVNFlagSet depends_flags = HValue::ConvertChangesToDependsFlags(loop_kills);
-  TRACE_GVN_2("Loop invariant motion for B%d %s\n",
-              block->block_id(),
-              GetGVNFlagsString(depends_flags).get());
+  if (FLAG_trace_gvn) {
+    HeapStringAllocator allocator;
+    StringStream stream(&allocator);
+    stream.Add("Loop invariant code motion for B%d depends on ",
+               block->block_id());
+    side_effects_tracker_.PrintSideEffectsTo(&stream, loop_kills);
+    stream.Add("\n");
+    stream.OutputToStdOut();
+  }
   HInstruction* instr = block->first();
   while (instr != NULL) {
     HInstruction* next = instr->next();
     if (instr->CheckFlag(HValue::kUseGVN)) {
-      TRACE_GVN_4("Checking instruction %d (%s) %s. Loop %s\n",
-                  instr->id(),
-                  instr->Mnemonic(),
-                  GetGVNFlagsString(instr->gvn_flags()).get(),
-                  GetGVNFlagsString(loop_kills).get());
-      bool can_hoist = !instr->gvn_flags().ContainsAnyOf(depends_flags);
+      SideEffects changes = side_effects_tracker_.ComputeChanges(instr);
+      SideEffects depends_on = side_effects_tracker_.ComputeDependsOn(instr);
+      if (FLAG_trace_gvn) {
+        HeapStringAllocator allocator;
+        StringStream stream(&allocator);
+        stream.Add("Checking instruction i%d (%s) changes ",
+                   instr->id(), instr->Mnemonic());
+        side_effects_tracker_.PrintSideEffectsTo(&stream, changes);
+        stream.Add(", depends on ");
+        side_effects_tracker_.PrintSideEffectsTo(&stream, depends_on);
+        stream.Add(". Loop changes ");
+        side_effects_tracker_.PrintSideEffectsTo(&stream, loop_kills);
+        stream.Add("\n");
+        stream.OutputToStdOut();
+      }
+      bool can_hoist = !depends_on.ContainsAnyOf(loop_kills);
       if (can_hoist && !graph()->use_optimistic_licm()) {
         can_hoist = block->IsLoopSuccessorDominator();
       }
@@ -604,10 +631,10 @@ bool HGlobalValueNumberingPhase::ShouldMove(HInstruction* instr,
 }
 
 
-GVNFlagSet
+SideEffects
 HGlobalValueNumberingPhase::CollectSideEffectsOnPathsToDominatedBlock(
     HBasicBlock* dominator, HBasicBlock* dominated) {
-  GVNFlagSet side_effects;
+  SideEffects side_effects;
   for (int i = 0; i < dominated->predecessors()->length(); ++i) {
     HBasicBlock* block = dominated->predecessors()->at(i);
     if (dominator->block_id() < block->block_id() &&
@@ -636,13 +663,13 @@ class GvnBasicBlockState: public ZoneObject {
  public:
   static GvnBasicBlockState* CreateEntry(Zone* zone,
                                          HBasicBlock* entry_block,
-                                         HValueMap* entry_map) {
+                                         HInstructionMap* entry_map) {
     return new(zone)
         GvnBasicBlockState(NULL, entry_block, entry_map, NULL, zone);
   }
 
   HBasicBlock* block() { return block_; }
-  HValueMap* map() { return map_; }
+  HInstructionMap* map() { return map_; }
   HSideEffectMap* dominators() { return &dominators_; }
 
   GvnBasicBlockState* next_in_dominator_tree_traversal(
@@ -669,7 +696,7 @@ class GvnBasicBlockState: public ZoneObject {
 
  private:
   void Initialize(HBasicBlock* block,
-                  HValueMap* map,
+                  HInstructionMap* map,
                   HSideEffectMap* dominators,
                   bool copy_map,
                   Zone* zone) {
@@ -685,7 +712,7 @@ class GvnBasicBlockState: public ZoneObject {
 
   GvnBasicBlockState(GvnBasicBlockState* previous,
                      HBasicBlock* block,
-                     HValueMap* map,
+                     HInstructionMap* map,
                      HSideEffectMap* dominators,
                      Zone* zone)
       : previous_(previous), next_(NULL) {
@@ -732,7 +759,7 @@ class GvnBasicBlockState: public ZoneObject {
   GvnBasicBlockState* previous_;
   GvnBasicBlockState* next_;
   HBasicBlock* block_;
-  HValueMap* map_;
+  HInstructionMap* map_;
   HSideEffectMap dominators_;
   int dominated_index_;
   int length_;
@@ -745,13 +772,14 @@ class GvnBasicBlockState: public ZoneObject {
 // GvnBasicBlockState instances.
 void HGlobalValueNumberingPhase::AnalyzeGraph() {
   HBasicBlock* entry_block = graph()->entry_block();
-  HValueMap* entry_map = new(zone()) HValueMap(zone());
+  HInstructionMap* entry_map =
+      new(zone()) HInstructionMap(zone(), &side_effects_tracker_);
   GvnBasicBlockState* current =
       GvnBasicBlockState::CreateEntry(zone(), entry_block, entry_map);
 
   while (current != NULL) {
     HBasicBlock* block = current->block();
-    HValueMap* map = current->map();
+    HInstructionMap* map = current->map();
     HSideEffectMap* dominators = current->dominators();
 
     TRACE_GVN_2("Analyzing block B%d%s\n",
@@ -770,17 +798,15 @@ void HGlobalValueNumberingPhase::AnalyzeGraph() {
       if (instr->CheckFlag(HValue::kTrackSideEffectDominators)) {
         for (int i = 0; i < kNumberOfTrackedSideEffects; i++) {
           HValue* other = dominators->at(i);
-          GVNFlag changes_flag = HValue::ChangesFlagFromInt(i);
-          GVNFlag depends_on_flag = HValue::DependsOnFlagFromInt(i);
-          if (instr->DependsOnFlags().Contains(depends_on_flag) &&
-              (other != NULL)) {
+          GVNFlag flag = GVNFlagFromInt(i);
+          if (instr->DependsOnFlags().Contains(flag) && other != NULL) {
             TRACE_GVN_5("Side-effect #%d in %d (%s) is dominated by %d (%s)\n",
                         i,
                         instr->id(),
                         instr->Mnemonic(),
                         other->id(),
                         other->Mnemonic());
-            if (instr->HandleSideEffectDominator(changes_flag, other)) {
+            if (instr->HandleSideEffectDominator(flag, other)) {
               removed_side_effects_ = true;
             }
           }
@@ -789,21 +815,27 @@ void HGlobalValueNumberingPhase::AnalyzeGraph() {
       // Instruction was unlinked during graph traversal.
       if (!instr->IsLinked()) continue;
 
-      GVNFlagSet flags = instr->ChangesFlags();
-      if (!flags.IsEmpty()) {
+      SideEffects changes = side_effects_tracker_.ComputeChanges(instr);
+      if (!changes.IsEmpty()) {
         // Clear all instructions in the map that are affected by side effects.
         // Store instruction as the dominating one for tracked side effects.
-        map->Kill(flags);
-        dominators->Store(flags, instr);
-        TRACE_GVN_2("Instruction %d %s\n", instr->id(),
-                    GetGVNFlagsString(flags).get());
+        map->Kill(changes);
+        dominators->Store(changes, instr);
+        if (FLAG_trace_gvn) {
+          HeapStringAllocator allocator;
+          StringStream stream(&allocator);
+          stream.Add("Instruction i%d changes ", instr->id());
+          side_effects_tracker_.PrintSideEffectsTo(&stream, changes);
+          stream.Add("\n");
+          stream.OutputToStdOut();
+        }
       }
       if (instr->CheckFlag(HValue::kUseGVN)) {
         ASSERT(!instr->HasObservableSideEffects());
-        HValue* other = map->Lookup(instr);
+        HInstruction* other = map->Lookup(instr);
         if (other != NULL) {
           ASSERT(instr->Equals(other) && other->Equals(instr));
-          TRACE_GVN_4("Replacing value %d (%s) with value %d (%s)\n",
+          TRACE_GVN_4("Replacing instruction i%d (%s) with i%d (%s)\n",
                       instr->id(),
                       instr->Mnemonic(),
                       other->id(),
@@ -823,7 +855,7 @@ void HGlobalValueNumberingPhase::AnalyzeGraph() {
 
     if (next != NULL) {
       HBasicBlock* dominated = next->block();
-      HValueMap* successor_map = next->map();
+      HInstructionMap* successor_map = next->map();
       HSideEffectMap* successor_dominators = next->dominators();
 
       // Kill everything killed on any path between this block and the
@@ -834,7 +866,7 @@ void HGlobalValueNumberingPhase::AnalyzeGraph() {
       if ((!successor_map->IsEmpty() || !successor_dominators->IsEmpty()) &&
           dominator_block->block_id() + 1 < dominated->block_id()) {
         visited_on_paths_.Clear();
-        GVNFlagSet side_effects_on_all_paths =
+        SideEffects side_effects_on_all_paths =
             CollectSideEffectsOnPathsToDominatedBlock(dominator_block,
                                                       dominated);
         successor_map->Kill(side_effects_on_all_paths);
index 30333cc..3da3ecf 100644 (file)
 namespace v8 {
 namespace internal {
 
+// This class extends GVNFlagSet with additional "special" dynamic side effects,
+// which can be used to represent side effects that cannot be expressed using
+// the GVNFlags of an HInstruction. These special side effects are tracked by a
+// SideEffectsTracker (see below).
+class SideEffects V8_FINAL {
+ public:
+  static const int kNumberOfSpecials = 64 - kNumberOfFlags;
+
+  SideEffects() : bits_(0) {}
+  explicit SideEffects(GVNFlagSet flags) : bits_(flags.ToIntegral()) {}
+  bool IsEmpty() const { return bits_ == 0; }
+  bool ContainsFlag(GVNFlag flag) const {
+    return (bits_ & MaskFlag(flag)) != 0;
+  }
+  bool ContainsSpecial(int special) const {
+    return (bits_ & MaskSpecial(special)) != 0;
+  }
+  bool ContainsAnyOf(SideEffects set) const { return (bits_ & set.bits_) != 0; }
+  void Add(SideEffects set) { bits_ |= set.bits_; }
+  void AddSpecial(int special) { bits_ |= MaskSpecial(special); }
+  void AddAllSpecial() { bits_ |= ~static_cast<uint64_t>(0) << kNumberOfFlags; }
+  void RemoveFlag(GVNFlag flag) { bits_ &= ~MaskFlag(flag); }
+  void RemoveAll() { bits_ = 0; }
+  uint64_t ToIntegral() const { return bits_; }
+  void PrintTo(StringStream* stream) const;
+
+ private:
+  uint64_t MaskFlag(GVNFlag flag) const {
+    return static_cast<uint64_t>(1) << static_cast<unsigned>(flag);
+  }
+  uint64_t MaskSpecial(int special) const {
+    ASSERT(special >= 0);
+    ASSERT(special < kNumberOfSpecials);
+    return static_cast<uint64_t>(1) << static_cast<unsigned>(
+        special + kNumberOfFlags);
+  }
+
+  uint64_t bits_;
+  STATIC_ASSERT(kNumberOfFlags + kNumberOfSpecials == sizeof(bits_) * CHAR_BIT);
+};
+
+
+// Tracks inobject field loads/stores in a fine grained fashion, and represents
+// them using the "special" dynamic side effects of the SideEffects class (see
+// above). This way unrelated inobject field stores don't prevent hoisting and
+// merging of inobject field loads.
+class SideEffectsTracker V8_FINAL BASE_EMBEDDED {
+ public:
+  SideEffectsTracker() : num_inobject_fields_(0) {}
+  SideEffects ComputeChanges(HInstruction* instr);
+  SideEffects ComputeDependsOn(HInstruction* instr);
+  void PrintSideEffectsTo(StringStream* stream, SideEffects side_effects) const;
+
+ private:
+  bool ComputeInobjectField(HObjectAccess access, int* index);
+
+  HObjectAccess inobject_fields_[SideEffects::kNumberOfSpecials];
+  int num_inobject_fields_;
+};
+
+
 // Perform common subexpression elimination and loop-invariant code motion.
-class HGlobalValueNumberingPhase : public HPhase {
+class HGlobalValueNumberingPhase V8_FINAL : public HPhase {
  public:
   explicit HGlobalValueNumberingPhase(HGraph* graph);
 
   void Run();
 
  private:
-  GVNFlagSet CollectSideEffectsOnPathsToDominatedBlock(
+  SideEffects CollectSideEffectsOnPathsToDominatedBlock(
       HBasicBlock* dominator,
       HBasicBlock* dominated);
   void AnalyzeGraph();
@@ -52,17 +113,18 @@ class HGlobalValueNumberingPhase : public HPhase {
   void LoopInvariantCodeMotion();
   void ProcessLoopBlock(HBasicBlock* block,
                         HBasicBlock* before_loop,
-                        GVNFlagSet loop_kills);
+                        SideEffects loop_kills);
   bool AllowCodeMotion();
   bool ShouldMove(HInstruction* instr, HBasicBlock* loop_header);
 
+  SideEffectsTracker side_effects_tracker_;
   bool removed_side_effects_;
 
   // A map of block IDs to their side effects.
-  ZoneList<GVNFlagSet> block_side_effects_;
+  ZoneList<SideEffects> block_side_effects_;
 
   // A map of loop header block IDs to their loop's side effects.
-  ZoneList<GVNFlagSet> loop_side_effects_;
+  ZoneList<SideEffects> loop_side_effects_;
 
   // Used when collecting side effects on paths from dominator to
   // dominated.
@@ -71,7 +133,6 @@ class HGlobalValueNumberingPhase : public HPhase {
   DISALLOW_COPY_AND_ASSIGN(HGlobalValueNumberingPhase);
 };
 
-
 } }  // namespace v8::internal
 
 #endif  // V8_HYDROGEN_GVN_H_
index 59d4f47..6e511d5 100644 (file)
@@ -604,11 +604,11 @@ void HValue::PrintChangesTo(StringStream* stream) {
     stream->Add("*");
   } else {
     bool add_comma = false;
-#define PRINT_DO(type)                            \
-    if (changes_flags.Contains(kChanges##type)) { \
-      if (add_comma) stream->Add(",");            \
-      add_comma = true;                           \
-      stream->Add(#type);                         \
+#define PRINT_DO(Type)                      \
+    if (changes_flags.Contains(k##Type)) {  \
+      if (add_comma) stream->Add(",");      \
+      add_comma = true;                     \
+      stream->Add(#Type);                   \
     }
     GVN_TRACKED_FLAG_LIST(PRINT_DO);
     GVN_UNTRACKED_FLAG_LIST(PRINT_DO);
@@ -1516,7 +1516,7 @@ void HCheckInstanceType::GetCheckMaskAndTag(uint8_t* mask, uint8_t* tag) {
 
 bool HCheckMaps::HandleSideEffectDominator(GVNFlag side_effect,
                                            HValue* dominator) {
-  ASSERT(side_effect == kChangesMaps);
+  ASSERT(side_effect == kMaps);
   // TODO(mstarzinger): For now we specialize on HStoreNamedField, but once
   // type information is rich enough we should generalize this to any HType
   // for which the map is known.
@@ -1624,7 +1624,7 @@ Range* HChange::InferRange(Zone* zone) {
         input_range != NULL &&
         input_range->IsInSmiRange()))) {
     set_type(HType::Smi());
-    ClearGVNFlag(kChangesNewSpacePromotion);
+    ClearChangesFlag(kNewSpacePromotion);
   }
   Range* result = (input_range != NULL)
       ? input_range->Copy(zone)
@@ -3412,7 +3412,7 @@ Representation HUnaryMathOperation::RepresentationFromInputs() {
 
 bool HAllocate::HandleSideEffectDominator(GVNFlag side_effect,
                                           HValue* dominator) {
-  ASSERT(side_effect == kChangesNewSpacePromotion);
+  ASSERT(side_effect == kNewSpacePromotion);
   Zone* zone = block()->zone();
   if (!FLAG_use_allocation_folding) return false;
 
@@ -4394,52 +4394,76 @@ void HObjectAccess::SetGVNFlags(HValue *instr, PropertyAccessType access_type) {
   // set the appropriate GVN flags for a given load or store instruction
   if (access_type == STORE) {
     // track dominating allocations in order to eliminate write barriers
-    instr->SetGVNFlag(kDependsOnNewSpacePromotion);
+    instr->SetDependsOnFlag(::v8::internal::kNewSpacePromotion);
     instr->SetFlag(HValue::kTrackSideEffectDominators);
   } else {
     // try to GVN loads, but don't hoist above map changes
     instr->SetFlag(HValue::kUseGVN);
-    instr->SetGVNFlag(kDependsOnMaps);
+    instr->SetDependsOnFlag(::v8::internal::kMaps);
   }
 
   switch (portion()) {
     case kArrayLengths:
-      instr->SetGVNFlag(access_type == STORE
-          ? kChangesArrayLengths : kDependsOnArrayLengths);
+      if (access_type == STORE) {
+        instr->SetChangesFlag(::v8::internal::kArrayLengths);
+      } else {
+        instr->SetDependsOnFlag(::v8::internal::kArrayLengths);
+      }
       break;
     case kStringLengths:
-      instr->SetGVNFlag(access_type == STORE
-          ? kChangesStringLengths : kDependsOnStringLengths);
+      if (access_type == STORE) {
+        instr->SetChangesFlag(::v8::internal::kStringLengths);
+      } else {
+        instr->SetDependsOnFlag(::v8::internal::kStringLengths);
+      }
       break;
     case kInobject:
-      instr->SetGVNFlag(access_type == STORE
-          ? kChangesInobjectFields : kDependsOnInobjectFields);
+      if (access_type == STORE) {
+        instr->SetChangesFlag(::v8::internal::kInobjectFields);
+      } else {
+        instr->SetDependsOnFlag(::v8::internal::kInobjectFields);
+      }
       break;
     case kDouble:
-      instr->SetGVNFlag(access_type == STORE
-          ? kChangesDoubleFields : kDependsOnDoubleFields);
+      if (access_type == STORE) {
+        instr->SetChangesFlag(::v8::internal::kDoubleFields);
+      } else {
+        instr->SetDependsOnFlag(::v8::internal::kDoubleFields);
+      }
       break;
     case kBackingStore:
-      instr->SetGVNFlag(access_type == STORE
-          ? kChangesBackingStoreFields : kDependsOnBackingStoreFields);
+      if (access_type == STORE) {
+        instr->SetChangesFlag(::v8::internal::kBackingStoreFields);
+      } else {
+        instr->SetDependsOnFlag(::v8::internal::kBackingStoreFields);
+      }
       break;
     case kElementsPointer:
-      instr->SetGVNFlag(access_type == STORE
-          ? kChangesElementsPointer : kDependsOnElementsPointer);
+      if (access_type == STORE) {
+        instr->SetChangesFlag(::v8::internal::kElementsPointer);
+      } else {
+        instr->SetDependsOnFlag(::v8::internal::kElementsPointer);
+      }
       break;
     case kMaps:
-      instr->SetGVNFlag(access_type == STORE
-          ? kChangesMaps : kDependsOnMaps);
+      if (access_type == STORE) {
+        instr->SetChangesFlag(::v8::internal::kMaps);
+      } else {
+        instr->SetDependsOnFlag(::v8::internal::kMaps);
+      }
       break;
     case kExternalMemory:
-      instr->SetGVNFlag(access_type == STORE
-          ? kChangesExternalMemory : kDependsOnExternalMemory);
+      if (access_type == STORE) {
+        instr->SetChangesFlag(::v8::internal::kExternalMemory);
+      } else {
+        instr->SetDependsOnFlag(::v8::internal::kExternalMemory);
+      }
       break;
   }
 }
 
 
-void HObjectAccess::PrintTo(StringStream* stream) {
+void HObjectAccess::PrintTo(StringStream* stream) const {
   stream->Add(".");
 
   switch (portion()) {
index 9073ac3..6556760 100644 (file)
@@ -476,22 +476,28 @@ class HUseIterator V8_FINAL 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. All tracked flags should appear before untracked ones.
+// All tracked flags should appear before untracked ones.
 enum GVNFlag {
   // Declare global value numbering flags.
-#define DECLARE_FLAG(type) kChanges##type, kDependsOn##type,
+#define DECLARE_FLAG(Type) k##Type,
   GVN_TRACKED_FLAG_LIST(DECLARE_FLAG)
   GVN_UNTRACKED_FLAG_LIST(DECLARE_FLAG)
 #undef DECLARE_FLAG
-  kNumberOfFlags,
-#define COUNT_FLAG(type) + 1
-  kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG)
+#define COUNT_FLAG(Type) + 1
+  kNumberOfTrackedSideEffects = 0 GVN_TRACKED_FLAG_LIST(COUNT_FLAG),
+  kNumberOfUntrackedSideEffects = 0 GVN_UNTRACKED_FLAG_LIST(COUNT_FLAG),
 #undef COUNT_FLAG
+  kNumberOfFlags = kNumberOfTrackedSideEffects + kNumberOfUntrackedSideEffects
 };
 
 
+static inline GVNFlag GVNFlagFromInt(int i) {
+  ASSERT(i >= 0);
+  ASSERT(i < kNumberOfFlags);
+  return static_cast<GVNFlag>(i);
+}
+
+
 class DecompositionResult V8_FINAL BASE_EMBEDDED {
  public:
   DecompositionResult() : base_(NULL), offset_(0), scale_(0) {}
@@ -537,7 +543,7 @@ class DecompositionResult V8_FINAL BASE_EMBEDDED {
 };
 
 
-typedef EnumSet<GVNFlag, int64_t> GVNFlagSet;
+typedef EnumSet<GVNFlag, int32_t> GVNFlagSet;
 
 
 class HValue : public ZoneObject {
@@ -588,18 +594,6 @@ class HValue : public ZoneObject {
 
   STATIC_ASSERT(kLastFlag < kBitsPerInt);
 
-  static const int kChangesToDependsFlagsLeftShift = 1;
-
-  static GVNFlag ChangesFlagFromInt(int x) {
-    return static_cast<GVNFlag>(x * 2);
-  }
-  static GVNFlag DependsOnFlagFromInt(int x) {
-    return static_cast<GVNFlag>(x * 2 + 1);
-  }
-  static GVNFlagSet ConvertChangesToDependsFlags(GVNFlagSet flags) {
-    return GVNFlagSet(flags.ToIntegral() << kChangesToDependsFlagsLeftShift);
-  }
-
   static HValue* cast(HValue* value) { return value; }
 
   enum Opcode {
@@ -775,43 +769,38 @@ class HValue : public ZoneObject {
   // of uses is non-empty.
   bool HasAtLeastOneUseWithFlagAndNoneWithout(Flag f) const;
 
-  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()); }
+  GVNFlagSet ChangesFlags() const { return changes_flags_; }
+  GVNFlagSet DependsOnFlags() const { return depends_on_flags_; }
+  void SetChangesFlag(GVNFlag f) { changes_flags_.Add(f); }
+  void SetDependsOnFlag(GVNFlag f) { depends_on_flags_.Add(f); }
+  void ClearChangesFlag(GVNFlag f) { changes_flags_.Remove(f); }
+  void ClearDependsOnFlag(GVNFlag f) { depends_on_flags_.Remove(f); }
+  bool CheckChangesFlag(GVNFlag f) const {
+    return changes_flags_.Contains(f);
+  }
+  bool CheckDependsOnFlag(GVNFlag f) const {
+    return depends_on_flags_.Contains(f);
+  }
+  void SetAllSideEffects() { changes_flags_.Add(AllSideEffectsFlagSet()); }
   void ClearAllSideEffects() {
-    gvn_flags_.Remove(AllSideEffectsFlagSet());
+    changes_flags_.Remove(AllSideEffectsFlagSet());
   }
   bool HasSideEffects() const {
-    return gvn_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
+    return changes_flags_.ContainsAnyOf(AllSideEffectsFlagSet());
   }
   bool HasObservableSideEffects() const {
     return !CheckFlag(kHasNoObservableSideEffects) &&
-        gvn_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
-  }
-
-  GVNFlagSet DependsOnFlags() const {
-    GVNFlagSet result = gvn_flags_;
-    result.Intersect(AllDependsOnFlagSet());
-    return result;
+        changes_flags_.ContainsAnyOf(AllObservableSideEffectsFlagSet());
   }
 
   GVNFlagSet SideEffectFlags() const {
-    GVNFlagSet result = gvn_flags_;
+    GVNFlagSet result = ChangesFlags();
     result.Intersect(AllSideEffectsFlagSet());
     return result;
   }
 
-  GVNFlagSet ChangesFlags() const {
-    GVNFlagSet result = gvn_flags_;
-    result.Intersect(AllChangesFlagSet());
-    return result;
-  }
-
   GVNFlagSet ObservableChangesFlags() const {
-    GVNFlagSet result = gvn_flags_;
-    result.Intersect(AllChangesFlagSet());
+    GVNFlagSet result = ChangesFlags();
     result.Intersect(AllObservableSideEffectsFlagSet());
     return result;
   }
@@ -952,20 +941,9 @@ class HValue : public ZoneObject {
     representation_ = r;
   }
 
-  static GVNFlagSet AllDependsOnFlagSet() {
-    GVNFlagSet result;
-    // Create changes mask.
-#define ADD_FLAG(type) result.Add(kDependsOn##type);
-  GVN_TRACKED_FLAG_LIST(ADD_FLAG)
-  GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
-#undef ADD_FLAG
-    return result;
-  }
-
-  static GVNFlagSet AllChangesFlagSet() {
+  static GVNFlagSet AllFlagSet() {
     GVNFlagSet result;
-    // Create changes mask.
-#define ADD_FLAG(type) result.Add(kChanges##type);
+#define ADD_FLAG(Type) result.Add(k##Type);
   GVN_TRACKED_FLAG_LIST(ADD_FLAG)
   GVN_UNTRACKED_FLAG_LIST(ADD_FLAG)
 #undef ADD_FLAG
@@ -974,19 +952,19 @@ class HValue : public ZoneObject {
 
   // A flag mask to mark an instruction as having arbitrary side effects.
   static GVNFlagSet AllSideEffectsFlagSet() {
-    GVNFlagSet result = AllChangesFlagSet();
-    result.Remove(kChangesOsrEntries);
+    GVNFlagSet result = AllFlagSet();
+    result.Remove(kOsrEntries);
     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 GVNFlagSet AllObservableSideEffectsFlagSet() {
-    GVNFlagSet result = AllChangesFlagSet();
-    result.Remove(kChangesNewSpacePromotion);
-    result.Remove(kChangesElementsKind);
-    result.Remove(kChangesElementsPointer);
-    result.Remove(kChangesMaps);
+    GVNFlagSet result = AllFlagSet();
+    result.Remove(kNewSpacePromotion);
+    result.Remove(kElementsKind);
+    result.Remove(kElementsPointer);
+    result.Remove(kMaps);
     return result;
   }
 
@@ -1007,7 +985,8 @@ class HValue : public ZoneObject {
   HUseListNode* use_list_;
   Range* range_;
   int flags_;
-  GVNFlagSet gvn_flags_;
+  GVNFlagSet changes_flags_;
+  GVNFlagSet depends_on_flags_;
 
  private:
   virtual bool IsDeletable() const { return false; }
@@ -1261,7 +1240,7 @@ class HInstruction : public HValue {
         next_(NULL),
         previous_(NULL),
         position_(RelocInfo::kNoPosition) {
-    SetGVNFlag(kDependsOnOsrEntries);
+    SetDependsOnFlag(kOsrEntries);
   }
 
   virtual void DeleteFromGraph() V8_OVERRIDE { Unlink(); }
@@ -1721,7 +1700,7 @@ class HChange V8_FINAL : public HUnaryOperation {
       set_type(HType::Smi());
     } else {
       set_type(HType::TaggedNumber());
-      if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
+      if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
     }
   }
 
@@ -1967,7 +1946,7 @@ class HStackCheck V8_FINAL : public HTemplateInstruction<1> {
  private:
   HStackCheck(HValue* context, Type type) : type_(type) {
     SetOperandAt(0, context);
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetChangesFlag(kNewSpacePromotion);
   }
 
   Type type_;
@@ -2515,7 +2494,7 @@ class HMapEnumLength V8_FINAL : public HUnaryOperation {
       : HUnaryOperation(value, HType::Smi()) {
     set_representation(Representation::Smi());
     SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnMaps);
+    SetDependsOnFlag(kMaps);
   }
 
   virtual bool IsDeletable() const V8_OVERRIDE { return true; }
@@ -2589,7 +2568,7 @@ class HUnaryMathOperation V8_FINAL : public HTemplateInstruction<2> {
         SetFlag(kFlexibleRepresentation);
         // TODO(svenpanne) This flag is actually only needed if representation()
         // is tagged, and not when it is an unboxed double or unboxed integer.
-        SetGVNFlag(kChangesNewSpacePromotion);
+        SetChangesFlag(kNewSpacePromotion);
         break;
       case kMathLog:
       case kMathExp:
@@ -2638,7 +2617,7 @@ class HLoadRoot V8_FINAL : public HTemplateInstruction<0> {
     SetFlag(kUseGVN);
     // TODO(bmeurer): We'll need kDependsOnRoots once we add the
     // corresponding HStoreRoot instruction.
-    SetGVNFlag(kDependsOnCalls);
+    SetDependsOnFlag(kCalls);
   }
 
   virtual bool IsDeletable() const V8_OVERRIDE { return true; }
@@ -2703,7 +2682,7 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
     map_set_.Add(Unique<Map>(map), zone);
     if (!has_migration_target_ && map->is_migration_target()) {
       has_migration_target_ = true;
-      SetGVNFlag(kChangesNewSpacePromotion);
+      SetChangesFlag(kNewSpacePromotion);
     }
   }
 
@@ -2717,8 +2696,8 @@ class HCheckMaps V8_FINAL : public HTemplateInstruction<2> {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
     SetFlag(kTrackSideEffectDominators);
-    SetGVNFlag(kDependsOnMaps);
-    SetGVNFlag(kDependsOnElementsKind);
+    SetDependsOnFlag(kMaps);
+    SetDependsOnFlag(kElementsKind);
   }
 
   bool omit_;
@@ -3322,7 +3301,7 @@ class HCapturedObject V8_FINAL : public HDematerializedObject {
   void ReuseSideEffectsFromStore(HInstruction* store) {
     ASSERT(store->HasObservableSideEffects());
     ASSERT(store->IsStoreNamedField());
-    gvn_flags_.Add(store->gvn_flags());
+    changes_flags_.Add(store->ChangesFlags());
   }
 
   // Replay effects of this instruction on the given environment.
@@ -3955,7 +3934,7 @@ class HBitwiseBinaryOperation : public HBinaryOperation {
   }
 
   virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
-    if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
+    if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
     if (to.IsTagged() &&
         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
       SetAllSideEffects();
@@ -4032,7 +4011,7 @@ class HArithmeticBinaryOperation : public HBinaryOperation {
   }
 
   virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
-    if (to.IsTagged()) SetGVNFlag(kChangesNewSpacePromotion);
+    if (to.IsTagged()) SetChangesFlag(kNewSpacePromotion);
     if (to.IsTagged() &&
         (left()->ToNumberCanBeObserved() || right()->ToNumberCanBeObserved())) {
       SetAllSideEffects();
@@ -4357,7 +4336,7 @@ class HStringCompareAndBranch : public HTemplateControlInstruction<2, 3> {
     SetOperandAt(1, left);
     SetOperandAt(2, right);
     set_representation(Representation::Tagged());
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetChangesFlag(kNewSpacePromotion);
   }
 
   Token::Value token_;
@@ -4582,7 +4561,7 @@ class HPower V8_FINAL : public HTemplateInstruction<2> {
     SetOperandAt(1, right);
     set_representation(Representation::Double());
     SetFlag(kUseGVN);
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetChangesFlag(kNewSpacePromotion);
   }
 
   virtual bool IsDeletable() const V8_OVERRIDE {
@@ -4624,7 +4603,7 @@ class HAdd V8_FINAL : public HArithmeticBinaryOperation {
 
   virtual void RepresentationChanged(Representation to) V8_OVERRIDE {
     if (to.IsTagged()) {
-      SetGVNFlag(kChangesNewSpacePromotion);
+      SetChangesFlag(kNewSpacePromotion);
       ClearFlag(kAllowUndefinedAsNaN);
     }
     if (to.IsTagged() &&
@@ -5081,8 +5060,8 @@ class HOsrEntry V8_FINAL : public HTemplateInstruction<0> {
 
  private:
   explicit HOsrEntry(BailoutId ast_id) : ast_id_(ast_id) {
-    SetGVNFlag(kChangesOsrEntries);
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetChangesFlag(kOsrEntries);
+    SetChangesFlag(kNewSpacePromotion);
   }
 
   BailoutId ast_id_;
@@ -5224,7 +5203,7 @@ class HLoadGlobalCell V8_FINAL : public HTemplateInstruction<0> {
     : cell_(Unique<Cell>::CreateUninitialized(cell)), details_(details) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnGlobalVars);
+    SetDependsOnFlag(kGlobalVars);
   }
 
   virtual bool IsDeletable() const V8_OVERRIDE { return !RequiresHoleCheck(); }
@@ -5376,8 +5355,8 @@ class HAllocate V8_FINAL : public HTemplateInstruction<2> {
     SetOperandAt(1, size);
     set_representation(Representation::Tagged());
     SetFlag(kTrackSideEffectDominators);
-    SetGVNFlag(kChangesNewSpacePromotion);
-    SetGVNFlag(kDependsOnNewSpacePromotion);
+    SetChangesFlag(kNewSpacePromotion);
+    SetDependsOnFlag(kNewSpacePromotion);
 
     if (FLAG_trace_pretenuring) {
       PrintF("HAllocate with AllocationSite %p %s\n",
@@ -5575,7 +5554,7 @@ class HStoreGlobalCell V8_FINAL : public HUnaryOperation {
       : HUnaryOperation(value),
         cell_(Unique<PropertyCell>::CreateUninitialized(cell)),
         details_(details) {
-    SetGVNFlag(kChangesGlobalVars);
+    SetChangesFlag(kGlobalVars);
   }
 
   Unique<PropertyCell> cell_;
@@ -5614,7 +5593,7 @@ class HLoadContextSlot V8_FINAL : public HUnaryOperation {
     }
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnContextSlots);
+    SetDependsOnFlag(kContextSlots);
   }
 
   int slot_index() const { return slot_index_; }
@@ -5698,7 +5677,7 @@ class HStoreContextSlot V8_FINAL : public HTemplateInstruction<2> {
       : slot_index_(slot_index), mode_(mode) {
     SetOperandAt(0, context);
     SetOperandAt(1, value);
-    SetGVNFlag(kChangesContextSlots);
+    SetChangesFlag(kContextSlots);
   }
 
   int slot_index_;
@@ -5976,7 +5955,7 @@ class HObjectAccess V8_FINAL {
     return HObjectAccess(kInobject, GlobalObject::kNativeContextOffset);
   }
 
-  void PrintTo(StringStream* stream);
+  void PrintTo(StringStream* stream) const;
 
   inline bool Equals(HObjectAccess that) const {
     return value_ == that.value_;  // portion and offset must match
@@ -5998,6 +5977,8 @@ class HObjectAccess V8_FINAL {
     kExternalMemory    // some field in external memory
   };
 
+  HObjectAccess() : value_(0) {}
+
   HObjectAccess(Portion portion, int offset,
                 Representation representation = Representation::Tagged(),
                 Handle<String> name = Handle<String>::null(),
@@ -6030,6 +6011,7 @@ class HObjectAccess V8_FINAL {
 
   friend class HLoadNamedField;
   friend class HStoreNamedField;
+  friend class SideEffectsScope;
 
   inline Portion portion() const {
     return PortionField::decode(value_);
@@ -6166,7 +6148,7 @@ class HLoadFunctionPrototype V8_FINAL : public HUnaryOperation {
       : HUnaryOperation(function) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnCalls);
+    SetDependsOnFlag(kCalls);
   }
 };
 
@@ -6311,10 +6293,10 @@ class HLoadKeyed V8_FINAL
           set_representation(Representation::Tagged());
         }
 
-        SetGVNFlag(kDependsOnArrayElements);
+        SetDependsOnFlag(kArrayElements);
       } else {
         set_representation(Representation::Double());
-        SetGVNFlag(kDependsOnDoubleArrayElements);
+        SetDependsOnFlag(kDoubleArrayElements);
       }
     } else {
       if (elements_kind == EXTERNAL_FLOAT32_ELEMENTS ||
@@ -6327,14 +6309,14 @@ class HLoadKeyed V8_FINAL
       }
 
       if (is_external()) {
-        SetGVNFlag(kDependsOnExternalMemory);
+        SetDependsOnFlag(kExternalMemory);
       } else if (is_fixed_typed_array()) {
-        SetGVNFlag(kDependsOnTypedArrayElements);
+        SetDependsOnFlag(kTypedArrayElements);
       } else {
         UNREACHABLE();
       }
       // Native code could change the specialized array.
-      SetGVNFlag(kDependsOnCalls);
+      SetDependsOnFlag(kCalls);
     }
 
     SetFlag(kUseGVN);
@@ -6458,7 +6440,7 @@ class HStoreNamedField V8_FINAL : public HTemplateInstruction<3> {
   }
   virtual bool HandleSideEffectDominator(GVNFlag side_effect,
                                          HValue* dominator) V8_OVERRIDE {
-    ASSERT(side_effect == kChangesNewSpacePromotion);
+    ASSERT(side_effect == kNewSpacePromotion);
     new_space_dominator_ = dominator;
     return false;
   }
@@ -6690,7 +6672,7 @@ class HStoreKeyed V8_FINAL
 
   virtual bool HandleSideEffectDominator(GVNFlag side_effect,
                                          HValue* dominator) V8_OVERRIDE {
-    ASSERT(side_effect == kChangesNewSpacePromotion);
+    ASSERT(side_effect == kNewSpacePromotion);
     new_space_dominator_ = dominator;
     return false;
   }
@@ -6733,20 +6715,20 @@ class HStoreKeyed V8_FINAL
 
     if (IsFastObjectElementsKind(elements_kind)) {
       SetFlag(kTrackSideEffectDominators);
-      SetGVNFlag(kDependsOnNewSpacePromotion);
+      SetDependsOnFlag(kNewSpacePromotion);
     }
     if (is_external()) {
-      SetGVNFlag(kChangesExternalMemory);
+      SetChangesFlag(kExternalMemory);
       SetFlag(kAllowUndefinedAsNaN);
     } else if (IsFastDoubleElementsKind(elements_kind)) {
-      SetGVNFlag(kChangesDoubleArrayElements);
+      SetChangesFlag(kDoubleArrayElements);
     } else if (IsFastSmiElementsKind(elements_kind)) {
-      SetGVNFlag(kChangesArrayElements);
+      SetChangesFlag(kArrayElements);
     } else if (is_fixed_typed_array()) {
-      SetGVNFlag(kChangesTypedArrayElements);
+      SetChangesFlag(kTypedArrayElements);
       SetFlag(kAllowUndefinedAsNaN);
     } else {
-      SetGVNFlag(kChangesArrayElements);
+      SetChangesFlag(kArrayElements);
     }
 
     // EXTERNAL_{UNSIGNED_,}{BYTE,SHORT,INT}_ELEMENTS are truncating.
@@ -6850,10 +6832,10 @@ class HTransitionElementsKind V8_FINAL : public HTemplateInstruction<2> {
     SetOperandAt(0, object);
     SetOperandAt(1, context);
     SetFlag(kUseGVN);
-    SetGVNFlag(kChangesElementsKind);
+    SetChangesFlag(kElementsKind);
     if (!IsSimpleMapChangeTransition(from_kind_, to_kind_)) {
-      SetGVNFlag(kChangesElementsPointer);
-      SetGVNFlag(kChangesNewSpacePromotion);
+      SetChangesFlag(kElementsPointer);
+      SetChangesFlag(kNewSpacePromotion);
     }
     set_representation(Representation::Tagged());
   }
@@ -6904,8 +6886,8 @@ class HStringAdd V8_FINAL : public HBinaryOperation {
         flags_(flags), pretenure_flag_(pretenure_flag) {
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnMaps);
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetDependsOnFlag(kMaps);
+    SetChangesFlag(kNewSpacePromotion);
     if (FLAG_trace_pretenuring) {
       PrintF("HStringAdd with AllocationSite %p %s\n",
              allocation_site.is_null()
@@ -6956,9 +6938,9 @@ class HStringCharCodeAt V8_FINAL : public HTemplateInstruction<3> {
     SetOperandAt(2, index);
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnMaps);
-    SetGVNFlag(kDependsOnStringChars);
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetDependsOnFlag(kMaps);
+    SetDependsOnFlag(kStringChars);
+    SetChangesFlag(kNewSpacePromotion);
   }
 
   // No side effects: runtime function assumes string + number inputs.
@@ -6992,7 +6974,7 @@ class HStringCharFromCode V8_FINAL : public HTemplateInstruction<2> {
     SetOperandAt(1, char_code);
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetChangesFlag(kNewSpacePromotion);
   }
 
   virtual bool IsDeletable() const V8_OVERRIDE {
@@ -7101,7 +7083,7 @@ class HFunctionLiteral V8_FINAL : public HTemplateInstruction<1> {
         language_mode_(shared->language_mode()) {
     SetOperandAt(0, context);
     set_representation(Representation::Tagged());
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetChangesFlag(kNewSpacePromotion);
   }
 
   virtual bool IsDeletable() const V8_OVERRIDE { return true; }
@@ -7172,7 +7154,7 @@ class HToFastProperties V8_FINAL : public HUnaryOperation {
  private:
   explicit HToFastProperties(HValue* value) : HUnaryOperation(value) {
     set_representation(Representation::Tagged());
-    SetGVNFlag(kChangesNewSpacePromotion);
+    SetChangesFlag(kNewSpacePromotion);
 
     // This instruction is not marked as kChangesMaps, but does
     // change the map of the input operand. Use it only when creating
@@ -7251,7 +7233,7 @@ class HSeqStringGetChar V8_FINAL : public HTemplateInstruction<2> {
     SetOperandAt(1, index);
     set_representation(Representation::Integer32());
     SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnStringChars);
+    SetDependsOnFlag(kStringChars);
   }
 
   virtual bool IsDeletable() const V8_OVERRIDE { return true; }
@@ -7290,7 +7272,7 @@ class HSeqStringSetChar V8_FINAL : public HTemplateInstruction<4> {
     SetOperandAt(2, index);
     SetOperandAt(3, value);
     set_representation(Representation::Tagged());
-    SetGVNFlag(kChangesStringChars);
+    SetChangesFlag(kStringChars);
   }
 
   String::Encoding encoding_;
@@ -7330,8 +7312,8 @@ class HCheckMapValue V8_FINAL : public HTemplateInstruction<2> {
     SetOperandAt(1, map);
     set_representation(Representation::Tagged());
     SetFlag(kUseGVN);
-    SetGVNFlag(kDependsOnMaps);
-    SetGVNFlag(kDependsOnElementsKind);
+    SetDependsOnFlag(kMaps);
+    SetDependsOnFlag(kElementsKind);
   }
 };
 
index 56839b2..5f69625 100644 (file)
@@ -99,25 +99,25 @@ class HLoadEliminationTable : public ZoneObject {
         break;
       }
       default: {
-        if (instr->CheckGVNFlag(kChangesInobjectFields)) {
+        if (instr->CheckChangesFlag(kInobjectFields)) {
           TRACE((" kill-all i%d\n", instr->id()));
           Kill();
           break;
         }
-        if (instr->CheckGVNFlag(kChangesMaps)) {
+        if (instr->CheckChangesFlag(kMaps)) {
           TRACE((" kill-maps i%d\n", instr->id()));
           KillOffset(JSObject::kMapOffset);
         }
-        if (instr->CheckGVNFlag(kChangesElementsKind)) {
+        if (instr->CheckChangesFlag(kElementsKind)) {
           TRACE((" kill-elements-kind i%d\n", instr->id()));
           KillOffset(JSObject::kMapOffset);
           KillOffset(JSObject::kElementsOffset);
         }
-        if (instr->CheckGVNFlag(kChangesElementsPointer)) {
+        if (instr->CheckChangesFlag(kElementsPointer)) {
           TRACE((" kill-elements i%d\n", instr->id()));
           KillOffset(JSObject::kElementsOffset);
         }
-        if (instr->CheckGVNFlag(kChangesOsrEntries)) {
+        if (instr->CheckChangesFlag(kOsrEntries)) {
           TRACE((" kill-osr i%d\n", instr->id()));
           Kill();
         }
@@ -454,11 +454,11 @@ class HLoadEliminationEffects : public ZoneObject {
         elements_stored_ = true;
       }
       default: {
-        fields_stored_ |= instr->CheckGVNFlag(kChangesInobjectFields);
-        maps_stored_ |= instr->CheckGVNFlag(kChangesMaps);
-        maps_stored_ |= instr->CheckGVNFlag(kChangesElementsKind);
-        elements_stored_ |= instr->CheckGVNFlag(kChangesElementsKind);
-        elements_stored_ |= instr->CheckGVNFlag(kChangesElementsPointer);
+        fields_stored_ |= instr->CheckChangesFlag(kInobjectFields);
+        maps_stored_ |= instr->CheckChangesFlag(kMaps);
+        maps_stored_ |= instr->CheckChangesFlag(kElementsKind);
+        elements_stored_ |= instr->CheckChangesFlag(kElementsKind);
+        elements_stored_ |= instr->CheckChangesFlag(kElementsPointer);
       }
     }
   }
index da415d4..b035ed1 100644 (file)
@@ -2174,7 +2174,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
   // generated store code.
   if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
       (elements_kind == FAST_ELEMENTS && access_type == STORE)) {
-    checked_object->ClearGVNFlag(kDependsOnElementsKind);
+    checked_object->ClearDependsOnFlag(kElementsKind);
   }
 
   bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
@@ -2184,7 +2184,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
       store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
     HCheckMaps* check_cow_map = Add<HCheckMaps>(
         elements, isolate()->factory()->fixed_array_map(), top_info());
-    check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
+    check_cow_map->ClearDependsOnFlag(kElementsKind);
   }
   HInstruction* length = NULL;
   if (is_js_array) {
@@ -2258,7 +2258,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess(
       } else {
         HCheckMaps* check_cow_map = Add<HCheckMaps>(
             elements, isolate()->factory()->fixed_array_map(), top_info());
-        check_cow_map->ClearGVNFlag(kDependsOnElementsKind);
+        check_cow_map->ClearDependsOnFlag(kElementsKind);
       }
     }
   }
@@ -5309,7 +5309,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField(
   if (transition_to_field) {
     HConstant* transition_constant = Add<HConstant>(info->transition());
     instr->SetTransition(transition_constant, top_info());
-    instr->SetGVNFlag(kChangesMaps);
+    instr->SetChangesFlag(kMaps);
   }
   return instr;
 }
@@ -6208,7 +6208,7 @@ HInstruction* HOptimizedGraphBuilder::BuildMonomorphicElementAccess(
   HCheckMaps* checked_object = Add<HCheckMaps>(object, map, top_info(),
                                                dependency);
   if (dependency) {
-    checked_object->ClearGVNFlag(kDependsOnElementsKind);
+    checked_object->ClearDependsOnFlag(kElementsKind);
   }
 
   if (access_type == STORE && map->prototype()->IsJSObject()) {
@@ -6688,7 +6688,7 @@ HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
   AddInstruction(constant_value);
   HCheckMaps* check =
       Add<HCheckMaps>(constant_value, handle(constant->map()), info);
-  check->ClearGVNFlag(kDependsOnElementsKind);
+  check->ClearDependsOnFlag(kElementsKind);
   return check;
 }