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