Refactor JumpTarget::Combine.
authorkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 13 May 2009 10:29:49 +0000 (10:29 +0000)
committerkmillikin@chromium.org <kmillikin@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 13 May 2009 10:29:49 +0000 (10:29 +0000)
Review URL: http://codereview.chromium.org/113329

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

src/arm/virtual-frame-arm.h
src/ia32/virtual-frame-ia32.h
src/jump-target.cc
src/jump-target.h
src/virtual-frame.h
src/x64/virtual-frame-x64.h

index 371a23e..460d4f3 100644 (file)
@@ -471,6 +471,18 @@ class VirtualFrame : public Malloced {
 
   bool Equals(VirtualFrame* other);
 
+  // Perform initialization required during entry frame computation
+  // after setting the virtual frame element at index in frame to be
+  // target.
+  void InitializeEntryElement(int index, FrameElement* target) {
+    elements_[index].clear_copied();
+    if (target->is_register()) {
+      register_locations_[target->reg().code()] = index;
+    } else if (target->is_copy()) {
+      elements_[target->index()].set_copied();
+    }
+  }
+
   friend class JumpTarget;
 };
 
index 298eda2..77d803d 100644 (file)
@@ -485,6 +485,18 @@ class VirtualFrame : public Malloced {
 
   bool Equals(VirtualFrame* other);
 
+  // Perform initialization required during entry frame computation
+  // after setting the virtual frame element at index in frame to be
+  // target.
+  void InitializeEntryElement(int index, FrameElement* target) {
+    elements_[index].clear_copied();
+    if (target->is_register()) {
+      register_locations_[target->reg().code()] = index;
+    } else if (target->is_copy()) {
+      elements_[target->index()].set_copied();
+    }
+  }
+
   friend class JumpTarget;
 };
 
index 5ab49df..56d4448 100644 (file)
@@ -92,69 +92,6 @@ void JumpTarget::Reset() {
 }
 
 
