Author: [email protected]
Date: Tue Apr 28 06:53:15 2009
New Revision: 1808

Modified:
    branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc
    branches/bleeding_edge/src/virtual-frame.h

Log:
Change MergeTo code for virtual frames to use register indices.
Review URL: http://codereview.chromium.org/99052

Modified: branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc
==============================================================================
--- branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc       (original)
+++ branches/bleeding_edge/src/ia32/virtual-frame-ia32.cc       Tue Apr 28  
06:53:15 2009
@@ -310,64 +310,33 @@
    // We have already done X-to-memory moves.
    ASSERT(stack_pointer_ >= expected->stack_pointer_);

-  // Perform register-to-register moves.
-  int start = 0;
-  int end = elements_.length() - 1;
-  bool any_moves_blocked;  // Did we fail to make some moves this  
iteration?
-  bool should_break_cycles = false;
-  bool any_moves_made;  // Did we make any progress this iteration?
-  do {
-    any_moves_blocked = false;
-    any_moves_made = false;
-    int first_move_blocked = kIllegalIndex;
-    int last_move_blocked = kIllegalIndex;
-    for (int i = start; i <= end; i++) {
-      FrameElement source = elements_[i];
-      FrameElement target = expected->elements_[i];
-      if (source.is_register() && target.is_register()) {
-        if (target.reg().is(source.reg())) {
-          if (target.is_synced() && !source.is_synced()) {
-            __ mov(Operand(ebp, fp_relative(i)), source.reg());
-          }
-          elements_[i] = target;
-        } else {
-          // We need to move source to target.
-          if (is_used(target.reg())) {
-            // The move is blocked because the target contains valid data.
-            // If we are stuck with only cycles remaining, then we spill  
source.
-            // Otherwise, we just need more iterations.
-            if (should_break_cycles) {
-              SpillElementAt(i);
-              should_break_cycles = false;
-            } else {  // Record a blocked move.
-              if (!any_moves_blocked) {
-                first_move_blocked = i;
-              }
-              last_move_blocked = i;
-              any_moves_blocked = true;
-            }
-          } else {
-            // The move is not blocked.  This frame element can be moved  
from
-            // its source register to its target register.
-            if (target.is_synced() && !source.is_synced()) {
-              SyncElementAt(i);
-            }
-            Use(target.reg(), i);
-            Unuse(source.reg());
-            elements_[i] = target;
-            __ mov(target.reg(), source.reg());
-            any_moves_made = true;
-          }
-        }
+  for (int i = 0; i < kNumRegisters; i++) {
+    // Move the right value into register i if it is currently in a  
register.
+    int index = expected->register_locations_[i];
+    int use_index = register_locations_[i];
+    // Fast check if register is unused in target or already correct
+    if (index != kIllegalIndex
+        && index != use_index
+        && elements_[index].is_register()) {
+      Register source = elements_[index].reg();
+      Register target = { i };
+      if (use_index == kIllegalIndex) {  // Target is currently unused.
+        // Copy contents of source from source to target.
+        // Set frame element register to target.
+        elements_[index].set_reg(target);
+        Use(target, index);
+        Unuse(source);
+        __ mov(target, source);
+      } else {
+        // Exchange contents of registers source and target.
+        elements_[use_index].set_reg(source);
+        elements_[index].set_reg(target);
+        register_locations_[target.code()] = index;
+        register_locations_[source.code()] = use_index;
+        __ xchg(source, target);
        }
      }
-    // Update control flags for next iteration.
-    should_break_cycles = (any_moves_blocked && !any_moves_made);
-    if (any_moves_blocked) {
-      start = first_move_blocked;
-      end = last_move_blocked;
-    }
-  } while (any_moves_blocked);
+  }
  }


@@ -376,19 +345,22 @@
    // final step and is done from the bottom up so that the backing
    // elements of copies are in their correct locations when we
    // encounter the copies.
-  for (int i = 0; i < elements_.length(); i++) {
-    FrameElement source = elements_[i];
-    FrameElement target = expected->elements_[i];
-    if (target.is_register() && !source.is_register()) {
+  for (int i = 0; i < kNumRegisters; i++) {
+    int index = expected->register_locations_[i];
+    if (index != kIllegalIndex) {
+      FrameElement source = elements_[index];
+      FrameElement target = expected->elements_[index];
        switch (source.type()) {
          case FrameElement::INVALID:  // Fall through.
-        case FrameElement::REGISTER:
            UNREACHABLE();
            break;
-
+        case FrameElement::REGISTER:
+          ASSERT(source.reg().is(target.reg()));
+          continue;  // Go to next iteration.  Skips Use(target.reg())  
below.
+          break;
          case FrameElement::MEMORY:
-          ASSERT(i <= stack_pointer_);
-          __ mov(target.reg(), Operand(ebp, fp_relative(i)));
+          ASSERT(index <= stack_pointer_);
+          __ mov(target.reg(), Operand(ebp, fp_relative(index)));
            break;

          case FrameElement::CONSTANT:
@@ -400,11 +372,25 @@
            break;

          case FrameElement::COPY: {
-          FrameElement backing = elements_[source.index()];
+          int backing_index = source.index();
+          FrameElement backing = elements_[backing_index];
            ASSERT(backing.is_memory() || backing.is_register());
            if (backing.is_memory()) {
-            ASSERT(source.index() <= stack_pointer_);
-            __ mov(target.reg(), Operand(ebp,  
fp_relative(source.index())));
+            ASSERT(backing_index <= stack_pointer_);
+            // Code optimization if backing store should also move
+            // to a register: move backing store to its register first.
+            if (expected->elements_[backing_index].is_register()) {
+              FrameElement new_backing =  
expected->elements_[backing_index];
+              Register new_backing_reg = new_backing.reg();
+              ASSERT(!is_used(new_backing_reg));
+              elements_[backing_index] = new_backing;
+              Use(new_backing_reg, backing_index);
+              __ mov(new_backing_reg,
+                     Operand(ebp, fp_relative(backing_index)));
+              __ mov(target.reg(), new_backing_reg);
+            } else {
+              __ mov(target.reg(), Operand(ebp,  
fp_relative(backing_index)));
+            }
            } else {
              __ mov(target.reg(), backing.reg());
            }
@@ -412,11 +398,11 @@
        }
        // Ensure the proper sync state.  If the source was memory no
        // code needs to be emitted.
-      if (target.is_synced() && !source.is_memory()) {
-        SyncElementAt(i);
+      if (target.is_synced() && !source.is_synced()) {
+        __ mov(Operand(ebp, fp_relative(index)), target.reg());
        }
-      Use(target.reg(), i);
-      elements_[i] = target;
+      Use(target.reg(), index);
+      elements_[index] = target;
      }
    }
  }

Modified: branches/bleeding_edge/src/virtual-frame.h
==============================================================================
--- branches/bleeding_edge/src/virtual-frame.h  (original)
+++ branches/bleeding_edge/src/virtual-frame.h  Tue Apr 28 06:53:15 2009
@@ -191,6 +191,11 @@
      data_.index_ = new_index;
    }

+  void set_reg(Register new_reg) {
+    ASSERT(is_register());
+    data_.reg_ = new_reg;
+  }
+
    friend class VirtualFrame;
  };


--~--~---------~--~----~------------~-------~--~----~
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
-~----------~----~----~----~------~----~------~--~---

Reply via email to