From 45434d575eef59fd5936f7eba0ba6b2fff4d642d Mon Sep 17 00:00:00 2001 From: bmeurer Date: Wed, 18 Mar 2015 00:27:31 -0700 Subject: [PATCH] [turbofan] Improve ChangeLowering. - Use representation information provided by the type system to skip SMI checks. - Fix combining of ChangeTaggedToFloat64 with JSToNumber now that JS operators can produce control. - Remove the unnecessary abstraction of smi/field offsets. - Improve unit test coverage. - Various cosmetic fixes. R=svenpanne@chromium.org Review URL: https://codereview.chromium.org/1018873002 Cr-Commit-Position: refs/heads/master@{#27250} --- src/compiler/change-lowering.cc | 203 +++++--- src/compiler/change-lowering.h | 2 +- .../compiler/change-lowering-unittest.cc | 456 +++++++++--------- 3 files changed, 359 insertions(+), 302 deletions(-) diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc index fffd8bf896..4806e2bfe1 100644 --- a/src/compiler/change-lowering.cc +++ b/src/compiler/change-lowering.cc @@ -5,7 +5,6 @@ #include "src/compiler/change-lowering.h" #include "src/code-factory.h" -#include "src/compiler/diamond.h" #include "src/compiler/js-graph.h" #include "src/compiler/linkage.h" #include "src/compiler/machine-operator.h" @@ -47,25 +46,17 @@ Reduction ChangeLowering::Reduce(Node* node) { Node* ChangeLowering::HeapNumberValueIndexConstant() { - STATIC_ASSERT(HeapNumber::kValueOffset % kPointerSize == 0); - const int heap_number_value_offset = - ((HeapNumber::kValueOffset / kPointerSize) * (machine()->Is64() ? 8 : 4)); - return jsgraph()->IntPtrConstant(heap_number_value_offset - kHeapObjectTag); + return jsgraph()->IntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag); } Node* ChangeLowering::SmiMaxValueConstant() { - const int smi_value_size = machine()->Is32() ? SmiTagging<4>::SmiValueSize() - : SmiTagging<8>::SmiValueSize(); - return jsgraph()->Int32Constant( - -(static_cast(0xffffffffu << (smi_value_size - 1)) + 1)); + return jsgraph()->Int32Constant(Smi::kMaxValue); } Node* ChangeLowering::SmiShiftBitsConstant() { - const int smi_shift_size = machine()->Is32() ? SmiTagging<4>::SmiShiftSize() - : SmiTagging<8>::SmiShiftSize(); - return jsgraph()->IntPtrConstant(smi_shift_size + kSmiTagSize); + return jsgraph()->IntPtrConstant(kSmiShiftSize + kSmiTagSize); } @@ -93,6 +84,14 @@ Node* ChangeLowering::ChangeInt32ToFloat64(Node* value) { } +Node* ChangeLowering::ChangeInt32ToSmi(Node* value) { + if (machine()->Is64()) { + value = graph()->NewNode(machine()->ChangeInt32ToInt64(), value); + } + return graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()); +} + + Node* ChangeLowering::ChangeSmiToFloat64(Node* value) { return ChangeInt32ToFloat64(ChangeSmiToInt32(value)); } @@ -135,64 +134,80 @@ Node* ChangeLowering::TestNotSmi(Node* value) { } -Node* ChangeLowering::Uint32LessThanOrEqual(Node* lhs, Node* rhs) { - return graph()->NewNode(machine()->Uint32LessThanOrEqual(), lhs, rhs); -} - - -Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) { - MachineType const type = static_cast(kTypeBool | kRepTagged); - return Replace(graph()->NewNode(common()->Select(type), val, +Reduction ChangeLowering::ChangeBitToBool(Node* value, Node* control) { + return Replace(graph()->NewNode(common()->Select(kMachAnyTagged), value, jsgraph()->TrueConstant(), jsgraph()->FalseConstant())); } -Reduction ChangeLowering::ChangeBoolToBit(Node* val) { - return Replace( - graph()->NewNode(machine()->WordEqual(), val, jsgraph()->TrueConstant())); +Reduction ChangeLowering::ChangeBoolToBit(Node* value) { + return Replace(graph()->NewNode(machine()->WordEqual(), value, + jsgraph()->TrueConstant())); } -Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) { - return Replace(AllocateHeapNumberWithValue(val, control)); +Reduction ChangeLowering::ChangeFloat64ToTagged(Node* value, Node* control) { + return Replace(AllocateHeapNumberWithValue(value, control)); } Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { - if (machine()->Is64()) { - return Replace(graph()->NewNode( - machine()->Word64Shl(), - graph()->NewNode(machine()->ChangeInt32ToInt64(), value), - SmiShiftBitsConstant())); - } else if (NodeProperties::GetBounds(value).upper->Is(Type::SignedSmall())) { - return Replace( - graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant())); + if (machine()->Is64() || + NodeProperties::GetBounds(value).upper->Is(Type::SignedSmall())) { + return Replace(ChangeInt32ToSmi(value)); } Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), value, value); - Node* ovf = graph()->NewNode(common()->Projection(1), add); - Diamond d(graph(), common(), ovf, BranchHint::kFalse); - d.Chain(control); - return Replace( - d.Phi(kMachAnyTagged, - AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), d.if_true), - graph()->NewNode(common()->Projection(0), add))); + Node* ovf = graph()->NewNode(common()->Projection(1), add); + Node* branch = + graph()->NewNode(common()->Branch(BranchHint::kFalse), ovf, control); + + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = + AllocateHeapNumberWithValue(ChangeInt32ToFloat64(value), if_true); + + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = graph()->NewNode(common()->Projection(0), add); + + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); + Node* phi = + graph()->NewNode(common()->Phi(kMachAnyTagged, 2), vtrue, vfalse, merge); + + return Replace(phi); } Reduction ChangeLowering::ChangeTaggedToUI32(Node* value, Node* control, Signedness signedness) { + if (NodeProperties::GetBounds(value).upper->Is(Type::TaggedSigned())) { + return Replace(ChangeSmiToInt32(value)); + } + const MachineType type = (signedness == kSigned) ? kMachInt32 : kMachUint32; const Operator* op = (signedness == kSigned) ? machine()->ChangeFloat64ToInt32() : machine()->ChangeFloat64ToUint32(); - Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse); - d.Chain(control); - return Replace( - d.Phi(type, graph()->NewNode(op, LoadHeapNumberValue(value, d.if_true)), - ChangeSmiToInt32(value))); + + if (NodeProperties::GetBounds(value).upper->Is(Type::TaggedPointer())) { + return Replace(graph()->NewNode(op, LoadHeapNumberValue(value, control))); + } + + Node* check = TestNotSmi(value); + Node* branch = + graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); + + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = graph()->NewNode(op, LoadHeapNumberValue(value, if_true)); + + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = ChangeSmiToInt32(value); + + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); + Node* phi = graph()->NewNode(common()->Phi(type, 2), vtrue, vfalse, merge); + + return Replace(phi); } @@ -226,50 +241,88 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* value, Node* control) { Node* const effect = NodeProperties::GetEffectInput(value); Node* const control = NodeProperties::GetControlInput(value); - Diamond d1(graph(), common(), TestNotSmi(object), BranchHint::kFalse); - d1.Chain(control); + const Operator* merge_op = common()->Merge(2); + const Operator* ephi_op = common()->EffectPhi(2); + const Operator* phi_op = common()->Phi(kMachFloat64, 2); - DCHECK_EQ(FLAG_turbo_deoptimization, - OperatorProperties::GetFrameStateInputCount(value->op()) == 1); - Node* number = + Node* check1 = TestNotSmi(object); + Node* branch1 = + graph()->NewNode(common()->Branch(BranchHint::kFalse), check1, control); + + Node* if_true1 = graph()->NewNode(common()->IfTrue(), branch1); + Node* vtrue1 = FLAG_turbo_deoptimization ? graph()->NewNode(value->op(), object, context, NodeProperties::GetFrameStateInput(value, 0), - effect, d1.if_true) - : graph()->NewNode(value->op(), object, context, effect, - d1.if_true); - Diamond d2(graph(), common(), TestNotSmi(number)); - d2.Nest(d1, true); - Node* phi2 = d2.Phi(kMachFloat64, LoadHeapNumberValue(number, d2.if_true), - ChangeSmiToFloat64(number)); + effect, if_true1) + : graph()->NewNode(value->op(), object, context, effect, if_true1); + Node* etrue1 = vtrue1; + { + Node* check2 = TestNotSmi(vtrue1); + Node* branch2 = graph()->NewNode(common()->Branch(), check2, if_true1); - Node* phi1 = d1.Phi(kMachFloat64, phi2, ChangeSmiToFloat64(object)); - Node* ephi1 = d1.EffectPhi(number, effect); + Node* if_true2 = graph()->NewNode(common()->IfTrue(), branch2); + Node* vtrue2 = LoadHeapNumberValue(vtrue1, if_true2); - for (Edge edge : value->use_edges()) { - if (NodeProperties::IsEffectEdge(edge)) { - edge.UpdateTo(ephi1); - } + Node* if_false2 = graph()->NewNode(common()->IfFalse(), branch2); + Node* vfalse2 = ChangeSmiToFloat64(vtrue1); + + if_true1 = graph()->NewNode(merge_op, if_true2, if_false2); + vtrue1 = graph()->NewNode(phi_op, vtrue2, vfalse2, if_true1); } + + Node* if_false1 = graph()->NewNode(common()->IfFalse(), branch1); + Node* vfalse1 = ChangeSmiToFloat64(object); + Node* efalse1 = effect; + + Node* merge1 = graph()->NewNode(merge_op, if_true1, if_false1); + Node* ephi1 = graph()->NewNode(ephi_op, etrue1, efalse1, merge1); + Node* phi1 = graph()->NewNode(phi_op, vtrue1, vfalse1, merge1); + + NodeProperties::ReplaceWithValue(value, phi1, ephi1, merge1); return Replace(phi1); } - Diamond d(graph(), common(), TestNotSmi(value), BranchHint::kFalse); - d.Chain(control); - Node* load = LoadHeapNumberValue(value, d.if_true); - Node* number = ChangeSmiToFloat64(value); - return Replace(d.Phi(kMachFloat64, load, number)); + Node* check = TestNotSmi(value); + Node* branch = + graph()->NewNode(common()->Branch(BranchHint::kFalse), check, control); + + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = LoadHeapNumberValue(value, if_true); + + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = ChangeSmiToFloat64(value); + + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); + Node* phi = + graph()->NewNode(common()->Phi(kMachFloat64, 2), vtrue, vfalse, merge); + + return Replace(phi); } Reduction ChangeLowering::ChangeUint32ToTagged(Node* value, Node* control) { - Diamond d(graph(), common(), - Uint32LessThanOrEqual(value, SmiMaxValueConstant()), - BranchHint::kTrue); - d.Chain(control); - return Replace(d.Phi( - kMachAnyTagged, ChangeUint32ToSmi(value), - AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), d.if_false))); + if (NodeProperties::GetBounds(value).upper->Is(Type::UnsignedSmall())) { + return Replace(ChangeUint32ToSmi(value)); + } + + Node* check = graph()->NewNode(machine()->Uint32LessThanOrEqual(), value, + SmiMaxValueConstant()); + Node* branch = + graph()->NewNode(common()->Branch(BranchHint::kTrue), check, control); + + Node* if_true = graph()->NewNode(common()->IfTrue(), branch); + Node* vtrue = ChangeUint32ToSmi(value); + + Node* if_false = graph()->NewNode(common()->IfFalse(), branch); + Node* vfalse = + AllocateHeapNumberWithValue(ChangeUint32ToFloat64(value), if_false); + + Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); + Node* phi = + graph()->NewNode(common()->Phi(kMachAnyTagged, 2), vtrue, vfalse, merge); + + return Replace(phi); } diff --git a/src/compiler/change-lowering.h b/src/compiler/change-lowering.h index 40a3e152b5..3f98639937 100644 --- a/src/compiler/change-lowering.h +++ b/src/compiler/change-lowering.h @@ -31,13 +31,13 @@ class ChangeLowering FINAL : public Reducer { Node* AllocateHeapNumberWithValue(Node* value, Node* control); Node* ChangeInt32ToFloat64(Node* value); + Node* ChangeInt32ToSmi(Node* value); Node* ChangeSmiToFloat64(Node* value); Node* ChangeSmiToInt32(Node* value); Node* ChangeUint32ToFloat64(Node* value); Node* ChangeUint32ToSmi(Node* value); Node* LoadHeapNumberValue(Node* value, Node* control); Node* TestNotSmi(Node* value); - Node* Uint32LessThanOrEqual(Node* lhs, Node* rhs); Reduction ChangeBitToBool(Node* value, Node* control); Reduction ChangeBoolToBit(Node* value); diff --git a/test/unittests/compiler/change-lowering-unittest.cc b/test/unittests/compiler/change-lowering-unittest.cc index 50119ece2d..5cfb8fdc41 100644 --- a/test/unittests/compiler/change-lowering-unittest.cc +++ b/test/unittests/compiler/change-lowering-unittest.cc @@ -23,45 +23,15 @@ namespace v8 { namespace internal { namespace compiler { -class ChangeLoweringTest : public GraphTest { +class ChangeLoweringTest : public TypedGraphTest { public: ChangeLoweringTest() : simplified_(zone()) {} - ~ChangeLoweringTest() OVERRIDE {} 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 SmiMaxValue() const { return -(SmiMinValue() + 1); } - int SmiMinValue() const { - return static_cast(0xffffffffu << (SmiValueSize() - 1)); - } - int SmiShiftAmount() const { return kSmiTagSize + SmiShiftSize(); } - int SmiShiftSize() const { - return Is32() ? SmiTagging<4>::SmiShiftSize() - : SmiTagging<8>::SmiShiftSize(); - } - int SmiValueSize() const { - return Is32() ? SmiTagging<4>::SmiValueSize() - : SmiTagging<8>::SmiValueSize(); - } + bool Is64() const { return WordRepresentation() == kRepWord64; } Reduction Reduce(Node* node) { MachineOperatorBuilder machine(zone(), WordRepresentation()); @@ -80,15 +50,33 @@ class ChangeLoweringTest : public GraphTest { IsNumberConstant(BitEq(0.0)), effect_matcher, control_matcher); } + Matcher IsChangeInt32ToSmi(const Matcher& value_matcher) { + return Is64() ? IsWord64Shl(IsChangeInt32ToInt64(value_matcher), + IsSmiShiftBitsConstant()) + : IsWord32Shl(value_matcher, IsSmiShiftBitsConstant()); + } + Matcher IsChangeSmiToInt32(const Matcher& value_matcher) { + return Is64() ? IsTruncateInt64ToInt32( + IsWord64Sar(value_matcher, IsSmiShiftBitsConstant())) + : IsWord32Sar(value_matcher, IsSmiShiftBitsConstant()); + } + Matcher IsChangeUint32ToSmi(const Matcher& value_matcher) { + return Is64() ? IsWord64Shl(IsChangeUint32ToUint64(value_matcher), + IsSmiShiftBitsConstant()) + : IsWord32Shl(value_matcher, IsSmiShiftBitsConstant()); + } Matcher IsLoadHeapNumber(const Matcher& value_matcher, const Matcher& control_matcher) { return IsLoad(kMachFloat64, value_matcher, - IsIntPtrConstant(HeapNumberValueOffset()), graph()->start(), - control_matcher); + IsIntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), + graph()->start(), control_matcher); } Matcher IsIntPtrConstant(int value) { return Is32() ? IsInt32Constant(value) : IsInt64Constant(value); } + Matcher IsSmiShiftBitsConstant() { + return IsIntPtrConstant(kSmiShiftSize + kSmiTagSize); + } Matcher IsWordEqual(const Matcher& lhs_matcher, const Matcher& rhs_matcher) { return Is32() ? IsWord32Equal(lhs_matcher, rhs_matcher) @@ -115,51 +103,95 @@ class ChangeLoweringCommonTest TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBitToBool) { - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeBitToBool(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - EXPECT_THAT(reduction.replacement(), - IsSelect(static_cast(kTypeBool | kRepTagged), val, - IsTrueConstant(), IsFalseConstant())); + Node* value = Parameter(Type::Boolean()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeBitToBool(), value)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsSelect(kMachAnyTagged, value, IsTrueConstant(), + IsFalseConstant())); } TARGET_TEST_P(ChangeLoweringCommonTest, ChangeBoolToBit) { - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeBoolToBit(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrueConstant())); + Node* value = Parameter(Type::Number()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeBoolToBit(), value)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsWordEqual(value, IsTrueConstant())); } TARGET_TEST_P(ChangeLoweringCommonTest, ChangeFloat64ToTagged) { - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeFloat64ToTagged(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - Node* finish = reduction.replacement(); + Node* value = Parameter(Type::Number()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeFloat64ToTagged(), value)); + ASSERT_TRUE(r.Changed()); Capture heap_number; EXPECT_THAT( - finish, + r.replacement(), IsFinish( AllOf(CaptureEq(&heap_number), - IsAllocateHeapNumber(IsValueEffect(val), graph()->start())), + IsAllocateHeapNumber(IsValueEffect(value), graph()->start())), IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier), CaptureEq(&heap_number), - IsIntPtrConstant(HeapNumberValueOffset()), val, - CaptureEq(&heap_number), graph()->start()))); + IsIntPtrConstant(HeapNumber::kValueOffset - kHeapObjectTag), + value, CaptureEq(&heap_number), graph()->start()))); } -TARGET_TEST_P(ChangeLoweringCommonTest, StringAdd) { - Node* node = - graph()->NewNode(simplified()->StringAdd(), Parameter(0), Parameter(1)); - Reduction reduction = Reduce(node); - EXPECT_FALSE(reduction.Changed()); +TARGET_TEST_P(ChangeLoweringCommonTest, ChangeInt32ToTaggedWithSignedSmall) { + Node* value = Parameter(Type::SignedSmall()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeInt32ToTagged(), value)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsChangeInt32ToSmi(value)); +} + + +TARGET_TEST_P(ChangeLoweringCommonTest, ChangeUint32ToTaggedWithUnsignedSmall) { + Node* value = Parameter(Type::UnsignedSmall()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeUint32ToTagged(), value)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsChangeUint32ToSmi(value)); +} + + +TARGET_TEST_P(ChangeLoweringCommonTest, ChangeTaggedToInt32WithTaggedSigned) { + Node* value = Parameter(Type::TaggedSigned()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeTaggedToInt32(), value)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsChangeSmiToInt32(value)); +} + + +TARGET_TEST_P(ChangeLoweringCommonTest, ChangeTaggedToInt32WithTaggedPointer) { + Node* value = Parameter(Type::TaggedPointer()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeTaggedToInt32(), value)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsChangeFloat64ToInt32( + IsLoadHeapNumber(value, graph()->start()))); +} + + +TARGET_TEST_P(ChangeLoweringCommonTest, ChangeTaggedToUint32WithTaggedSigned) { + Node* value = Parameter(Type::TaggedSigned()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeTaggedToUint32(), value)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsChangeSmiToInt32(value)); +} + + +TARGET_TEST_P(ChangeLoweringCommonTest, ChangeTaggedToUint32WithTaggedPointer) { + Node* value = Parameter(Type::TaggedPointer()); + Reduction r = + Reduce(graph()->NewNode(simplified()->ChangeTaggedToUint32(), value)); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsChangeFloat64ToUint32( + IsLoadHeapNumber(value, graph()->start()))); } @@ -179,26 +211,24 @@ class ChangeLowering32Test : public ChangeLoweringTest { TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) { - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val); - NodeProperties::SetBounds(val, Bounds(Type::None(), Type::Integral32())); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - Node* phi = reduction.replacement(); + Node* value = Parameter(Type::Integral32()); + Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture add, branch, heap_number, if_true; EXPECT_THAT( - phi, + r.replacement(), IsPhi(kMachAnyTagged, IsFinish(AllOf(CaptureEq(&heap_number), IsAllocateHeapNumber(_, CaptureEq(&if_true))), IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier), CaptureEq(&heap_number), - IsIntPtrConstant(HeapNumberValueOffset()), - IsChangeInt32ToFloat64(val), + IsIntPtrConstant(HeapNumber::kValueOffset - + kHeapObjectTag), + IsChangeInt32ToFloat64(value), CaptureEq(&heap_number), CaptureEq(&if_true))), - IsProjection( - 0, AllOf(CaptureEq(&add), IsInt32AddWithOverflow(val, val))), + IsProjection(0, AllOf(CaptureEq(&add), + IsInt32AddWithOverflow(value, value))), IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), IsIfFalse(AllOf(CaptureEq(&branch), IsBranch(IsProjection(1, CaptureEq(&add)), @@ -206,43 +236,27 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) { } -TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTaggedSmall) { - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val); - NodeProperties::SetBounds(val, Bounds(Type::None(), Type::SignedSmall())); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - Node* change = reduction.replacement(); - Capture add, branch, heap_number, if_true; - EXPECT_THAT(change, IsWord32Shl(val, IsInt32Constant(SmiShiftAmount()))); -} - - TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToFloat64) { STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTagSize == 1); - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - Node* phi = reduction.replacement(); + Node* value = Parameter(Type::Number()); + Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture branch, if_true; EXPECT_THAT( - phi, - IsPhi( - kMachFloat64, IsLoadHeapNumber(val, CaptureEq(&if_true)), - IsChangeInt32ToFloat64( - IsWord32Sar(val, IsInt32Constant(SmiShiftAmount()))), - IsMerge( - AllOf(CaptureEq(&if_true), - IsIfTrue(AllOf( - CaptureEq(&branch), - IsBranch(IsWord32And(val, IsInt32Constant(kSmiTagMask)), - graph()->start())))), - IsIfFalse(CaptureEq(&branch))))); + r.replacement(), + IsPhi(kMachFloat64, IsLoadHeapNumber(value, CaptureEq(&if_true)), + IsChangeInt32ToFloat64(IsWord32Sar( + value, IsInt32Constant(kSmiTagSize + kSmiShiftSize))), + IsMerge(AllOf(CaptureEq(&if_true), + IsIfTrue(AllOf( + CaptureEq(&branch), + IsBranch(IsWord32And( + value, IsInt32Constant(kSmiTagMask)), + graph()->start())))), + IsIfFalse(CaptureEq(&branch))))); } @@ -250,23 +264,22 @@ TARGET_TEST_F(ChangeLowering32Test, 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(); + Node* value = Parameter(Type::Signed32()); + Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture branch, if_true; EXPECT_THAT( - phi, - IsPhi(kMachInt32, - IsChangeFloat64ToInt32(IsLoadHeapNumber(val, 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())))))); + r.replacement(), + IsPhi( + kMachInt32, + IsChangeFloat64ToInt32(IsLoadHeapNumber(value, CaptureEq(&if_true))), + IsWord32Sar(value, IsInt32Constant(kSmiTagSize + kSmiShiftSize)), + IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), + IsIfFalse(AllOf( + CaptureEq(&branch), + IsBranch(IsWord32And(value, IsInt32Constant(kSmiTagMask)), + graph()->start())))))); } @@ -274,23 +287,22 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToUint32) { STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTagSize == 1); - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - Node* phi = reduction.replacement(); + Node* value = Parameter(Type::Unsigned32()); + Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture branch, if_true; EXPECT_THAT( - phi, - IsPhi(kMachUint32, - IsChangeFloat64ToUint32(IsLoadHeapNumber(val, 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())))))); + r.replacement(), + IsPhi( + kMachUint32, + IsChangeFloat64ToUint32(IsLoadHeapNumber(value, CaptureEq(&if_true))), + IsWord32Sar(value, IsInt32Constant(kSmiTagSize + kSmiShiftSize)), + IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), + IsIfFalse(AllOf( + CaptureEq(&branch), + IsBranch(IsWord32And(value, IsInt32Constant(kSmiTagMask)), + graph()->start())))))); } @@ -298,30 +310,30 @@ 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(); + Node* value = Parameter(Type::Number()); + Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture branch, heap_number, if_false; EXPECT_THAT( - phi, + r.replacement(), IsPhi( - kMachAnyTagged, IsWord32Shl(val, IsInt32Constant(SmiShiftAmount())), + kMachAnyTagged, + IsWord32Shl(value, IsInt32Constant(kSmiTagSize + kSmiShiftSize)), IsFinish(AllOf(CaptureEq(&heap_number), IsAllocateHeapNumber(_, CaptureEq(&if_false))), IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier), CaptureEq(&heap_number), - IsInt32Constant(HeapNumberValueOffset()), - IsChangeUint32ToFloat64(val), + IsInt32Constant(HeapNumber::kValueOffset - + kHeapObjectTag), + IsChangeUint32ToFloat64(value), 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)))))); + IsMerge(IsIfTrue(AllOf( + CaptureEq(&branch), + IsBranch(IsUint32LessThanOrEqual( + value, IsInt32Constant(Smi::kMaxValue)), + graph()->start()))), + AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch)))))); } @@ -337,14 +349,11 @@ class ChangeLowering64Test : public ChangeLoweringTest { TARGET_TEST_F(ChangeLowering64Test, ChangeInt32ToTagged) { - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - EXPECT_THAT(reduction.replacement(), - IsWord64Shl(IsChangeInt32ToInt64(val), - IsInt64Constant(SmiShiftAmount()))); + Node* value = Parameter(Type::Signed32()); + Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); + EXPECT_THAT(r.replacement(), IsChangeInt32ToSmi(value)); } @@ -352,26 +361,23 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToFloat64) { STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTagSize == 1); - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - Node* phi = reduction.replacement(); + Node* value = Parameter(Type::Number()); + Node* node = graph()->NewNode(simplified()->ChangeTaggedToFloat64(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture branch, if_true; EXPECT_THAT( - phi, - IsPhi( - kMachFloat64, IsLoadHeapNumber(val, CaptureEq(&if_true)), - IsChangeInt32ToFloat64(IsTruncateInt64ToInt32( - IsWord64Sar(val, IsInt64Constant(SmiShiftAmount())))), - IsMerge( - AllOf(CaptureEq(&if_true), - IsIfTrue(AllOf( - CaptureEq(&branch), - IsBranch(IsWord64And(val, IsInt64Constant(kSmiTagMask)), - graph()->start())))), - IsIfFalse(CaptureEq(&branch))))); + r.replacement(), + IsPhi(kMachFloat64, IsLoadHeapNumber(value, CaptureEq(&if_true)), + IsChangeInt32ToFloat64(IsTruncateInt64ToInt32(IsWord64Sar( + value, IsInt64Constant(kSmiTagSize + kSmiShiftSize)))), + IsMerge(AllOf(CaptureEq(&if_true), + IsIfTrue(AllOf( + CaptureEq(&branch), + IsBranch(IsWord64And( + value, IsInt64Constant(kSmiTagMask)), + graph()->start())))), + IsIfFalse(CaptureEq(&branch))))); } @@ -379,24 +385,23 @@ 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(); + Node* value = Parameter(Type::Signed32()); + Node* node = graph()->NewNode(simplified()->ChangeTaggedToInt32(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture branch, if_true; EXPECT_THAT( - phi, - IsPhi(kMachInt32, - IsChangeFloat64ToInt32(IsLoadHeapNumber(val, CaptureEq(&if_true))), - IsTruncateInt64ToInt32( - IsWord64Sar(val, IsInt64Constant(SmiShiftAmount()))), - IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), - IsIfFalse(AllOf( - CaptureEq(&branch), - IsBranch(IsWord64And(val, IsInt64Constant(kSmiTagMask)), - graph()->start())))))); + r.replacement(), + IsPhi( + kMachInt32, + IsChangeFloat64ToInt32(IsLoadHeapNumber(value, CaptureEq(&if_true))), + IsTruncateInt64ToInt32( + IsWord64Sar(value, IsInt64Constant(kSmiTagSize + kSmiShiftSize))), + IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), + IsIfFalse(AllOf( + CaptureEq(&branch), + IsBranch(IsWord64And(value, IsInt64Constant(kSmiTagMask)), + graph()->start())))))); } @@ -404,24 +409,23 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToUint32) { STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTagSize == 1); - Node* val = Parameter(0); - Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), val); - Reduction reduction = Reduce(node); - ASSERT_TRUE(reduction.Changed()); - - Node* phi = reduction.replacement(); + Node* value = Parameter(Type::Unsigned32()); + Node* node = graph()->NewNode(simplified()->ChangeTaggedToUint32(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture branch, if_true; EXPECT_THAT( - phi, - IsPhi(kMachUint32, - IsChangeFloat64ToUint32(IsLoadHeapNumber(val, CaptureEq(&if_true))), - IsTruncateInt64ToInt32( - IsWord64Sar(val, IsInt64Constant(SmiShiftAmount()))), - IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), - IsIfFalse(AllOf( - CaptureEq(&branch), - IsBranch(IsWord64And(val, IsInt64Constant(kSmiTagMask)), - graph()->start())))))); + r.replacement(), + IsPhi( + kMachUint32, + IsChangeFloat64ToUint32(IsLoadHeapNumber(value, CaptureEq(&if_true))), + IsTruncateInt64ToInt32( + IsWord64Sar(value, IsInt64Constant(kSmiTagSize + kSmiShiftSize))), + IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), + IsIfFalse(AllOf( + CaptureEq(&branch), + IsBranch(IsWord64And(value, IsInt64Constant(kSmiTagMask)), + graph()->start())))))); } @@ -429,31 +433,31 @@ 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(); + Node* value = Parameter(Type::Number()); + Node* node = graph()->NewNode(simplified()->ChangeUint32ToTagged(), value); + Reduction r = Reduce(node); + ASSERT_TRUE(r.Changed()); Capture branch, heap_number, if_false; EXPECT_THAT( - phi, + r.replacement(), IsPhi( - kMachAnyTagged, IsWord64Shl(IsChangeUint32ToUint64(val), - IsInt64Constant(SmiShiftAmount())), + kMachAnyTagged, + IsWord64Shl(IsChangeUint32ToUint64(value), + IsInt64Constant(kSmiTagSize + kSmiShiftSize)), IsFinish(AllOf(CaptureEq(&heap_number), IsAllocateHeapNumber(_, CaptureEq(&if_false))), IsStore(StoreRepresentation(kMachFloat64, kNoWriteBarrier), CaptureEq(&heap_number), - IsInt64Constant(HeapNumberValueOffset()), - IsChangeUint32ToFloat64(val), + IsInt64Constant(HeapNumber::kValueOffset - + kHeapObjectTag), + IsChangeUint32ToFloat64(value), 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)))))); + IsMerge(IsIfTrue(AllOf( + CaptureEq(&branch), + IsBranch(IsUint32LessThanOrEqual( + value, IsInt32Constant(Smi::kMaxValue)), + graph()->start()))), + AllOf(CaptureEq(&if_false), IsIfFalse(CaptureEq(&branch)))))); } } // namespace compiler