-FrameElement* JumpTarget::Combine(FrameElement* left, FrameElement* right) {
-  // Given a pair of non-null frame element pointers, return one of
-  // them as an entry frame candidate or null if they are
-  // incompatible.
-
-  // If either is invalid, the result is.
-  if (!left->is_valid()) return left;
-  if (!right->is_valid()) return right;
-
-  // If they have the exact same location, the result is in that
-  // location, otherwise we reallocate.  If either is unsynced, the
-  // result is.  The result static type is the merge of the static
-  // types.  It's safe to set it on one of the frame elements, and
-  // harmless too (because we are only going to merge the reaching
-  // frames and will ensure that the types are coherent, and changing
-  // the static type does not emit code).
-
-  StaticType type = left->static_type().merge(right->static_type());
-  if (left->is_memory() && right->is_memory()) {
-    left->set_static_type(type);
-    return left;
-  }
-
-  if (left->is_register() && right->is_register() &&
-      left->reg().is(right->reg())) {
-    if (!left->is_synced()) {
-      left->set_static_type(type);
-      return left;
-    } else {
-      right->set_static_type(type);
-      return right;
-    }
-  }
-
-  if (left->is_constant() &&
-      right->is_constant() &&
-      left->handle().is_identical_to(right->handle())) {
-    if (!left->is_synced()) {
-      left->set_static_type(type);
-      return left;
-    } else {
-      right->set_static_type(type);
-      return right;
-    }
-  }
-
-  if (left->is_copy() &&
-      right->is_copy() &&
-      left->index() == right->index()) {
-    if (!left->is_synced()) {
-      left->set_static_type(type);
-      return left;
-    } else {
-      right->set_static_type(type);
-      return right;
-    }
-  }
-
-  // Otherwise they are incompatible and we will reallocate them.
-  return NULL;
-}
-
-
 void JumpTarget::ComputeEntryFrame(int mergable_elements) {
   // Given: a collection of frames reaching by forward CFG edges and
   // the directionality of the block.  Compute: an entry frame for the
@@ -198,15 +135,15 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
   // Compute elements based on the other reaching frames.
   if (reaching_frames_.length() > 1) {
     for (int i = 0; i < length; i++) {
+      FrameElement* element = elements[i];
       for (int j = 1; j < reaching_frames_.length(); j++) {
-        FrameElement* element = elements[i];
-
         // Element computation is monotonic: new information will not
         // change our decision about undetermined or invalid elements.
         if (element == NULL || !element->is_valid()) break;
 
-        elements[i] = Combine(element, &reaching_frames_[j]->elements_[i]);
+        element = element->Combine(&reaching_frames_[j]->elements_[i]);
       }
+      elements[i] = element;
     }
   }
 
@@ -216,33 +153,23 @@ void JumpTarget::ComputeEntryFrame(int mergable_elements) {
   entry_frame_ = new VirtualFrame(cgen_);
   int index = 0;
   for (; index < entry_frame_->elements_.length(); index++) {
+    FrameElement* target = elements[index];
     // If the element is determined, set it now.  Count registers.  Mark
     // elements as copied exactly when they have a copy.  Undetermined
     // elements are initially recorded as if in memory.
-    if (elements[index] != NULL) {
-      entry_frame_->elements_[index] = *elements[index];
-      entry_frame_->elements_[index].clear_copied();
-      if (elements[index]->is_register()) {
-        entry_frame_->register_locations_[elements[index]->reg().code()] =
-            index;
-      } else if (elements[index]->is_copy()) {
-        entry_frame_->elements_[elements[index]->index()].set_copied();
-      }
+    if (target != NULL) {
+      entry_frame_->elements_[index] = *target;
+      entry_frame_->InitializeEntryElement(index, target);
     }
   }
   // Then fill in the rest of the frame with new elements.
   for (; index < length; index++) {
-    if (elements[index] == NULL) {
+    FrameElement* target = elements[index];
+    if (target == NULL) {
       entry_frame_->elements_.Add(FrameElement::MemoryElement());
     } else {
-      entry_frame_->elements_.Add(*elements[index]);
-      entry_frame_->elements_[index].clear_copied();
-      if (elements[index]->is_register()) {
-        entry_frame_->register_locations_[elements[index]->reg().code()] =
-            index;
-      } else if (elements[index]->is_copy()) {
-        entry_frame_->elements_[elements[index]->index()].set_copied();
-      }
+      entry_frame_->elements_.Add(*target);
+      entry_frame_->InitializeEntryElement(index, target);
     }
   }
 
index 1cfbe29..9b63b54 100644 (file)
@@ -202,10 +202,6 @@ class JumpTarget : public Malloced {  // Shadows are dynamically allocated.
   // jump, and a fresh label for its merge code.
   void AddReachingFrame(VirtualFrame* frame);
 
-  // Choose an element from a pair of frame elements to be in the
-  // expected frame.  Return null if they are incompatible.
-  FrameElement* Combine(FrameElement* left, FrameElement* right);
-
   // Compute a frame to use for entry to this block.  Mergable
   // elements is as described for the Bind function.
   void ComputeEntryFrame(int mergable_elements);
index 794f156..091e22a 100644 (file)
@@ -121,8 +121,6 @@ class FrameElement BASE_EMBEDDED {
     return data_.index_;
   }
 
-  bool Equals(FrameElement other);
-
   StaticType static_type() { return static_type_; }
 
   void set_static_type(StaticType static_type) {
@@ -131,6 +129,34 @@ class FrameElement BASE_EMBEDDED {
     static_type_ = static_type;
   }
 
+  // True if the frame elements are identical (all data members).
+  bool Equals(FrameElement other);
+
+  // Given a pair of non-null frame element pointers, return one of them
+  // as an entry frame candidate or null if they are incompatible.
+  FrameElement* Combine(FrameElement* other) {
+    // If either is invalid, the result is.
+    if (!is_valid()) return this;
+    if (!other->is_valid()) return other;
+
+    // If they do not have the exact same location we reallocate.
+    bool not_same_location =
+        (type_ != other->type_) ||
+        (is_register() && !reg().is(other->reg())) ||
+        (is_constant() && !handle().is_identical_to(other->handle())) ||
+        (is_copy() && index() != other->index());
+    if (not_same_location) return NULL;
+
+    // If either is unsynced, the result is.  The result static type is
+    // the merge of the static types.  It's safe to set it on one of the
+    // frame elements, and harmless too (because we are only going to
+    // merge the reaching frames and will ensure that the types are
+    // coherent, and changing the static type does not emit code).
+    FrameElement* result = is_synced() ? other : this;
+    result->set_static_type(static_type().merge(other->static_type()));
+    return result;
+  }
+
  private:
   enum Type {
     INVALID,
index f71766d..f64d8e1 100644 (file)
@@ -485,6 +485,18 @@ class VirtualFrame : public Malloced {
 
   bool Equals(VirtualFrame* other);
 
+  // Perform initialization required during entry frame computation
+  // after setting the virtual frame element at index in frame to be
+  // target.
+  void InitializeEntryElement(int index, FrameElement* target) {
+    elements_[index].clear_copied();
+    if (target->is_register()) {
+      register_locations_[target->reg().code()] = index;
+    } else if (target->is_copy()) {
+      elements_[target->index()].set_copied();
+    }
+  }
+
   friend class JumpTarget;
 };