Commit 7c36df7b authored by bmeurer@chromium.org's avatar bmeurer@chromium.org

[turbofan] Add support for ChangeUint32ToTagged in ChangeLowering.

TEST=compiler-unittests
R=jarin@chromium.org

Review URL: https://codereview.chromium.org/491433002

git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@23215 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent 37058c14
......@@ -28,6 +28,8 @@ Reduction ChangeLowering::Reduce(Node* node) {
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();
}
......@@ -44,6 +46,20 @@ Node* ChangeLowering::HeapNumberValueIndexConstant() {
}
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() {
// TODO(turbofan): Work-around for weird GCC 4.6 linker issue:
// src/compiler/change-lowering.cc:46: undefined reference to
......@@ -170,6 +186,33 @@ Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) {
}
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(); }
......
......@@ -28,6 +28,7 @@ class ChangeLowering V8_FINAL : public Reducer {
protected:
Node* HeapNumberValueIndexConstant();
Node* SmiMaxValueConstant();
Node* SmiShiftBitsConstant();
Reduction ChangeBitToBool(Node* val, Node* control);
......@@ -36,6 +37,7 @@ class ChangeLowering V8_FINAL : public Reducer {
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;
......
......@@ -53,6 +53,10 @@ class ChangeLoweringTest : public GraphTest {
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 @@ class ChangeLoweringTest : public GraphTest {
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());
......@@ -275,6 +289,37 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeTaggedToInt32) {
}
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))))));
}
// -----------------------------------------------------------------------------
// 64-bit
......@@ -353,6 +398,38 @@ TARGET_TEST_F(ChangeLowering64Test, ChangeTaggedToInt32) {
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
} // namespace v8
......@@ -662,6 +662,7 @@ Matcher<Node*> IsStore(const Matcher<MachineType>& type_matcher,
}
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(Word64Sar)
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_BINOP_MATCHER(Int32AddWithOverflow)
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)
......
......@@ -80,6 +80,8 @@ Matcher<Node*> IsWord32And(const Matcher<Node*>& lhs_matcher,
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 @@ Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher,
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);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment