Revision: 23215
Author:   [email protected]
Date:     Wed Aug 20 04:01:36 2014 UTC
Log:      [turbofan] Add support for ChangeUint32ToTagged in ChangeLowering.

TEST=compiler-unittests
[email protected]

Review URL: https://codereview.chromium.org/491433002
http://code.google.com/p/v8/source/detail?r=23215

Modified:
 /branches/bleeding_edge/src/compiler/change-lowering.cc
 /branches/bleeding_edge/src/compiler/change-lowering.h
 /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc
 /branches/bleeding_edge/test/compiler-unittests/graph-unittest.cc
 /branches/bleeding_edge/test/compiler-unittests/graph-unittest.h

=======================================
--- /branches/bleeding_edge/src/compiler/change-lowering.cc Wed Aug 20 04:01:00 2014 UTC +++ /branches/bleeding_edge/src/compiler/change-lowering.cc Wed Aug 20 04:01:36 2014 UTC
@@ -28,6 +28,8 @@
       return ChangeTaggedToFloat64(node->InputAt(0), control);
     case IrOpcode::kChangeTaggedToInt32:
       return ChangeTaggedToInt32(node->InputAt(0), control);
+    case IrOpcode::kChangeUint32ToTagged:
+      return ChangeUint32ToTagged(node->InputAt(0), control);
     default:
       return NoChange();
   }
@@ -42,6 +44,20 @@
((HeapNumber::kValueOffset / kPointerSize) * (machine()->is64() ? 8 : 4)); return jsgraph()->Int32Constant(heap_number_value_offset - kHeapObjectTag);
 }
+
+
+Node* ChangeLowering::SmiMaxValueConstant() {
+  // TODO(turbofan): Work-around for weird GCC 4.6 linker issue:
+  // src/compiler/change-lowering.cc:46: undefined reference to
+  // `v8::internal::SmiTagging<4u>::kSmiValueSize'
+  // src/compiler/change-lowering.cc:46: undefined reference to
+  // `v8::internal::SmiTagging<8u>::kSmiValueSize'
+  STATIC_ASSERT(SmiTagging<4>::kSmiValueSize == 31);
+  STATIC_ASSERT(SmiTagging<8>::kSmiValueSize == 32);
+  const int smi_value_size = machine()->is64() ? 32 : 31;
+  return jsgraph()->Int32Constant(
+      -(static_cast<int>(0xffffffffu << (smi_value_size - 1)) + 1));
+}


 Node* ChangeLowering::SmiShiftBitsConstant() {
@@ -168,6 +184,33 @@

   return Replace(phi);
 }
+
+
+Reduction ChangeLowering::ChangeUint32ToTagged(Node* val, Node* control) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagMask == 1);
+
+  Node* cmp = graph()->NewNode(machine()->Uint32LessThanOrEqual(), val,
+                               SmiMaxValueConstant());
+  Node* branch = graph()->NewNode(common()->Branch(), cmp, control);
+
+  Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
+  Node* smi = graph()->NewNode(
+      machine()->WordShl(),
+      machine()->is64()
+          ? graph()->NewNode(machine()->ChangeUint32ToUint64(), val)
+          : val,
+      SmiShiftBitsConstant());
+
+  Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+  Node* heap_number = AllocateHeapNumberWithValue(
+      graph()->NewNode(machine()->ChangeUint32ToFloat64(), val), if_false);
+
+  Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+  Node* phi = graph()->NewNode(common()->Phi(2), smi, heap_number, merge);
+
+  return Replace(phi);
+}


 Isolate* ChangeLowering::isolate() const { return jsgraph()->isolate(); }
=======================================
--- /branches/bleeding_edge/src/compiler/change-lowering.h Tue Aug 19 04:54:06 2014 UTC +++ /branches/bleeding_edge/src/compiler/change-lowering.h Wed Aug 20 04:01:36 2014 UTC
@@ -28,6 +28,7 @@

  protected:
   Node* HeapNumberValueIndexConstant();
+  Node* SmiMaxValueConstant();
   Node* SmiShiftBitsConstant();

   Reduction ChangeBitToBool(Node* val, Node* control);
@@ -36,6 +37,7 @@
   Reduction ChangeInt32ToTagged(Node* val, Node* control);
   Reduction ChangeTaggedToFloat64(Node* val, Node* control);
   Reduction ChangeTaggedToInt32(Node* val, Node* control);
+  Reduction ChangeUint32ToTagged(Node* val, Node* control);

   Graph* graph() const;
   Isolate* isolate() const;
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc Wed Aug 20 04:01:00 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc Wed Aug 20 04:01:36 2014 UTC
@@ -53,6 +53,10 @@
     UNREACHABLE();
     return 0;
   }
+  int SmiMaxValue() const { return -(SmiMinValue() + 1); }
+  int SmiMinValue() const {
+    return static_cast<int>(0xffffffffu << (SmiValueSize() - 1));
+  }
   int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); }
   int SmiShiftSize() const {
     // TODO(turbofan): Work-around for weird GCC 4.6 linker issue:
@@ -64,6 +68,16 @@
     STATIC_ASSERT(SmiTagging<8>::kSmiShiftSize == 31);
     return Is32() ? 0 : 31;
   }
