Reviewers: titzer,

Description:
Introduce simplified BooleanToNumber operator.

[email protected]
TEST=cctest/test-simplified-lowering/LowerBooleanToNumber

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

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

Affected files (+66, -6 lines):
  M src/compiler/js-typed-lowering.cc
  M src/compiler/opcodes.h
  M src/compiler/simplified-lowering.cc
  M src/compiler/simplified-operator.h
  M src/compiler/simplified-operator.cc
  M src/compiler/typer.cc
  M test/cctest/compiler/test-js-typed-lowering.cc
  M test/cctest/compiler/test-simplified-lowering.cc


Index: src/compiler/js-typed-lowering.cc
diff --git a/src/compiler/js-typed-lowering.cc b/src/compiler/js-typed-lowering.cc index 35283e4137402386a71413ee8ca72965e1852531..74849af8a8734bffa39eca783b3c39f2ef2a5209 100644
--- a/src/compiler/js-typed-lowering.cc
+++ b/src/compiler/js-typed-lowering.cc
@@ -444,7 +444,11 @@ Reduction JSTypedLowering::ReduceJSToNumberInput(Node* input) {
     // JSToNumber(null) => #0
     return ReplaceWith(jsgraph()->ZeroConstant());
   }
-  // TODO(turbofan): js-typed-lowering of ToNumber(x:boolean)
+  if (input_type->Is(Type::Boolean())) {
+    // JSToNumber(x:boolean) => BooleanToNumber(x)
+    return ReplaceWith(
+        graph()->NewNode(simplified()->BooleanToNumber(), input));
+  }
   // TODO(turbofan): js-typed-lowering of ToNumber(x:string)
   return NoChange();
 }
Index: src/compiler/opcodes.h
diff --git a/src/compiler/opcodes.h b/src/compiler/opcodes.h
index 722e1be96369fcc03acebb96f17f869a82aac9ea..f295eac09ef3529a3802719f464810d93bdc19ba 100644
--- a/src/compiler/opcodes.h
+++ b/src/compiler/opcodes.h
@@ -131,6 +131,7 @@
 // Opcodes for VirtuaMachine-level operators.
 #define SIMPLIFIED_OP_LIST(V) \
   V(BooleanNot)               \
+  V(BooleanToNumber)          \
   V(NumberEqual)              \
   V(NumberLessThan)           \
   V(NumberLessThanOrEqual)    \
Index: src/compiler/simplified-lowering.cc
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc index d1f2ee3bd1ec142819a2d4de28f31724851c21de..7f43bf56ec1e0f701cdedec6c33ebbc479cf734b 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -432,6 +432,24 @@ class RepresentationSelector {
         }
         break;
       }
+      case IrOpcode::kBooleanToNumber: {
+        if (lower()) {
+          MachineTypeUnion input = GetInfo(node->InputAt(0))->output;
+          if (input & kRepBit) {
+            // BooleanToNumber(x: kRepBit) => x
+            DeferReplacement(node, node->InputAt(0));
+          } else {
+            // BooleanToNumber(x: kRepTagged) => WordEqual(x, #true)
+            node->set_op(lowering->machine()->WordEqual());
+            node->AppendInput(jsgraph_->zone(), jsgraph_->TrueConstant());
+          }
+        } else {
+          // No input representation requirement; adapt during lowering.
+          ProcessInput(node, 0, kTypeBool);
+          SetOutput(node, kRepWord32);
+        }
+        break;
+      }
       case IrOpcode::kNumberEqual:
       case IrOpcode::kNumberLessThan:
       case IrOpcode::kNumberLessThanOrEqual: {
Index: src/compiler/simplified-operator.cc
diff --git a/src/compiler/simplified-operator.cc b/src/compiler/simplified-operator.cc index f314d262a818c23632cbe9e24633ede791c8aa18..75b6e2215b38d5fe690c0d07b875e29b581157c8 100644
--- a/src/compiler/simplified-operator.cc
+++ b/src/compiler/simplified-operator.cc
@@ -65,6 +65,7 @@ struct StaticParameterTraits<ElementAccess> {

 #define PURE_OP_LIST(V)                                \
   V(BooleanNot, Operator::kNoProperties, 1)            \
+  V(BooleanToNumber, Operator::kNoProperties, 1)       \
   V(NumberEqual, Operator::kCommutative, 2)            \
   V(NumberLessThan, Operator::kNoProperties, 2)        \
   V(NumberLessThanOrEqual, Operator::kNoProperties, 2) \
Index: src/compiler/simplified-operator.h
diff --git a/src/compiler/simplified-operator.h b/src/compiler/simplified-operator.h index 596f7f412221b84788af2207b8ceec5a24d3238b..907507cf723b07c909991e7fba650fd231fe3e52 100644
--- a/src/compiler/simplified-operator.h
+++ b/src/compiler/simplified-operator.h
@@ -91,6 +91,7 @@ class SimplifiedOperatorBuilder FINAL {
   explicit SimplifiedOperatorBuilder(Zone* zone);

   const Operator* BooleanNot();
+  const Operator* BooleanToNumber();

   const Operator* NumberEqual();
   const Operator* NumberLessThan();
Index: src/compiler/typer.cc
diff --git a/src/compiler/typer.cc b/src/compiler/typer.cc
index 1c83fc2cb0e6d41ae6bd5a1daa55f7b663fbd336..c4af35e16dd1b04db09fcf76e59199266dd8eb2e 100644
--- a/src/compiler/typer.cc
+++ b/src/compiler/typer.cc
@@ -644,6 +644,11 @@ Bounds Typer::Visitor::TypeBooleanNot(Node* node) {
 }


+Bounds Typer::Visitor::TypeBooleanToNumber(Node* node) {
+  return Bounds(Type::Number(zone()));
+}
+
+
 Bounds Typer::Visitor::TypeNumberEqual(Node* node) {
   return Bounds(Type::Boolean(zone()));
 }
Index: test/cctest/compiler/test-js-typed-lowering.cc
diff --git a/test/cctest/compiler/test-js-typed-lowering.cc b/test/cctest/compiler/test-js-typed-lowering.cc index 861cf3932b67e395f3c9001133e2d84fe4bb1c43..26ca7664a50eb9711e7acd9ea60afc1c6a0f69fc 100644
--- a/test/cctest/compiler/test-js-typed-lowering.cc
+++ b/test/cctest/compiler/test-js-typed-lowering.cc
@@ -665,6 +665,9 @@ TEST(StringComparison) {
 static void CheckIsConvertedToNumber(Node* val, Node* converted) {
   if (NodeProperties::GetBounds(val).upper->Is(Type::Number())) {
     CHECK_EQ(val, converted);
+  } else if (NodeProperties::GetBounds(val).upper->Is(Type::Boolean())) {
+    CHECK_EQ(IrOpcode::kBooleanToNumber, converted->opcode());
+    CHECK_EQ(val, converted->InputAt(0));
   } else {
     if (converted->opcode() == IrOpcode::kNumberConstant) return;
     CHECK_EQ(IrOpcode::kJSToNumber, converted->opcode());
@@ -1049,7 +1052,7 @@ TEST(OrderNumberBinopEffects2) {
   };

   for (size_t j = 0; j < arraysize(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Number(), Type::Boolean());
+    BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol());

     Node* i0 = B.CheckNoOp(0);
     Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
@@ -1062,7 +1065,7 @@ TEST(OrderNumberBinopEffects2) {
   }

   for (size_t j = 0; j < arraysize(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Boolean(), Type::Number());
+    BinopEffectsTester B(ops[j], Type::Symbol(), Type::Number());

     Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
     Node* i1 = B.CheckNoOp(1);
@@ -1085,7 +1088,7 @@ TEST(OrderCompareEffects) {
   };

   for (size_t j = 0; j < arraysize(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Boolean(), Type::String());
+    BinopEffectsTester B(ops[j], Type::Symbol(), Type::String());
     CHECK_EQ(ops[j + 1]->opcode(), B.result->op()->opcode());

     Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
@@ -1100,7 +1103,7 @@ TEST(OrderCompareEffects) {
   }

   for (size_t j = 0; j < arraysize(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Number(), Type::Boolean());
+    BinopEffectsTester B(ops[j], Type::Number(), Type::Symbol());

     Node* i0 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 0, true);
     Node* i1 = B.result->InputAt(1);
@@ -1113,7 +1116,7 @@ TEST(OrderCompareEffects) {
   }

   for (size_t j = 0; j < arraysize(ops); j += 2) {
-    BinopEffectsTester B(ops[j], Type::Boolean(), Type::Number());
+    BinopEffectsTester B(ops[j], Type::Symbol(), Type::Number());

     Node* i0 = B.result->InputAt(0);
     Node* i1 = B.CheckConvertedInput(IrOpcode::kJSToNumber, 1, true);
Index: test/cctest/compiler/test-simplified-lowering.cc
diff --git a/test/cctest/compiler/test-simplified-lowering.cc b/test/cctest/compiler/test-simplified-lowering.cc index da75cc4cc7a4bd039ae1b36d21e2211523dd0931..0306752b05029a622019b3015e22a3dc818de788 100644
--- a/test/cctest/compiler/test-simplified-lowering.cc
+++ b/test/cctest/compiler/test-simplified-lowering.cc
@@ -810,6 +810,33 @@ TEST(LowerBooleanNot_tagged_tagged) {
 }


+TEST(LowerBooleanToNumber_bit_int32) {
+  // BooleanToNumber(x: kRepBit) used as kMachInt32
+  TestingGraph t(Type::Boolean());
+  Node* b = t.ExampleWithOutput(kRepBit);
+  Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
+  Node* use = t.Use(cnv, kMachInt32);
+  t.Return(use);
+  t.Lower();
+  CHECK_EQ(b, use->InputAt(0));
+}
+
+
+TEST(LowerBooleanToNumber_tagged_int32) {
+  // BooleanToNumber(x: kRepTagged) used as kMachInt32
+  TestingGraph t(Type::Boolean());
+  Node* b = t.p0;
+  Node* cnv = t.graph()->NewNode(t.simplified()->BooleanToNumber(), b);
+  Node* use = t.Use(cnv, kMachInt32);
+  t.Return(use);
+  t.Lower();
+  CHECK_EQ(t.machine()->WordEqual()->opcode(), cnv->opcode());
+  CHECK(b == cnv->InputAt(0) || b == cnv->InputAt(1));
+  Node* c = t.jsgraph.TrueConstant();
+  CHECK(c == cnv->InputAt(0) || c == cnv->InputAt(1));
+}
+
+
 static Type* test_types[] = {Type::Signed32(), Type::Unsigned32(),
                              Type::Number(), Type::Any()};



--
--
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/d/optout.

Reply via email to