Revision: 23175
Author: [email protected]
Date: Tue Aug 19 04:54:06 2014 UTC
Log: [turbofan] Support lowering of
ChangeFloat64ToTagged/ChangeTaggedToInt32.
Adds new ValueEffect operator to ensure proper scheduling of
AllocateHeapNumber call nodes.
Also includes some refactoring to reduce code duplication.
TEST=compiler-unittests
[email protected]
Review URL: https://codereview.chromium.org/481903002
http://code.google.com/p/v8/source/detail?r=23175
Modified:
/branches/bleeding_edge/src/compiler/change-lowering.cc
/branches/bleeding_edge/src/compiler/change-lowering.h
/branches/bleeding_edge/src/compiler/common-operator.h
/branches/bleeding_edge/src/compiler/opcodes.h
/branches/bleeding_edge/src/compiler/operator-properties-inl.h
/branches/bleeding_edge/src/compiler/typer.cc
/branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc
/branches/bleeding_edge/test/compiler-unittests/common-operator-unittest.cc
/branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h
/branches/bleeding_edge/test/compiler-unittests/graph-unittest.cc
/branches/bleeding_edge/test/compiler-unittests/graph-unittest.h
=======================================
--- /branches/bleeding_edge/src/compiler/change-lowering.cc Mon Aug 18
11:36:06 2014 UTC
+++ /branches/bleeding_edge/src/compiler/change-lowering.cc Tue Aug 19
04:54:06 2014 UTC
@@ -15,16 +15,19 @@
Reduction ChangeLowering::Reduce(Node* node) {
Node* control = graph()->start();
- Node* effect = control;
switch (node->opcode()) {
case IrOpcode::kChangeBitToBool:
return ChangeBitToBool(node->InputAt(0), control);
case IrOpcode::kChangeBoolToBit:
return ChangeBoolToBit(node->InputAt(0));
+ case IrOpcode::kChangeFloat64ToTagged:
+ return ChangeFloat64ToTagged(node->InputAt(0), control);
case IrOpcode::kChangeInt32ToTagged:
- return ChangeInt32ToTagged(node->InputAt(0), effect, control);
+ return ChangeInt32ToTagged(node->InputAt(0), control);
case IrOpcode::kChangeTaggedToFloat64:
- return ChangeTaggedToFloat64(node->InputAt(0), effect, control);
+ return ChangeTaggedToFloat64(node->InputAt(0), control);
+ case IrOpcode::kChangeTaggedToInt32:
+ return ChangeTaggedToInt32(node->InputAt(0), control);
default:
return NoChange();
}
@@ -77,14 +80,16 @@
}
-Reduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* effect,
- Node* control) {
+Reduction ChangeLowering::ChangeFloat64ToTagged(Node* val, Node* control) {
+ return Replace(AllocateHeapNumberWithValue(val, control));
+}
+
+
+Reduction ChangeLowering::ChangeInt32ToTagged(Node* val, Node* control) {
if (machine()->is64()) {
return Replace(
graph()->NewNode(machine()->WordShl(), val,
SmiShiftBitsConstant()));
}
-
- Node* context = jsgraph()->SmiConstant(0);
Node* add = graph()->NewNode(machine()->Int32AddWithOverflow(), val,
val);
Node* ovf = graph()->NewNode(common()->Projection(1), add);
@@ -92,34 +97,21 @@
Node* branch = graph()->NewNode(common()->Branch(), ovf, control);
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
- Node* number = graph()->NewNode(machine()->ChangeInt32ToFloat64(), val);
-
- const Runtime::Function* fn =
- Runtime::FunctionForId(Runtime::kAllocateHeapNumber);
- DCHECK_EQ(0, fn->nargs);
- CallDescriptor* desc = linkage()->GetRuntimeCallDescriptor(
- fn->function_id, 0, Operator::kNoProperties);
- Node* heap_number = graph()->NewNode(
- common()->Call(desc), jsgraph()->CEntryStubConstant(),
- jsgraph()->ExternalConstant(ExternalReference(fn, isolate())),
- jsgraph()->Int32Constant(fn->nargs), context, effect, if_true);
- Node* store = graph()->NewNode(
- machine()->Store(kMachFloat64, kNoWriteBarrier), heap_number,
- HeapNumberValueIndexConstant(), number, heap_number, if_true);
- Node* finish = graph()->NewNode(common()->Finish(1), heap_number, store);
+ Node* heap_number = AllocateHeapNumberWithValue(
+ graph()->NewNode(machine()->ChangeInt32ToFloat64(), val), if_true);
Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* smi = graph()->NewNode(common()->Projection(0), add);
Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
- Node* phi = graph()->NewNode(common()->Phi(2), finish, smi, merge);
+ Node* phi = graph()->NewNode(common()->Phi(2), heap_number, smi, merge);
return Replace(phi);
}
-Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* effect,
- Node* control) {
+Reduction ChangeLowering::ChangeTaggedToInt32(Node* val, Node* control) {
+ STATIC_ASSERT(kSmiTag == 0);
STATIC_ASSERT(kSmiTagMask == 1);
Node* tag = graph()->NewNode(machine()->WordAnd(), val,
@@ -130,6 +122,35 @@
Node* load = graph()->NewNode(
machine()->Load(kMachFloat64), val, HeapNumberValueIndexConstant(),
graph()->NewNode(common()->ControlEffect(), if_true));
+ Node* change = graph()->NewNode(machine()->ChangeFloat64ToInt32(), load);
+
+ Node* if_false = graph()->NewNode(common()->IfFalse(), branch);
+ Node* integer =
+ graph()->NewNode(machine()->WordSar(), val, SmiShiftBitsConstant());
+ Node* number =
+ machine()->is64()
+ ? graph()->NewNode(machine()->ConvertInt64ToInt32(), integer)
+ : integer;
+
+ Node* merge = graph()->NewNode(common()->Merge(2), if_true, if_false);
+ Node* phi = graph()->NewNode(common()->Phi(2), change, number, merge);
+
+ return Replace(phi);
+}
+
+
+Reduction ChangeLowering::ChangeTaggedToFloat64(Node* val, Node* control) {
+ STATIC_ASSERT(kSmiTag == 0);
+ STATIC_ASSERT(kSmiTagMask == 1);
+
+ Node* tag = graph()->NewNode(machine()->WordAnd(), val,
+ jsgraph()->Int32Constant(kSmiTagMask));
+ 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* if_false = graph()->NewNode(common()->IfFalse(), branch);
Node* integer =
@@ -156,6 +177,27 @@
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
=======================================
--- /branches/bleeding_edge/src/compiler/change-lowering.h Mon Aug 18
06:54:07 2014 UTC
+++ /branches/bleeding_edge/src/compiler/change-lowering.h Tue Aug 19
04:54:06 2014 UTC
@@ -32,8 +32,10 @@
Reduction ChangeBitToBool(Node* val, Node* control);
Reduction ChangeBoolToBit(Node* val);
- Reduction ChangeInt32ToTagged(Node* val, Node* effect, Node* control);
- Reduction ChangeTaggedToFloat64(Node* val, Node* effect, Node* control);
+ Reduction ChangeFloat64ToTagged(Node* val, Node* control);
+ Reduction ChangeInt32ToTagged(Node* val, Node* control);
+ Reduction ChangeTaggedToFloat64(Node* val, Node* control);
+ Reduction ChangeTaggedToInt32(Node* val, Node* control);
Graph* graph() const;
Isolate* isolate() const;
@@ -43,6 +45,8 @@
MachineOperatorBuilder* machine() const { return machine_; }
private:
+ Node* AllocateHeapNumberWithValue(Node* value, Node* control);
+
JSGraph* jsgraph_;
Linkage* linkage_;
MachineOperatorBuilder* machine_;
=======================================
--- /branches/bleeding_edge/src/compiler/common-operator.h Mon Aug 18
11:36:06 2014 UTC
+++ /branches/bleeding_edge/src/compiler/common-operator.h Tue Aug 19
04:54:06 2014 UTC
@@ -134,6 +134,11 @@
return new (zone_) SimpleOperator(IrOpcode::kControlEffect,
Operator::kPure,
0, 0, "ControlEffect");
}
+ Operator* ValueEffect(int arguments) {
+ DCHECK(arguments > 0); // Disallow empty value effects.
+ return new (zone_) SimpleOperator(IrOpcode::kValueEffect,
Operator::kPure,
+ arguments, 0, "ValueEffect");
+ }
Operator* Finish(int arguments) {
DCHECK(arguments > 0); // Disallow empty finishes.
return new (zone_) Operator1<int>(IrOpcode::kFinish, Operator::kPure,
1, 1,
=======================================
--- /branches/bleeding_edge/src/compiler/opcodes.h Mon Aug 18 11:36:06 2014
UTC
+++ /branches/bleeding_edge/src/compiler/opcodes.h Tue Aug 19 04:54:06 2014
UTC
@@ -34,6 +34,7 @@
V(Phi) \
V(EffectPhi) \
V(ControlEffect) \
+ V(ValueEffect) \
V(Finish) \
V(FrameState) \
V(StateValues) \
=======================================
--- /branches/bleeding_edge/src/compiler/operator-properties-inl.h Mon Aug
18 13:09:06 2014 UTC
+++ /branches/bleeding_edge/src/compiler/operator-properties-inl.h Tue Aug
19 04:54:06 2014 UTC
@@ -91,6 +91,7 @@
inline bool OperatorProperties::HasEffectOutput(Operator* op) {
return op->opcode() == IrOpcode::kStart ||
op->opcode() == IrOpcode::kControlEffect ||
+ op->opcode() == IrOpcode::kValueEffect ||
(op->opcode() != IrOpcode::kFinish && GetEffectInputCount(op) >
0);
}
=======================================
--- /branches/bleeding_edge/src/compiler/typer.cc Mon Aug 18 11:36:06 2014
UTC
+++ /branches/bleeding_edge/src/compiler/typer.cc Tue Aug 19 04:54:06 2014
UTC
@@ -270,6 +270,11 @@
Bounds Typer::Visitor::TypeControlEffect(Node* node) {
return Bounds(Type::None(zone()));
}
+
+
+Bounds Typer::Visitor::TypeValueEffect(Node* node) {
+ return Bounds(Type::None(zone()));
+}
Bounds Typer::Visitor::TypeFinish(Node* node) { return OperandType(node,
0); }
=======================================
---
/branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc
Mon Aug 18 11:36:06 2014 UTC
+++
/branches/bleeding_edge/test/compiler-unittests/change-lowering-unittest.cc
Tue Aug 19 04:54:06 2014 UTC
@@ -19,20 +19,52 @@
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 @@
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 @@
};
-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());
+
+ EXPECT_THAT(reduction.replacement(), IsWordEqual(val, IsTrue()));
}
-class ChangeLowering32Test : public ChangeLoweringTest<int32_t> {
- public:
- virtual ~ChangeLowering32Test() {}
-};
-
-
-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 @@
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 @@
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(
@@ -177,22 +251,43 @@
IsIfFalse(CaptureEq(&branch)))));
}
-
-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) {
@@ -201,10 +296,8 @@
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 @@
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(
@@ -237,6 +327,32 @@
graph()->start())))),
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
=======================================
---
/branches/bleeding_edge/test/compiler-unittests/common-operator-unittest.cc
Mon Aug 18 11:36:06 2014 UTC
+++
/branches/bleeding_edge/test/compiler-unittests/common-operator-unittest.cc
Tue Aug 19 04:54:06 2014 UTC
@@ -10,6 +10,9 @@
namespace internal {
namespace compiler {
+static const int kArguments[] = {1, 5, 6, 42, 100, 10000, kMaxInt};
+
+
CommonOperatorTest::CommonOperatorTest() : common_(zone()) {}
@@ -24,10 +27,21 @@
EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
}
+
+
+TEST_F(CommonOperatorTest, ValueEffect) {
+ TRACED_FOREACH(int, arguments, kArguments) {
+ Operator* op = common()->ValueEffect(arguments);
+ EXPECT_EQ(arguments, OperatorProperties::GetValueInputCount(op));
+ EXPECT_EQ(arguments, OperatorProperties::GetTotalInputCount(op));
+ EXPECT_EQ(0, OperatorProperties::GetControlOutputCount(op));
+ EXPECT_EQ(1, OperatorProperties::GetEffectOutputCount(op));
+ EXPECT_EQ(0, OperatorProperties::GetValueOutputCount(op));
+ }
+}
TEST_F(CommonOperatorTest, Finish) {
- static const int kArguments[] = {1, 5, 6, 42, 100, 10000, kMaxInt};
TRACED_FOREACH(int, arguments, kArguments) {
Operator* op = common()->Finish(arguments);
EXPECT_EQ(1, OperatorProperties::GetValueInputCount(op));
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h
Mon Aug 18 06:54:07 2014 UTC
+++ /branches/bleeding_edge/test/compiler-unittests/compiler-unittests.h
Tue Aug 19 04:54:06 2014 UTC
@@ -33,6 +33,16 @@
#endif
+// The TARGET_TEST_P(Case, Name) macro works just like
+// TEST_P(Case, Name), except that the test is disabled
+// if the platform is not a supported TurboFan target.
+#if V8_TURBOFAN_TARGET
+#define TARGET_TEST_P(Case, Name) TEST_P(Case, Name)
+#else
+#define TARGET_TEST_P(Case, Name) TEST_P(Case, DISABLED_##Name)
+#endif
+
+
// The TARGET_TYPED_TEST(Case, Name) macro works just like
// TYPED_TEST(Case, Name), except that the test is disabled
// if the platform is not a supported TurboFan target.
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/graph-unittest.cc Mon
Aug 18 11:36:06 2014 UTC
+++ /branches/bleeding_edge/test/compiler-unittests/graph-unittest.cc Tue
Aug 19 04:54:06 2014 UTC
@@ -8,6 +8,7 @@
#include "src/compiler/node-properties-inl.h"
+using testing::_;
using testing::MakeMatcher;
using testing::MatcherInterface;
using testing::MatchResultListener;
@@ -565,6 +566,11 @@
return MakeMatcher(
new IsControl1Matcher(IrOpcode::kControlEffect, control_matcher));
}
+
+
+Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher) {
+ return MakeMatcher(new IsUnopMatcher(IrOpcode::kValueEffect,
value_matcher));
+}
Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
@@ -671,6 +677,7 @@
return MakeMatcher(new IsUnopMatcher(IrOpcode::k##Name,
input_matcher)); \
}
IS_UNOP_MATCHER(ConvertInt64ToInt32)
+IS_UNOP_MATCHER(ChangeFloat64ToInt32)
IS_UNOP_MATCHER(ChangeInt32ToFloat64)
#undef IS_UNOP_MATCHER
=======================================
--- /branches/bleeding_edge/test/compiler-unittests/graph-unittest.h Mon
Aug 18 11:36:06 2014 UTC
+++ /branches/bleeding_edge/test/compiler-unittests/graph-unittest.h Tue
Aug 19 04:54:06 2014 UTC
@@ -35,6 +35,7 @@
using ::testing::Matcher;
+
Matcher<Node*> IsBranch(const Matcher<Node*>& value_matcher,
const Matcher<Node*>& control_matcher);
Matcher<Node*> IsMerge(const Matcher<Node*>& control0_matcher,
@@ -42,6 +43,7 @@
Matcher<Node*> IsIfTrue(const Matcher<Node*>& control_matcher);
Matcher<Node*> IsIfFalse(const Matcher<Node*>& control_matcher);
Matcher<Node*> IsControlEffect(const Matcher<Node*>& control_matcher);
+Matcher<Node*> IsValueEffect(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsFinish(const Matcher<Node*>& value_matcher,
const Matcher<Node*>& effect_matcher);
Matcher<Node*> IsExternalConstant(
@@ -93,6 +95,7 @@
Matcher<Node*> IsInt32AddWithOverflow(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsConvertInt64ToInt32(const Matcher<Node*>& input_matcher);
+Matcher<Node*> IsChangeFloat64ToInt32(const Matcher<Node*>& input_matcher);
Matcher<Node*> IsChangeInt32ToFloat64(const Matcher<Node*>& input_matcher);
} // namespace compiler
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.