+  int SmiValueSize() const {
+    // TODO(turbofan): Work-around for weird GCC 4.6 linker issue:
+    // src/compiler/change-lowering.cc:46: undefined reference to
+    // `v8::internal::SmiTagging<4u>::kSmiValueSize'
+    // src/compiler/change-lowering.cc:46: undefined reference to
+    // `v8::internal::SmiTagging<8u>::kSmiValueSize'
+    STATIC_ASSERT(SmiTagging<4>::kSmiValueSize == 31);
+    STATIC_ASSERT(SmiTagging<8>::kSmiValueSize == 32);
+    return Is32() ? 31 : 32;
+  }

   Node* Parameter(int32_t index = 0) {
     return graph()->NewNode(common()->Parameter(index), graph()->start());
@@ -273,6 +287,37 @@
IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)),
                                  graph()->start()))))));
 }
+
+
+TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, heap_number, if_false;
+  EXPECT_THAT(
+      phi,
+      IsPhi(
+          IsWord32Shl(val, IsInt32Constant(SmiShiftAmount())),
+          IsFinish(
+              AllOf(CaptureEq(&heap_number),
+                    IsAllocateHeapNumber(_, CaptureEq(&if_false))),
+ IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
+                      IsInt32Constant(HeapNumberValueOffset()),
+ IsChangeUint32ToFloat64(val), CaptureEq(&heap_number),
+                      CaptureEq(&if_false))),
+          IsMerge(
+              IsIfTrue(AllOf(CaptureEq(&branch),
+                             IsBranch(IsUint32LessThanOrEqual(
+ val, IsInt32Constant(SmiMaxValue())),
+                                      graph()->start()))),
+ AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
+}


// -----------------------------------------------------------------------------
@@ -352,6 +397,38 @@
IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)),
                                  graph()->start()))))));
 }
+
+
+TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) {
+  STATIC_ASSERT(kSmiTag == 0);
+  STATIC_ASSERT(kSmiTagSize == 1);
+
+  Node* val = Parameter(0);
+  Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), val);
+  Reduction reduction = Reduce(node);
+  ASSERT_TRUE(reduction.Changed());
+
+  Node* phi = reduction.replacement();
+  Capture<Node*> branch, heap_number, if_false;
+  EXPECT_THAT(
+      phi,
+      IsPhi(
+          IsWord64Shl(IsChangeUint32ToUint64(val),
+                      IsInt32Constant(SmiShiftAmount())),
+          IsFinish(
+              AllOf(CaptureEq(&heap_number),
+                    IsAllocateHeapNumber(_, CaptureEq(&if_false))),
+ IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number),
+                      IsInt32Constant(HeapNumberValueOffset()),
+ IsChangeUint32ToFloat64(val), CaptureEq(&heap_number),
+                      CaptureEq(&if_false))),
+          IsMerge(
+              IsIfTrue(AllOf(CaptureEq(&branch),
+                             IsBranch(IsUint32LessThanOrEqual(
+ val, IsInt32Constant(SmiMaxValue())),
+                                      graph()->start()))),
+ AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch))))));
+}

 }  // namespace compiler
 }  // namespace internal
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/graph-unittest.cc Wed Aug 20 04:01:00 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/graph-unittest.cc Wed Aug 20 04:01:36 2014 UTC
@@ -662,6 +662,7 @@
   }
 IS_BINOP_MATCHER(Word32And)
 IS_BINOP_MATCHER(Word32Sar)
+IS_BINOP_MATCHER(Word32Shl)
 IS_BINOP_MATCHER(Word32Ror)
 IS_BINOP_MATCHER(Word32Equal)
 IS_BINOP_MATCHER(Word64And)
@@ -669,6 +670,7 @@
 IS_BINOP_MATCHER(Word64Shl)
 IS_BINOP_MATCHER(Word64Equal)
 IS_BINOP_MATCHER(Int32AddWithOverflow)
+IS_BINOP_MATCHER(Uint32LessThanOrEqual)
 #undef IS_BINOP_MATCHER


@@ -679,6 +681,7 @@
 IS_UNOP_MATCHER(ChangeFloat64ToInt32)
 IS_UNOP_MATCHER(ChangeInt32ToFloat64)
 IS_UNOP_MATCHER(ChangeInt32ToInt64)
+IS_UNOP_MATCHER(ChangeUint32ToFloat64)
 IS_UNOP_MATCHER(ChangeUint32ToUint64)
 IS_UNOP_MATCHER(TruncateFloat64ToInt32)
 IS_UNOP_MATCHER(TruncateInt64ToInt32)
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/graph-unittest.h Wed Aug 20 04:01:00 2014 UTC +++ /branches/bleeding_edge/test/compiler-unittests/graph-unittest.h Wed Aug 20 04:01:36 2014 UTC
@@ -80,6 +80,8 @@
                            const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsWord32Sar(const Matcher<Node*>& lhs_matcher,
                            const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsWord32Shl(const Matcher<Node*>& lhs_matcher,
+                           const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsWord32Ror(const Matcher<Node*>& lhs_matcher,
                            const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsWord32Equal(const Matcher<Node*>& lhs_matcher,
@@ -94,9 +96,12 @@
                              const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsInt32AddWithOverflow(const Matcher<Node*>& lhs_matcher,
                                       const Matcher<Node*>& rhs_matcher);
+Matcher<Node*> IsUint32LessThanOrEqual(const Matcher<Node*>& lhs_matcher,
+                                       const Matcher<Node*>& rhs_matcher);
 Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher);
 Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher);
 Matcher<Node*> IsChangeInt32ToInt64(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeUint32ToFloat64(const Matcher<Node*>& input_matcher);
 Matcher<Node*> IsChangeUint32ToUint64(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsTruncateFloat64ToInt32(const Matcher<Node*>& input_matcher);
 Matcher<Node*> IsTruncateInt64ToInt32(const Matcher<Node*>& input_matcher);

--
--
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