Revision: 3487
Author: [email protected]
Date: Thu Dec 17 22:38:12 2009
Log: -Inlined double variant of compare iff one of the sides is a constant  
smi and it is not a for loop condition.

Review URL: http://codereview.chromium.org/507040
http://code.google.com/p/v8/source/detail?r=3487

Modified:
  /branches/bleeding_edge/src/ast.h
  /branches/bleeding_edge/src/compiler.cc
  /branches/bleeding_edge/src/ia32/assembler-ia32.cc
  /branches/bleeding_edge/src/ia32/assembler-ia32.h
  /branches/bleeding_edge/src/ia32/codegen-ia32.cc
  /branches/bleeding_edge/src/ia32/codegen-ia32.h
  /branches/bleeding_edge/src/ia32/disasm-ia32.cc
  /branches/bleeding_edge/src/parser.cc

=======================================
--- /branches/bleeding_edge/src/ast.h   Wed Dec 16 22:21:50 2009
+++ /branches/bleeding_edge/src/ast.h   Thu Dec 17 22:38:12 2009
@@ -139,6 +139,7 @@
    virtual MaterializedLiteral* AsMaterializedLiteral() { return NULL; }
    virtual ObjectLiteral* AsObjectLiteral() { return NULL; }
    virtual ArrayLiteral* AsArrayLiteral() { return NULL; }
+  virtual CompareOperation* AsCompareOperation() { return NULL; }
  };


@@ -1185,7 +1186,7 @@
  class CompareOperation: public Expression {
   public:
    CompareOperation(Token::Value op, Expression* left, Expression* right)
-      : op_(op), left_(left), right_(right) {
+      : op_(op), left_(left), right_(right), is_for_loop_condition_(false)  
{
      ASSERT(Token::IsCompareOp(op));
    }

@@ -1194,11 +1195,19 @@
    Token::Value op() const { return op_; }
    Expression* left() const { return left_; }
    Expression* right() const { return right_; }
+
+  // Accessors for flag whether this compare operation is hanging of a for  
loop.
+  bool is_for_loop_condition() const { return is_for_loop_condition_; }
+  void set_is_for_loop_condition() { is_for_loop_condition_ = true; }
+
+  // Type testing & conversion
+  virtual CompareOperation* AsCompareOperation() { return this; }

   private:
    Token::Value op_;
    Expression* left_;
    Expression* right_;
+  bool is_for_loop_condition_;
  };


=======================================
--- /branches/bleeding_edge/src/compiler.cc     Wed Dec 16 01:51:07 2009
+++ /branches/bleeding_edge/src/compiler.cc     Thu Dec 17 22:38:12 2009
@@ -1101,9 +1101,9 @@


  void CodeGenSelector::VisitCompareOperation(CompareOperation* expr) {
-      ProcessExpression(expr->left(), Expression::kValue);
-      CHECK_BAILOUT;
-      ProcessExpression(expr->right(), Expression::kValue);
+  ProcessExpression(expr->left(), Expression::kValue);
+  CHECK_BAILOUT;
+  ProcessExpression(expr->right(), Expression::kValue);
  }


=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.cc  Tue Nov 17 00:35:43  
2009
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.cc  Thu Dec 17 22:38:12  
2009
@@ -2002,6 +2002,17 @@
    EMIT(0x5E);
    emit_sse_operand(dst, src);
  }
+
+
+void Assembler::xorpd(XMMRegister dst, XMMRegister src) {
+  ASSERT(CpuFeatures::IsEnabled(SSE2));
+  EnsureSpace ensure_space(this);
+  last_pc_ = pc_;
+  EMIT(0x66);
+  EMIT(0x0F);
+  EMIT(0x57);
+  emit_sse_operand(dst, src);
+}


  void Assembler::comisd(XMMRegister dst, XMMRegister src) {
=======================================
--- /branches/bleeding_edge/src/ia32/assembler-ia32.h   Thu Dec 10 04:52:28  
2009
+++ /branches/bleeding_edge/src/ia32/assembler-ia32.h   Thu Dec 17 22:38:12  
2009
@@ -745,6 +745,7 @@
    void subsd(XMMRegister dst, XMMRegister src);
    void mulsd(XMMRegister dst, XMMRegister src);
    void divsd(XMMRegister dst, XMMRegister src);
+  void xorpd(XMMRegister dst, XMMRegister src);

    void comisd(XMMRegister dst, XMMRegister src);

=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Thu Dec 17 17:43:50  
2009
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc    Thu Dec 17 22:38:12  
2009
@@ -1865,7 +1865,8 @@
  }


-void CodeGenerator::Comparison(Condition cc,
+void CodeGenerator::Comparison(AstNode* node,
+                               Condition cc,
                                 bool strict,
                                 ControlDestination* dest) {
    // Strict only makes sense for equality comparisons.
@@ -1912,7 +1913,8 @@
          default:
            UNREACHABLE();
        }
-    } else {  // Only one side is a constant Smi.
+    } else {
+      // Only one side is a constant Smi.
        // If left side is a constant Smi, reverse the operands.
        // Since one side is a constant Smi, conversion order does not  
matter.
        if (left_side_constant_smi) {
@@ -1926,6 +1928,8 @@
        // Implement comparison against a constant Smi, inlining the case
        // where both sides are Smis.
        left_side.ToRegister();
+      Register left_reg = left_side.reg();
+      Handle<Object> right_val = right_side.handle();

        // Here we split control flow to the stub call and inlined cases
        // before finally splitting it to the control destination.  We use
@@ -1933,10 +1937,49 @@
        // the first split.  We manually handle the off-frame references
        // by reconstituting them on the non-fall-through path.
        JumpTarget is_smi;
-      Register left_reg = left_side.reg();
-      Handle<Object> right_val = right_side.handle();
        __ test(left_side.reg(), Immediate(kSmiTagMask));
        is_smi.Branch(zero, taken);
+
+      bool is_for_loop_compare = (node->AsCompareOperation() != NULL)
+          && node->AsCompareOperation()->is_for_loop_condition();
+      if (!is_for_loop_compare
+          && CpuFeatures::IsSupported(SSE2)
+          && right_val->IsSmi()) {
+        // Right side is a constant smi and left side has been checked
+        // not to be a smi.
+        CpuFeatures::Scope use_sse2(SSE2);
+        JumpTarget not_number;
+        __ cmp(FieldOperand(left_reg, HeapObject::kMapOffset),
+               Immediate(Factory::heap_number_map()));
+        not_number.Branch(not_equal, &left_side);
+        __ movdbl(xmm1,
+                  FieldOperand(left_reg, HeapNumber::kValueOffset));
+        int value = Smi::cast(*right_val)->value();
+        if (value == 0) {
+          __ xorpd(xmm0, xmm0);
+        } else {
+          Result temp = allocator()->Allocate();
+          __ mov(temp.reg(), Immediate(value));
+          __ cvtsi2sd(xmm0, Operand(temp.reg()));
+          temp.Unuse();
+        }
+        __ comisd(xmm1, xmm0);
+        // Jump to builtin for NaN.
+        not_number.Branch(parity_even, &left_side);
+        left_side.Unuse();
+        Condition double_cc = cc;
+        switch (cc) {
+          case less:          double_cc = below;       break;
+          case equal:         double_cc = equal;       break;
+          case less_equal:    double_cc = below_equal; break;
+          case greater:       double_cc = above;       break;
+          case greater_equal: double_cc = above_equal; break;
+          default: UNREACHABLE();
+        }
+        dest->true_target()->Branch(double_cc);
+        dest->false_target()->Jump();
+        not_number.Bind(&left_side);
+      }

        // Setup and call the compare stub.
        CompareStub stub(cc, strict);
@@ -1961,6 +2004,7 @@
        right_side.Unuse();
        dest->Split(cc);
      }
+
    } else if (cc == equal &&
               (left_side_constant_null || right_side_constant_null)) {
      // To make null checks efficient, we check if either the left side or
@@ -1997,7 +2041,8 @@
        operand.Unuse();
        dest->Split(not_zero);
      }
-  } else {  // Neither side is a constant Smi or null.
+  } else {
+    // Neither side is a constant Smi or null.
      // If either side is a non-smi constant, skip the smi check.
      bool known_non_smi =
          (left_side.is_constant() && !left_side.handle()->IsSmi()) ||
@@ -2664,7 +2709,7 @@
      // Compare and branch to the body if true or the next test if
      // false.  Prefer the next test as a fall through.
      ControlDestination dest(clause->body_target(), &next_test, false);
-    Comparison(equal, true, &dest);
+    Comparison(node, equal, true, &dest);

      // If the comparison fell through to the true target, jump to the
      // actual body.
@@ -6077,7 +6122,7 @@
    }
    Load(left);
    Load(right);
-  Comparison(cc, strict, destination());
+  Comparison(node, cc, strict, destination());
  }


=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.h     Wed Dec 16 22:21:50 2009
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.h     Thu Dec 17 22:38:12 2009
@@ -459,7 +459,8 @@
                                  Result* right,
                                  OverwriteMode overwrite_mode);

-  void Comparison(Condition cc,
+  void Comparison(AstNode* node,
+                  Condition cc,
                    bool strict,
                    ControlDestination* destination);

@@ -727,8 +728,8 @@

    bool ArgsInRegistersSupported() {
      return ((op_ == Token::ADD) || (op_ == Token::SUB)
-             || (op_ == Token::MUL) || (op_ == Token::DIV))
-            && flags_ != NO_SMI_CODE_IN_STUB;
+            || (op_ == Token::MUL) || (op_ == Token::DIV))
+        && flags_ != NO_SMI_CODE_IN_STUB;
    }
    bool IsOperationCommutative() {
      return (op_ == Token::ADD) || (op_ == Token::MUL);
=======================================
--- /branches/bleeding_edge/src/ia32/disasm-ia32.cc     Tue Nov 17 02:24:27 2009
+++ /branches/bleeding_edge/src/ia32/disasm-ia32.cc     Thu Dec 17 22:38:12 2009
@@ -1049,6 +1049,14 @@
                             NameOfXMMRegister(regop),
                             NameOfXMMRegister(rm));
              data++;
+          } if (*data == 0x57) {
+            data++;
+            int mod, regop, rm;
+            get_modrm(*data, &mod, &regop, &rm);
+            AppendToBuffer("xorpd %s,%s",
+                           NameOfXMMRegister(regop),
+                           NameOfXMMRegister(rm));
+            data++;
            } else {
              UnimplementedInstruction();
            }
=======================================
--- /branches/bleeding_edge/src/parser.cc       Mon Nov 16 13:59:31 2009
+++ /branches/bleeding_edge/src/parser.cc       Thu Dec 17 22:38:12 2009
@@ -2657,6 +2657,9 @@
    Expression* cond = NULL;
    if (peek() != Token::SEMICOLON) {
      cond = ParseExpression(true, CHECK_OK);
+    if (cond && cond->AsCompareOperation()) {
+      cond->AsCompareOperation()->set_is_for_loop_condition();
+    }
    }
    Expect(Token::SEMICOLON, CHECK_OK);

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

Reply via email to