Index: test/compiler-unittests/change-lowering-unittest.cc |
diff --git a/test/compiler-unittests/change-lowering-unittest.cc b/test/compiler-unittests/change-lowering-unittest.cc |
index 329acfff1ef57dd83852ea854aef9afe590c0626..46c07fd1290641f03ee664a8d846e1122a31909c 100644 |
--- a/test/compiler-unittests/change-lowering-unittest.cc |
+++ b/test/compiler-unittests/change-lowering-unittest.cc |
@@ -19,20 +19,52 @@ namespace v8 { |
namespace internal { |
namespace compiler { |
-template <typename T> |
+// TODO(bmeurer): Find a new home for these functions. |
+inline std::ostream& operator<<(std::ostream& os, const MachineType& type) { |
+ OStringStream ost; |
+ ost << type; |
+ return os << ost.c_str(); |
+} |
+ |
+ |
class ChangeLoweringTest : public GraphTest { |
public: |
- static const size_t kPointerSize = sizeof(T); |
- static const MachineType kWordRepresentation = |
- (kPointerSize == 4) ? kRepWord32 : kRepWord64; |
- STATIC_ASSERT(HeapNumber::kValueOffset % kApiPointerSize == 0); |
- static const int kHeapNumberValueOffset = static_cast<int>( |
- (HeapNumber::kValueOffset / kApiPointerSize) * kPointerSize); |
- |
ChangeLoweringTest() : simplified_(zone()) {} |
virtual ~ChangeLoweringTest() {} |
+ virtual MachineType WordRepresentation() const = 0; |
+ |
protected: |
+ int HeapNumberValueOffset() const { |
+ STATIC_ASSERT(HeapNumber::kValueOffset % kApiPointerSize == 0); |
+ return (HeapNumber::kValueOffset / kApiPointerSize) * PointerSize() - |
+ kHeapObjectTag; |
+ } |
+ bool Is32() const { return WordRepresentation() == kRepWord32; } |
+ int PointerSize() const { |
+ switch (WordRepresentation()) { |
+ case kRepWord32: |
+ return 4; |
+ case kRepWord64: |
+ return 8; |
+ default: |
+ break; |
+ } |
+ UNREACHABLE(); |
+ return 0; |
+ } |
+ int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); } |
+ int SmiShiftSize() 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>::kSmiShiftSize' |
+ // src/compiler/change-lowering.cc:46: undefined reference to |
+ // `v8::internal::SmiTagging<8u>::kSmiShiftSize' |
+ STATIC_ASSERT(SmiTagging<4>::kSmiShiftSize == 0); |
+ STATIC_ASSERT(SmiTagging<8>::kSmiShiftSize == 31); |
+ return Is32() ? 0 : 31; |
+ } |
+ |
Node* Parameter(int32_t index = 0) { |
return graph()->NewNode(common()->Parameter(index), graph()->start()); |
} |
@@ -42,20 +74,35 @@ class ChangeLoweringTest : public GraphTest { |
JSGraph jsgraph(graph(), common(), &typer); |
CompilationInfo info(isolate(), zone()); |
Linkage linkage(&info); |
- MachineOperatorBuilder machine(zone(), kWordRepresentation); |
+ MachineOperatorBuilder machine(zone(), WordRepresentation()); |
ChangeLowering reducer(&jsgraph, &linkage, &machine); |
return reducer.Reduce(node); |
} |
SimplifiedOperatorBuilder* simplified() { return &simplified_; } |
- PrintableUnique<HeapObject> true_unique() { |
- return PrintableUnique<HeapObject>::CreateImmovable( |
- zone(), factory()->true_value()); |
+ Matcher<Node*> IsAllocateHeapNumber(const Matcher<Node*>& effect_matcher, |
+ const Matcher<Node*>& control_matcher) { |
+ return IsCall( |
+ _, IsHeapConstant(PrintableUnique<HeapObject>::CreateImmovable( |
+ zone(), CEntryStub(isolate(), 1).GetCode())), |
+ IsExternalConstant(ExternalReference( |
+ Runtime::FunctionForId(Runtime::kAllocateHeapNumber), isolate())), |
+ IsInt32Constant(0), IsNumberConstant(0.0), effect_matcher, |
+ control_matcher); |
} |
- PrintableUnique<HeapObject> false_unique() { |
- return PrintableUnique<HeapObject>::CreateImmovable( |
- zone(), factory()->false_value()); |
+ Matcher<Node*> IsFalse() { |
+ return IsHeapConstant(PrintableUnique<HeapObject>::CreateImmovable( |
+ zone(), factory()->false_value())); |
+ } |
+ Matcher<Node*> IsTrue() { |
+ return IsHeapConstant(PrintableUnique<HeapObject>::CreateImmovable( |
+ zone(), factory()->true_value())); |
+ } |
+ Matcher<Node*> IsWordEqual(const Matcher<Node*>& lhs_matcher, |
+ const Matcher<Node*>& rhs_matcher) { |
+ return Is32() ? IsWord32Equal(lhs_matcher, rhs_matcher) |
+ : IsWord64Equal(lhs_matcher, rhs_matcher); |
} |
private: |
@@ -63,53 +110,94 @@ class ChangeLoweringTest : public GraphTest { |
}; |
-typedef ::testing::Types<int32_t, int64_t> ChangeLoweringTypes; |
-TYPED_TEST_CASE(ChangeLoweringTest, ChangeLoweringTypes); |
+// ----------------------------------------------------------------------------- |
+// Common. |
+namespace { |
-TARGET_TYPED_TEST(ChangeLoweringTest, ChangeBitToBool) { |
- Node* val = this->Parameter(0); |
- Node* node = |
- this->graph()->NewNode(this->simplified()->ChangeBitToBool(), val); |
- Reduction reduction = this->Reduce(node); |
+class Common : public ChangeLoweringTest, |
+ public ::testing::WithParamInterface<MachineType> { |
+ public: |
+ virtual ~Common() {} |
+ |
+ virtual MachineType WordRepresentation() const V8_FINAL V8_OVERRIDE { |
+ return GetParam(); |
+ } |
+}; |
+ |
+ |
+TARGET_TEST_P(Common, ChangeBitToBool) { |
+ Node* val = Parameter(0); |
+ Node* node = graph()->NewNode(simplified()->ChangeBitToBool(), val); |
+ Reduction reduction = Reduce(node); |
ASSERT_TRUE(reduction.Changed()); |
Node* phi = reduction.replacement(); |
Capture<Node*> branch; |
- EXPECT_THAT( |
- phi, IsPhi(IsHeapConstant(this->true_unique()), |
- IsHeapConstant(this->false_unique()), |
- IsMerge(IsIfTrue(AllOf(CaptureEq(&branch), |
- IsBranch(val, this->graph()->start()))), |
- IsIfFalse(CaptureEq(&branch))))); |
+ EXPECT_THAT(phi, |
+ IsPhi(IsTrue(), IsFalse(), |
+ IsMerge(IsIfTrue(AllOf(CaptureEq(&branch), |
+ IsBranch(val, graph()->start()))), |
+ IsIfFalse(CaptureEq(&branch))))); |
} |
-TARGET_TYPED_TEST(ChangeLoweringTest, StringAdd) { |
- Node* node = this->graph()->NewNode(this->simplified()->StringAdd(), |
- this->Parameter(0), this->Parameter(1)); |
- Reduction reduction = this->Reduce(node); |
- EXPECT_FALSE(reduction.Changed()); |
-} |
- |
+TARGET_TEST_P(Common, ChangeBoolToBit) { |
+ Node* val = Parameter(0); |
+ Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val); |
+ Reduction reduction = Reduce(node); |
+ ASSERT_TRUE(reduction.Changed()); |
-class ChangeLowering32Test : public ChangeLoweringTest<int32_t> { |
- public: |
- virtual ~ChangeLowering32Test() {} |
-}; |
+ EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrue())); |
+} |
-TARGET_TEST_F(ChangeLowering32Test, ChangeBoolToBit) { |
+TARGET_TEST_P(Common, ChangeFloat64ToTagged) { |
Node* val = Parameter(0); |
- Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val); |
+ Node* node = graph()->NewNode(simplified()->ChangeFloat64ToTagged(), val); |
Reduction reduction = Reduce(node); |
ASSERT_TRUE(reduction.Changed()); |
- EXPECT_THAT(reduction.replacement(), |
- IsWord32Equal(val, IsHeapConstant(true_unique()))); |
+ Node* finish = reduction.replacement(); |
+ Capture<Node*> heap_number; |
+ EXPECT_THAT( |
+ finish, |
+ IsFinish( |
+ AllOf(CaptureEq(&heap_number), |
+ IsAllocateHeapNumber(IsValueEffect(val), graph()->start())), |
+ IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number), |
+ IsInt32Constant(HeapNumberValueOffset()), val, |
+ CaptureEq(&heap_number), graph()->start()))); |
} |
+TARGET_TEST_P(Common, StringAdd) { |
+ Node* node = |
+ graph()->NewNode(simplified()->StringAdd(), Parameter(0), Parameter(1)); |
+ Reduction reduction = Reduce(node); |
+ EXPECT_FALSE(reduction.Changed()); |
+} |
+ |
+} // namespace |
+ |
+ |
+INSTANTIATE_TEST_CASE_P(ChangeLoweringTest, Common, |
+ ::testing::Values(kRepWord32, kRepWord64)); |
+ |
+ |
+// ----------------------------------------------------------------------------- |
+// 32-bit |
+ |
+ |
+class ChangeLowering32Test : public ChangeLoweringTest { |
+ public: |
+ virtual ~ChangeLowering32Test() {} |
+ virtual MachineType WordRepresentation() const V8_FINAL V8_OVERRIDE { |
+ return kRepWord32; |
+ } |
+}; |
+ |
+ |
TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) { |
Node* val = Parameter(0); |
Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val); |
@@ -118,32 +206,21 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) { |
Node* phi = reduction.replacement(); |
Capture<Node*> add, branch, heap_number, if_true; |
- const int32_t kValueOffset = kHeapNumberValueOffset - kHeapObjectTag; |
EXPECT_THAT( |
phi, |
- IsPhi( |
- IsFinish( |
- AllOf( |
- CaptureEq(&heap_number), |
- IsCall( |
- _, IsHeapConstant( |
- PrintableUnique<HeapObject>::CreateImmovable( |
- zone(), CEntryStub(isolate(), 1).GetCode())), |
- IsExternalConstant(ExternalReference( |
- Runtime::FunctionForId(Runtime::kAllocateHeapNumber), |
- isolate())), |
- IsInt32Constant(0), IsNumberConstant(0.0), |
- graph()->start(), CaptureEq(&if_true))), |
- IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number), |
- IsInt32Constant(kValueOffset), |
- IsChangeInt32ToFloat64(val), CaptureEq(&heap_number), |
- CaptureEq(&if_true))), |
- IsProjection( |
- 0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(val, val))), |
- IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), |
- IsIfFalse(AllOf(CaptureEq(&branch), |
- IsBranch(IsProjection(1, CaptureEq(&add)), |
- graph()->start())))))); |
+ IsPhi(IsFinish( |
+ AllOf(CaptureEq(&heap_number), |
+ IsAllocateHeapNumber(_, CaptureEq(&if_true))), |
+ IsStore(kMachFloat64, kNoWriteBarrier, CaptureEq(&heap_number), |
+ IsInt32Constant(HeapNumberValueOffset()), |
+ IsChangeInt32ToFloat64(val), CaptureEq(&heap_number), |
+ CaptureEq(&if_true))), |
+ IsProjection( |
+ 0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(val, val))), |
+ IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), |
+ IsIfFalse(AllOf(CaptureEq(&branch), |
+ IsBranch(IsProjection(1, CaptureEq(&add)), |
+ graph()->start())))))); |
} |
@@ -156,18 +233,15 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) { |
Reduction reduction = Reduce(node); |
ASSERT_TRUE(reduction.Changed()); |
- const int32_t kShiftAmount = |
- kSmiTagSize + SmiTagging<kPointerSize>::kSmiShiftSize; |
- const int32_t kValueOffset = kHeapNumberValueOffset - kHeapObjectTag; |
Node* phi = reduction.replacement(); |
Capture<Node*> branch, if_true; |
EXPECT_THAT( |
phi, |
IsPhi( |
- IsLoad(kMachFloat64, val, IsInt32Constant(kValueOffset), |
+ IsLoad(kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()), |
IsControlEffect(CaptureEq(&if_true))), |
IsChangeInt32ToFloat64( |
- IsWord32Sar(val, IsInt32Constant(kShiftAmount))), |
+ IsWord32Sar(val, IsInt32Constant(SmiShiftAmount()))), |
IsMerge( |
AllOf(CaptureEq(&if_true), |
IsIfTrue(AllOf( |
@@ -178,33 +252,52 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) { |
} |
-class ChangeLowering64Test : public ChangeLoweringTest<int64_t> { |
- public: |
- virtual ~ChangeLowering64Test() {} |
-}; |
- |
+TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToInt32) { |
+ STATIC_ASSERT(kSmiTag == 0); |
+ STATIC_ASSERT(kSmiTagSize == 1); |
-TARGET_TEST_F(ChangeLowering64Test, ChangeBoolToBit) { |
Node* val = Parameter(0); |
- Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val); |
+ Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val); |
Reduction reduction = Reduce(node); |
ASSERT_TRUE(reduction.Changed()); |
- EXPECT_THAT(reduction.replacement(), |
- IsWord64Equal(val, IsHeapConstant(true_unique()))); |
+ Node* phi = reduction.replacement(); |
+ Capture<Node*> branch, if_true; |
+ EXPECT_THAT( |
+ phi, |
+ IsPhi(IsChangeFloat64ToInt32(IsLoad( |
+ kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()), |
+ IsControlEffect(CaptureEq(&if_true)))), |
+ IsWord32Sar(val, IsInt32Constant(SmiShiftAmount())), |
+ IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), |
+ IsIfFalse(AllOf( |
+ CaptureEq(&branch), |
+ IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)), |
+ graph()->start())))))); |
} |
+// ----------------------------------------------------------------------------- |
+// 64-bit |
+ |
+ |
+class ChangeLowering64Test : public ChangeLoweringTest { |
+ public: |
+ virtual ~ChangeLowering64Test() {} |
+ virtual MachineType WordRepresentation() const V8_FINAL V8_OVERRIDE { |
+ return kRepWord64; |
+ } |
+}; |
+ |
+ |
TARGET_TEST_F(ChangeLowering64Test, ChangeInt32ToTagged) { |
Node* val = Parameter(0); |
Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val); |
Reduction reduction = Reduce(node); |
ASSERT_TRUE(reduction.Changed()); |
- const int32_t kShiftAmount = |
- kSmiTagSize + SmiTagging<kPointerSize>::kSmiShiftSize; |
EXPECT_THAT(reduction.replacement(), |
- IsWord64Shl(val, IsInt32Constant(kShiftAmount))); |
+ IsWord64Shl(val, IsInt32Constant(SmiShiftAmount()))); |
} |
@@ -217,18 +310,15 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) { |
Reduction reduction = Reduce(node); |
ASSERT_TRUE(reduction.Changed()); |
- const int32_t kShiftAmount = |
- kSmiTagSize + SmiTagging<kPointerSize>::kSmiShiftSize; |
- const int32_t kValueOffset = kHeapNumberValueOffset - kHeapObjectTag; |
Node* phi = reduction.replacement(); |
Capture<Node*> branch, if_true; |
EXPECT_THAT( |
phi, |
IsPhi( |
- IsLoad(kMachFloat64, val, IsInt32Constant(kValueOffset), |
+ IsLoad(kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()), |
IsControlEffect(CaptureEq(&if_true))), |
IsChangeInt32ToFloat64(IsConvertInt64ToInt32( |
- IsWord64Sar(val, IsInt32Constant(kShiftAmount)))), |
+ IsWord64Sar(val, IsInt32Constant(SmiShiftAmount())))), |
IsMerge( |
AllOf(CaptureEq(&if_true), |
IsIfTrue(AllOf( |
@@ -238,6 +328,32 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) { |
IsIfFalse(CaptureEq(&branch))))); |
} |
+ |
+TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToInt32) { |
+ STATIC_ASSERT(kSmiTag == 0); |
+ STATIC_ASSERT(kSmiTagSize == 1); |
+ |
+ Node* val = Parameter(0); |
+ Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), val); |
+ Reduction reduction = Reduce(node); |
+ ASSERT_TRUE(reduction.Changed()); |
+ |
+ Node* phi = reduction.replacement(); |
+ Capture<Node*> branch, if_true; |
+ EXPECT_THAT( |
+ phi, |
+ IsPhi(IsChangeFloat64ToInt32(IsLoad( |
+ kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()), |
+ IsControlEffect(CaptureEq(&if_true)))), |
+ IsConvertInt64ToInt32( |
+ IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))), |
+ IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), |
+ IsIfFalse(AllOf( |
+ CaptureEq(&branch), |
+ IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)), |
+ graph()->start())))))); |
+} |
+ |
} // namespace compiler |
} // namespace internal |
} // namespace v8 |