Reviewers: ulan,

Description:
Crankshaft: Recognize (i >>> 0) === i for integer32 inputs and replace
with i >= 0, with no bailout.

Please review this at https://codereview.chromium.org/14211009/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge/

Affected files:
  M     src/hydrogen-instructions.h
  M     src/hydrogen.h
  M     src/hydrogen.cc
  M     src/ia32/lithium-codegen-ia32.cc
  M     src/token.h
  M     src/x64/lithium-codegen-x64.cc


Index: src/hydrogen-instructions.h
===================================================================
--- src/hydrogen-instructions.h (revision 14364)
+++ src/hydrogen-instructions.h (working copy)
@@ -4613,7 +4613,7 @@
     if (right()->IsInteger32Constant()) {
if (decomposition->Apply(left(), 0, right()->GetInteger32Constant())) {
         // This is intended to look for HAdd and HSub, to handle compounds
-        // like ((base + offset) >> scale) with one single decomposition.
+        // like ((base + offset) >>> scale) with one single decomposition.
         left()->TryDecompose(decomposition);
         return true;
       }
Index: src/hydrogen.cc
===================================================================
--- src/hydrogen.cc     (revision 14364)
+++ src/hydrogen.cc     (working copy)
@@ -10041,6 +10041,21 @@
 }


+void HOptimizedGraphBuilder::HandleTripleShiftZeroCompare(
+    CompareOperation* expr,
+    HValue* input) {
+  // (i >>> 0) === i is transformed to i >= 0.
+  // (i >>> 0) !== i is transformed to i < 0.
+ Token::Value op = (expr->op() == Token::EQ_STRICT) ? Token::GTE : Token::LT;
+  HCompareIDAndBranch* compare =
+      new(zone()) HCompareIDAndBranch(input, graph()->GetConstant0(), op);
+  compare->set_observed_input_representation(Representation::Integer32(),
+                                             Representation::Integer32());
+  compare->set_position(expr->position());
+  return ast_context()->ReturnControl(compare, expr->id());
+}
+
+
void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, HTypeof* typeof_expr, Handle<String> check) {
@@ -10067,6 +10082,34 @@
 }


+// Recognize the pattern (i >>> 0) !== i.
+static bool MatchTripleShiftZeroCompare(HValue* left,
+                                        Token::Value op,
+                                        HValue* right,
+                                        HValue** input) {
+  if (!right->representation().IsInteger32()) return false;
+  if (!left->IsShr()) return false;
+  HShr* shr =  HShr::cast(left);
+  if (right != shr->left()) return false;
+  if (!shr->right()->IsConstant()) return false;
+  HConstant* shiftOperand = HConstant::cast(shr->right());
+  if (*(shiftOperand->handle()) != Smi::FromInt(0)) return false;
+  *input = right;
+  return true;
+}
+
+
+static bool IsTripleShiftZeroCompare(HValue* left,
+                                     Token::Value op,
+                                     HValue* right,
+                                     HValue** input) {
+  if (!Token::IsStrictOp(op)) return false;
+  return MatchTripleShiftZeroCompare(left, op, right, input) ||
+      MatchTripleShiftZeroCompare(right, op, left, input);
+}
+
+
+
 static bool MatchLiteralCompareTypeof(HValue* left,
                                       Token::Value op,
                                       HValue* right,
@@ -10156,6 +10199,9 @@
     return HandleLiteralCompareTypeof(expr, typeof_expr, check);
   }
   HValue* sub_expr = NULL;
+  if (IsTripleShiftZeroCompare(left, op, right, &sub_expr)) {
+    return HandleTripleShiftZeroCompare(expr, sub_expr);
+  }
   Factory* f = isolate()->factory();
if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) {
     return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
Index: src/hydrogen.h
===================================================================
--- src/hydrogen.h      (revision 14364)
+++ src/hydrogen.h      (working copy)
@@ -1559,6 +1559,7 @@
   void HandleLiteralCompareNil(CompareOperation* expr,
                                HValue* value,
                                NilValue nil);
+  void HandleTripleShiftZeroCompare(CompareOperation* expr, HValue* input);

   HInstruction* BuildStringCharCodeAt(HValue* context,
                                       HValue* string,
Index: src/ia32/lithium-codegen-ia32.cc
===================================================================
--- src/ia32/lithium-codegen-ia32.cc    (revision 14364)
+++ src/ia32/lithium-codegen-ia32.cc    (working copy)
@@ -1692,11 +1692,11 @@
     uint8_t shift_count = static_cast<uint8_t>(value & 0x1F);
     switch (instr->op()) {
       case Token::ROR:
-        if (shift_count == 0 && instr->can_deopt()) {
+        if (shift_count != 0) {
+          __ ror(ToRegister(left), shift_count);
+        } else if (instr->can_deopt()) {
           __ test(ToRegister(left), Immediate(0x80000000));
           DeoptimizeIf(not_zero, instr->environment());
-        } else {
-          __ ror(ToRegister(left), shift_count);
         }
         break;
       case Token::SAR:
@@ -1705,11 +1705,11 @@
         }
         break;
       case Token::SHR:
-        if (shift_count == 0 && instr->can_deopt()) {
+        if (shift_count != 0) {
+          __ shr(ToRegister(left), shift_count);
+        } else if (instr->can_deopt()) {
           __ test(ToRegister(left), Immediate(0x80000000));
           DeoptimizeIf(not_zero, instr->environment());
-        } else {
-          __ shr(ToRegister(left), shift_count);
         }
         break;
       case Token::SHL:
Index: src/token.h
===================================================================
--- src/token.h (revision 14364)
+++ src/token.h (working copy)
@@ -225,6 +225,10 @@
     return op == EQ || op == EQ_STRICT;
   }

+  static bool IsStrictOp(Value op) {
+    return op == EQ_STRICT || op == NE_STRICT;
+  }
+
   static Value NegateCompareOp(Value op) {
     ASSERT(IsCompareOp(op));
     switch (op) {
Index: src/x64/lithium-codegen-x64.cc
===================================================================
--- src/x64/lithium-codegen-x64.cc      (revision 14364)
+++ src/x64/lithium-codegen-x64.cc      (working copy)
@@ -1498,11 +1498,15 @@
         }
         break;
       case Token::SHR:
-        if (shift_count == 0 && instr->can_deopt()) {
+        if (shift_count != 0) {
+          __ shrl(ToRegister(left), Immediate(shift_count));
+        } else if (instr->can_deopt()) {
           __ testl(ToRegister(left), ToRegister(left));
           DeoptimizeIf(negative, instr->environment());
         } else {
-          __ shrl(ToRegister(left), Immediate(shift_count));
+ // Even if the shift is zero, we have to zero out the high bits with
+          // a movl for negative inputs.
+          __ movl(ToRegister(left), ToRegister(left));
         }
         break;
       case Token::SHL:


--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.


Reply via email to