Author: whessev8
Date: Mon Dec 15 05:21:45 2008
New Revision: 979

Modified:
    branches/experimental/toiger/src/codegen-ia32.cc
    branches/experimental/toiger/src/virtual-frame-ia32.cc
    branches/experimental/toiger/src/virtual-frame-ia32.h

Log:
Allow non-spilled frames into VisitCompareOperation, and allow them
to be passed from there to SmiComparison and SmiComparisonDeferred.
Profit from constants and registers in SmiComparison.
Review URL: http://codereview.chromium.org/13665

Modified: branches/experimental/toiger/src/codegen-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/codegen-ia32.cc    (original)
+++ branches/experimental/toiger/src/codegen-ia32.cc    Mon Dec 15 05:21:45  
2008
@@ -403,6 +403,7 @@

    if (has_cc()) {
      ASSERT(frame_ != NULL);
+    frame_->SpillAll();
      // Convert cc_reg_ into a boolean value.
      JumpTarget loaded(this);
      JumpTarget materialize_true(this);
@@ -426,6 +427,7 @@
      // Load "true" if necessary.
      if (true_target.is_linked()) {
        true_target.Bind();
+      frame_->SpillAll();
        frame_->EmitPush(Immediate(Factory::true_value()));
      }
      // If both "true" and "false" need to be reincarnated jump across the
@@ -436,6 +438,7 @@
      // Load "false" if necessary.
      if (false_target.is_linked()) {
        false_target.Bind();
+      frame_->SpillAll();
        frame_->EmitPush(Immediate(Factory::false_value()));
      }
      // A value is loaded on all paths reaching this point.
@@ -1185,8 +1188,13 @@
    SmiComparisonDeferred(CodeGenerator* generator,
                          Condition cc,
                          bool strict,
-                        int value)
-      : DeferredCode(generator), cc_(cc), strict_(strict), value_(value) {
+                        Register left_side,
+                        int right_side) :
+      DeferredCode(generator),
+      cc_(cc),
+      strict_(strict),
+      left_side_(left_side),
+      right_side_(right_side) {
      set_comment("[ ComparisonDeferred");
    }
    virtual void Generate();
@@ -1194,18 +1202,21 @@
   private:
    Condition cc_;
    bool strict_;
-  int value_;
+  Register left_side_;
+  int right_side_;
  };


  void SmiComparisonDeferred::Generate() {
    CompareStub stub(cc_, strict_);
    // Setup parameters and call stub.
-  __ mov(edx, Operand(eax));
-  __ Set(eax, Immediate(Smi::FromInt(value_)));
+  if (!left_side_.is(edx)) {
+    __ mov(edx, Operand(left_side_));
+  }
+  __ Set(eax, Immediate(Smi::FromInt(right_side_)));
    __ CallStub(&stub);
    __ cmp(eax, 0);
-  // "result" is returned in the flags
+  // "result" is returned in the flags.
  }


@@ -1218,13 +1229,16 @@
    int int_value = Smi::cast(*value)->value();
    ASSERT(is_intn(int_value, kMaxSmiInlinedBits));

+  Result comparee = frame_->Pop();
+  comparee.ToRegister();
+  Register reg = comparee.reg();
+  __ test(reg, Immediate(kSmiTagMask));
    SmiComparisonDeferred* deferred =
-      new SmiComparisonDeferred(this, cc, strict, int_value);
-  frame_->EmitPop(eax);
-  __ test(eax, Immediate(kSmiTagMask));
+      new SmiComparisonDeferred(this, cc, strict, reg, int_value);
    deferred->enter()->Branch(not_zero, not_taken);
-  // Test smi equality by pointer comparison.
-  __ cmp(Operand(eax), Immediate(value));
+  // Test smi equality and comparison by signed int comparison.
+  __ cmp(Operand(reg), Immediate(value));
+  comparee.Unuse();
    deferred->exit()->Bind();
    cc_reg_ = cc;
  }
