From fa3dc0a534eea4252136ab0c04a811766a4ef4a6 Mon Sep 17 00:00:00 2001 From: "bmeurer@chromium.org" Date: Wed, 20 Aug 2014 08:13:00 +0000 Subject: [PATCH] [turbofan] Add support for ChangeTaggedToUint32 in ChangeLowering. Also refactor some common code in ChangeLowering. TEST=cctest,compiler-unittests R=jarin@chromium.org Review URL: https://codereview.chromium.org/488043002 git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23216 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/compiler/change-lowering.cc | 89 ++++++++++++---------- src/compiler/change-lowering.h | 9 ++- .../compiler-unittests/change-lowering-unittest.cc | 51 +++++++++++++ 3 files changed, 104 insertions(+), 45 deletions(-) diff --git a/src/compiler/change-lowering.cc b/src/compiler/change-lowering.cc index ab5b662..2348dd5 100644 --- a/src/compiler/change-lowering.cc +++ b/src/compiler/change-lowering.cc @@ -27,6 +27,11 @@ Reduction ChangeLowering::Reduce(Node* node) { case IrOpcode::kChangeTaggedToFloat64: return ChangeTaggedToFloat64(node->InputAt(0), control); case IrOpcode::kChangeTaggedToInt32: + case IrOpcode::kChangeTaggedToUint32: + // ToInt32 and ToUint32 perform exactly the same operation, just the + // interpretation of the resulting 32 bit value is different, so we can + // use the same subgraph for both operations. + // See ECMA-262 9.5: ToInt32 and ECMA-262 9.6: ToUint32. return ChangeTaggedToInt32(node->InputAt(0), control); case IrOpcode::kChangeUint32ToTagged: return ChangeUint32ToTagged(node->InputAt(0), control); @@ -73,6 +78,43 @@ Node* ChangeLowering::SmiShiftBitsConstant() { } +Node* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) { + // The AllocateHeapNumber() runtime function does not use the context, so we + // can safely pass in Smi zero here. + Node* context = jsgraph()->ZeroConstant(); + Node* effect = graph()->NewNode(common()->ValueEffect(1), value); + const Runtime::Function* function = + Runtime::FunctionForId(Runtime::kAllocateHeapNumber); + DCHECK_EQ(0, function->nargs); + CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor( + function->function_id, 0, Operator::kNoProperties); + Node* heap_number = graph()->NewNode( + common()->Call(desc), jsgraph()->CEntryStubConstant(), + jsgraph()->ExternalConstant(ExternalReference(function, isolate())), + jsgraph()->Int32Constant(function->nargs), context, effect, control); + Node* store = graph()->NewNode( + machine()->Store(kMachFloat64, kNoWriteBarrier), heap_number, + HeapNumberValueIndexConstant(), value, heap_number, control); + return graph()->NewNode(common()->Finish(1), heap_number, store); +} + + +Node* ChangeLowering::ChangeSmiToInt32(Node* value) { + value = graph()->NewNode(machine()->WordSar(), value, SmiShiftBitsConstant()); + if (machine()->is64()) { + value = graph()->NewNode(machine()->TruncateInt64ToInt32(), value); + } + return value; +} + + +Node* ChangeLowering::LoadHeapNumberValue(Node* value, Node* control) { + return graph()->NewNode(machine()->Load(kMachFloat64), value, + HeapNumberValueIndexConstant(), + graph()->NewNode(common()->ControlEffect(), control)); +} + + Reduction ChangeLowering::ChangeBitToBool(Node* val, Node* control) { Node* branch = graph()->NewNode(common()->Branch(), val, control); @@ -137,18 +179,11 @@ Reduction ChangeLowering::ChangeTaggedToInt32(Node* val, Node* control) { Node* branch = graph()->NewNode(common()->Branch(), tag, control); Node* if_true = graph()->NewNode(common()->IfTrue(), branch); - Node* load = graph()->NewNode( - machine()->Load(kMachFloat64), val, HeapNumberValueIndexConstant(), - graph()->NewNode(common()->ControlEffect(), if_true)); - Node* change = graph()->NewNode(machine()->TruncateFloat64ToInt32(), load); + Node* change = graph()->NewNode(machine()->TruncateFloat64ToInt32(), + LoadHeapNumberValue(val, if_true)); Node* if_false = graph()->NewNode(common()->IfFalse(), branch); - Node* integer = - graph()->NewNode(machine()->WordSar(), val, SmiShiftBitsConstant()); - Node* number = - machine()->is64() - ? graph()->NewNode(machine()->TruncateInt64ToInt32(), integer) - : integer; + Node* number = ChangeSmiToInt32(val); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* phi = graph()->NewNode(common()->Phi(2), change, number, merge); @@ -166,18 +201,11 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) { Node* branch = graph()->NewNode(common()->Branch(), tag, control); Node* if_true = graph()->NewNode(common()->IfTrue(), branch); - Node* load = graph()->NewNode( - machine()->Load(kMachFloat64), val, HeapNumberValueIndexConstant(), - graph()->NewNode(common()->ControlEffect(), if_true)); + Node* load = LoadHeapNumberValue(val, if_true); Node* if_false = graph()->NewNode(common()->IfFalse(), branch); - Node* integer = - graph()->NewNode(machine()->WordSar(), val, SmiShiftBitsConstant()); - Node* number = graph()->NewNode( - machine()->ChangeInt32ToFloat64(), - machine()->is64() - ? graph()->NewNode(machine()->TruncateInt64ToInt32(), integer) - : integer); + Node* number = graph()->NewNode(machine()->ChangeInt32ToFloat64(), + ChangeSmiToInt32(val)); Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false); Node* phi = graph()->NewNode(common()->Phi(2), load, number, merge); @@ -223,27 +251,6 @@ CommonOperatorBuilder* ChangeLowering::common() const { return jsgraph()->common(); } - -Node* ChangeLowering::AllocateHeapNumberWithValue(Node* value, Node* control) { - // The AllocateHeapNumber() runtime function does not use the context, so we - // can safely pass in Smi zero here. - Node* context = jsgraph()->ZeroConstant(); - Node* effect = graph()->NewNode(common()->ValueEffect(1), value); - const Runtime::Function* function = - Runtime::FunctionForId(Runtime::kAllocateHeapNumber); - DCHECK_EQ(0, function->nargs); - CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor( - function->function_id, 0, Operator::kNoProperties); - Node* heap_number = graph()->NewNode( - common()->Call(desc), jsgraph()->CEntryStubConstant(), - jsgraph()->ExternalConstant(ExternalReference(function, isolate())), - jsgraph()->Int32Constant(function->nargs), context, effect, control); - Node* store = graph()->NewNode( - machine()->Store(kMachFloat64, kNoWriteBarrier), heap_number, - HeapNumberValueIndexConstant(), value, heap_number, control); - return graph()->NewNode(common()->Finish(1), heap_number, store); -} - } // namespace compiler } // namespace internal } // namespace v8 diff --git a/src/compiler/change-lowering.h b/src/compiler/change-lowering.h index 9601b55..8352631 100644 --- a/src/compiler/change-lowering.h +++ b/src/compiler/change-lowering.h @@ -26,11 +26,15 @@ class ChangeLowering V8_FINAL : public Reducer { virtual Reduction Reduce(Node* node) V8_OVERRIDE; - protected: + private: Node* HeapNumberValueIndexConstant(); Node* SmiMaxValueConstant(); Node* SmiShiftBitsConstant(); + Node* AllocateHeapNumberWithValue(Node* value, Node* control); + Node* ChangeSmiToInt32(Node* value); + Node* LoadHeapNumberValue(Node* value, Node* control); + Reduction ChangeBitToBool(Node* val, Node* control); Reduction ChangeBoolToBit(Node* val); Reduction ChangeFloat64ToTagged(Node* val, Node* control); @@ -46,9 +50,6 @@ class ChangeLowering V8_FINAL : public Reducer { CommonOperatorBuilder* common() const; MachineOperatorBuilder* machine() const { return machine_; } - private: - Node* AllocateHeapNumberWithValue(Node* value, Node* control); - JSGraph* jsgraph_; Linkage* linkage_; MachineOperatorBuilder* machine_; diff --git a/test/compiler-unittests/change-lowering-unittest.cc b/test/compiler-unittests/change-lowering-unittest.cc index 303c1dc..ce89622 100644 --- a/test/compiler-unittests/change-lowering-unittest.cc +++ b/test/compiler-unittests/change-lowering-unittest.cc @@ -289,6 +289,31 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToInt32) { } +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(); + Capture branch, if_true; + EXPECT_THAT( + phi, + IsPhi(IsTruncateFloat64ToInt32(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())))))); +} + + TARGET_TEST_F(ChangeLowering32Test, ChangeUint32ToTagged) { STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTagSize == 1); @@ -399,6 +424,32 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToInt32) { } +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(); + Capture branch, if_true; + EXPECT_THAT( + phi, + IsPhi(IsTruncateFloat64ToInt32(IsLoad( + kMachFloat64, val, IsInt32Constant(HeapNumberValueOffset()), + IsControlEffect(CaptureEq(&if_true)))), + IsTruncateInt64ToInt32( + IsWord64Sar(val, IsInt32Constant(SmiShiftAmount()))), + IsMerge(AllOf(CaptureEq(&if_true), IsIfTrue(CaptureEq(&branch))), + IsIfFalse(AllOf( + CaptureEq(&branch), + IsBranch(IsWord64And(val, IsInt32Constant(kSmiTagMask)), + graph()->start())))))); +} + + TARGET_TEST_F(ChangeLowering64Test, ChangeUint32ToTagged) { STATIC_ASSERT(kSmiTag == 0); STATIC_ASSERT(kSmiTagSize == 1); -- 2.7.4