@@ -3986,6 +4000,7 @@
          right->AsLiteral() != NULL && right->AsLiteral()->IsNull();
      // The 'null' value can only be equal to 'null' or 'undefined'.
      if (left_is_null || right_is_null) {
+      frame_->SpillAll();
        Load(left_is_null ? right : left);
        frame_->SpillAll();
        frame_->EmitPop(eax);
@@ -4024,6 +4039,7 @@
         right->AsLiteral()->handle()->IsString())) {
      Handle<String> check(String::cast(*right->AsLiteral()->handle()));

+    frame_->SpillAll();
      // Load the operand and move it to register edx.
      LoadTypeofExpression(operation->expression());
      frame_->SpillAll();
@@ -4133,6 +4149,7 @@
        cc = greater_equal;
        break;
      case Token::IN: {
+      frame_->SpillAll();
        Load(left);
        frame_->SpillAll();
        Load(right);
@@ -4142,6 +4159,7 @@
        return;
      }
      case Token::INSTANCEOF: {
+      frame_->SpillAll();
        Load(left);
        frame_->SpillAll();
        Load(right);
@@ -4159,6 +4177,7 @@
    // Optimize for the case where (at least) one of the expressions
    // is a literal small integer.
    if (IsInlineSmi(left->AsLiteral())) {
+    frame_->SpillAll();
      Load(right);
      frame_->SpillAll();
      SmiComparison(ReverseCondition(cc), left->AsLiteral()->handle(),  
strict);
@@ -4166,11 +4185,11 @@
    }
    if (IsInlineSmi(right->AsLiteral())) {
      Load(left);
-    frame_->SpillAll();
      SmiComparison(cc, right->AsLiteral()->handle(), strict);
      return;
    }

+  frame_->SpillAll();
    Load(left);
    frame_->SpillAll();
    Load(right);

Modified: branches/experimental/toiger/src/virtual-frame-ia32.cc
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.cc      (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.cc      Mon Dec 15  
05:21:45 2008
@@ -50,9 +50,23 @@


  void Result::Unuse() {
-  ASSERT(!reg().is(no_reg));
-  cgen_->allocator()->Unuse(reg());
-  data_.reg_ = no_reg;
+  if (is_register()) {
+    cgen_->allocator()->Unuse(reg());
+  }
+  type_ = INVALID;
+}
+
+
+void Result::ToRegister() {
+  ASSERT(is_valid());
+  if (is_constant()) {
+    Register reg = cgen_->allocator()->Allocate();
+    ASSERT(!reg.is(no_reg));
+    cgen_->masm()->Set(reg, Immediate(handle()));
+    data_.reg_ = reg;
+    type_ = REGISTER;
+  }
+  ASSERT(is_register());
  }


@@ -514,34 +528,40 @@
      for (int i = start; i <= end; i++) {
        FrameElement source = elements_[i];
        FrameElement target = expected->elements_[i];
-      if (source.is_register() && target.is_register() &&
-          !target.reg().is(source.reg())) {
-        // We need to move source to target.
-        if (frame_registers_.is_used(target.reg().code())) {
-          // 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.
-          Use(target.reg());
-          Unuse(source.reg());
+      if (source.is_register() && target.is_register()) {
+        if (target.reg().is(source.reg())) {
            if (target.is_synced() && !source.is_synced()) {
              SyncElementAt(i);
            }
            elements_[i] = target;
-          __ mov(target.reg(), source.reg());
-          any_moves_made = true;
+        } else {
+          // We need to move source to target.
+          if (frame_registers_.is_used(target.reg().code())) {
+            // 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());
+            Unuse(source.reg());
+            elements_[i] = target;
+            __ mov(target.reg(), source.reg());
+            any_moves_made = true;
+          }
          }
        }
      }

Modified: branches/experimental/toiger/src/virtual-frame-ia32.h
==============================================================================
--- branches/experimental/toiger/src/virtual-frame-ia32.h       (original)
+++ branches/experimental/toiger/src/virtual-frame-ia32.h       Mon Dec 15  
05:21:45 2008
@@ -40,7 +40,7 @@
  class Result BASE_EMBEDDED {
   public:
    // Construct a register Result.
-  explicit Result(Register reg, CodeGenerator* cgen);
+  Result(Register reg, CodeGenerator* cgen);

    // Construct a Result whose value is a compile-time constant.
    Result(Handle<Object> value, CodeGenerator * cgen) :
@@ -50,14 +50,16 @@
    }

    ~Result() {
-    // We have called Unuse() before Result goes out of scope.
-    ASSERT(!is_register() || reg().is(no_reg));
+    if (is_register()) {
+      Unuse();
+    }
    }

    void Unuse();

    bool is_register() const { return type() == REGISTER; }
    bool is_constant() const { return type() == CONSTANT; }
+  bool is_valid() const { return type() != INVALID; }

    Register reg() const {
      ASSERT(type() == REGISTER);
@@ -69,8 +71,16 @@
      return Handle<Object>(data_.handle_);
    }

+  // Change a result to a register result.  If the result is not already
+  // in a register, allocate a register from the code generator, and emit
+  // code to move the value into that register.
+  void ToRegister();
   private:
-  enum Type { REGISTER, CONSTANT };
+  enum Type {
+    REGISTER,
+    CONSTANT,
+    INVALID
+  };

    Type type_;

@@ -83,9 +93,6 @@

    CodeGenerator* cgen_;
  };
-
-
-// A result in a register just means that the value can be read from the  
register


  //  
-------------------------------------------------------------------------

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

Reply via email to