Commit 5f3914fc authored by Benedikt Meurer's avatar Benedikt Meurer

[turbofan] Use the typer to statically detect Smis.

R=rossberg@chromium.org

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

Cr-Commit-Position: refs/heads/master@{#26939}
parent f0b11873
...@@ -165,7 +165,7 @@ Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) { ...@@ -165,7 +165,7 @@ Reduction ChangeLowering::ChangeInt32ToTagged(Node* value, Node* control) {
machine()->Word64Shl(), machine()->Word64Shl(),
graph()->NewNode(machine()->ChangeInt32ToInt64(), value), graph()->NewNode(machine()->ChangeInt32ToInt64(), value),
SmiShiftBitsConstant())); SmiShiftBitsConstant()));
} else if (NodeProperties::GetBounds(value).upper->Is(Type::Signed31())) { } else if (NodeProperties::GetBounds(value).upper->Is(Type::SignedSmall())) {
return Replace( return Replace(
graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant())); graph()->NewNode(machine()->WordShl(), value, SmiShiftBitsConstant()));
} }
......
...@@ -1140,12 +1140,13 @@ Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) { ...@@ -1140,12 +1140,13 @@ Node* SimplifiedLowering::OffsetMinusTagConstant(int32_t offset) {
} }
WriteBarrierKind SimplifiedLowering::ComputeWriteBarrierKind( namespace {
BaseTaggedness base_is_tagged, MachineType representation, Node* value) {
// TODO(turbofan): skip write barriers for Smis, etc. WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged,
if (machine()->Is64() && value->opcode() == IrOpcode::kChangeInt32ToTagged) { MachineType representation,
// TODO(bmeurer): Remove this hack once we have a way to represent "sminess" Type* type) {
// of values, either in types or representations. if (type->Is(Type::TaggedSigned())) {
// Write barriers are only for writes of heap objects.
return kNoWriteBarrier; return kNoWriteBarrier;
} }
if (base_is_tagged == kTaggedBase && if (base_is_tagged == kTaggedBase &&
...@@ -1156,6 +1157,8 @@ WriteBarrierKind SimplifiedLowering::ComputeWriteBarrierKind( ...@@ -1156,6 +1157,8 @@ WriteBarrierKind SimplifiedLowering::ComputeWriteBarrierKind(
return kNoWriteBarrier; return kNoWriteBarrier;
} }
} // namespace
void SimplifiedLowering::DoLoadField(Node* node) { void SimplifiedLowering::DoLoadField(Node* node) {
const FieldAccess& access = FieldAccessOf(node->op()); const FieldAccess& access = FieldAccessOf(node->op());
...@@ -1167,8 +1170,9 @@ void SimplifiedLowering::DoLoadField(Node* node) { ...@@ -1167,8 +1170,9 @@ void SimplifiedLowering::DoLoadField(Node* node) {
void SimplifiedLowering::DoStoreField(Node* node) { void SimplifiedLowering::DoStoreField(Node* node) {
const FieldAccess& access = FieldAccessOf(node->op()); const FieldAccess& access = FieldAccessOf(node->op());
WriteBarrierKind kind = ComputeWriteBarrierKind( Type* type = NodeProperties::GetBounds(node->InputAt(1)).upper;
access.base_is_tagged, access.machine_type, node->InputAt(1)); WriteBarrierKind kind =
ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, type);
node->set_op( node->set_op(
machine()->Store(StoreRepresentation(access.machine_type, kind))); machine()->Store(StoreRepresentation(access.machine_type, kind)));
Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag()); Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
...@@ -1273,10 +1277,11 @@ void SimplifiedLowering::DoLoadElement(Node* node) { ...@@ -1273,10 +1277,11 @@ void SimplifiedLowering::DoLoadElement(Node* node) {
void SimplifiedLowering::DoStoreElement(Node* node) { void SimplifiedLowering::DoStoreElement(Node* node) {
const ElementAccess& access = ElementAccessOf(node->op()); const ElementAccess& access = ElementAccessOf(node->op());
node->set_op(machine()->Store(StoreRepresentation( Type* type = NodeProperties::GetBounds(node->InputAt(2)).upper;
access.machine_type, node->set_op(machine()->Store(
ComputeWriteBarrierKind(access.base_is_tagged, access.machine_type, StoreRepresentation(access.machine_type,
node->InputAt(2))))); ComputeWriteBarrierKind(access.base_is_tagged,
access.machine_type, type))));
node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1))); node->ReplaceInput(1, ComputeIndex(access, node->InputAt(1)));
} }
......
...@@ -57,9 +57,6 @@ class SimplifiedLowering FINAL { ...@@ -57,9 +57,6 @@ class SimplifiedLowering FINAL {
Node* IsTagged(Node* node); Node* IsTagged(Node* node);
Node* Untag(Node* node); Node* Untag(Node* node);
Node* OffsetMinusTagConstant(int32_t offset); Node* OffsetMinusTagConstant(int32_t offset);
WriteBarrierKind ComputeWriteBarrierKind(BaseTaggedness base_is_tagged,
MachineType representation,
Node* value);
Node* ComputeIndex(const ElementAccess& access, Node* const key); Node* ComputeIndex(const ElementAccess& access, Node* const key);
Node* StringComparison(Node* node, bool requires_ordering); Node* StringComparison(Node* node, bool requires_ordering);
Node* Int32Div(Node* const node); Node* Int32Div(Node* const node);
......
...@@ -1616,16 +1616,15 @@ Bounds Typer::Visitor::TypeStringAdd(Node* node) { ...@@ -1616,16 +1616,15 @@ Bounds Typer::Visitor::TypeStringAdd(Node* node) {
} }
static Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) { namespace {
// TODO(neis): Enable when expressible.
/* Type* ChangeRepresentation(Type* type, Type* rep, Zone* zone) {
return Type::Union( return Type::Union(Type::Semantic(type, zone),
Type::Intersect(type, Type::Semantic(), zone), Type::Representation(rep, zone), zone);
Type::Intersect(rep, Type::Representation(), zone), zone);
*/
return type;
} }
} // namespace
Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) { Bounds Typer::Visitor::TypeChangeTaggedToInt32(Node* node) {
Bounds arg = Operand(node, 0); Bounds arg = Operand(node, 0);
...@@ -1657,9 +1656,12 @@ Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) { ...@@ -1657,9 +1656,12 @@ Bounds Typer::Visitor::TypeChangeTaggedToFloat64(Node* node) {
Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) { Bounds Typer::Visitor::TypeChangeInt32ToTagged(Node* node) {
Bounds arg = Operand(node, 0); Bounds arg = Operand(node, 0);
// TODO(neis): DCHECK(arg.upper->Is(Type::Signed32())); // TODO(neis): DCHECK(arg.upper->Is(Type::Signed32()));
return Bounds( Type* lower_rep = arg.lower->Is(Type::SignedSmall()) ? Type::TaggedSigned()
ChangeRepresentation(arg.lower, Type::Tagged(), zone()), : Type::Tagged();
ChangeRepresentation(arg.upper, Type::Tagged(), zone())); Type* upper_rep = arg.upper->Is(Type::SignedSmall()) ? Type::TaggedSigned()
: Type::Tagged();
return Bounds(ChangeRepresentation(arg.lower, lower_rep, zone()),
ChangeRepresentation(arg.upper, upper_rep, zone()));
} }
......
...@@ -1441,39 +1441,41 @@ TEST(LowerLoadField_to_load) { ...@@ -1441,39 +1441,41 @@ TEST(LowerLoadField_to_load) {
TEST(LowerStoreField_to_store) { TEST(LowerStoreField_to_store) {
TestingGraph t(Type::Any(), Type::Signed32()); {
TestingGraph t(Type::Any(), Type::Signed32());
for (size_t i = 0; i < arraysize(kMachineReps); i++) { for (size_t i = 0; i < arraysize(kMachineReps); i++) {
FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Handle<Name>::null(), Type::Any(), kMachineReps[i]}; Handle<Name>::null(), Type::Any(), kMachineReps[i]};
Node* val = t.ExampleWithOutput(kMachineReps[i]); Node* val = t.ExampleWithOutput(kMachineReps[i]);
Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
val, t.start, t.start); val, t.start, t.start);
t.Effect(store); t.Effect(store);
t.Lower(); t.Lower();
CHECK_EQ(IrOpcode::kStore, store->opcode()); CHECK_EQ(IrOpcode::kStore, store->opcode());
CHECK_EQ(val, store->InputAt(2)); CHECK_EQ(val, store->InputAt(2));
CheckFieldAccessArithmetic(access, store); CheckFieldAccessArithmetic(access, store);
StoreRepresentation rep = OpParameter<StoreRepresentation>(store); StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
if (kMachineReps[i] & kRepTagged) { if (kMachineReps[i] & kRepTagged) {
CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind()); CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
}
CHECK_EQ(kMachineReps[i], rep.machine_type());
} }
CHECK_EQ(kMachineReps[i], rep.machine_type());
} }
{
if (t.machine()->Is64()) { TestingGraph t(Type::Any(),
Type::Intersect(Type::SignedSmall(), Type::TaggedSigned()));
FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, FieldAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Handle<Name>::null(), Type::Any(), kMachAnyTagged}; Handle<Name>::null(), Type::Any(), kMachAnyTagged};
Node* val = t.graph()->NewNode(t.simplified()->ChangeInt32ToTagged(), t.p0);
Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0, Node* store = t.graph()->NewNode(t.simplified()->StoreField(access), t.p0,
val, t.start, t.start); t.p1, t.start, t.start);
t.Effect(store); t.Effect(store);
t.Lower(); t.Lower();
CHECK_EQ(IrOpcode::kStore, store->opcode()); CHECK_EQ(IrOpcode::kStore, store->opcode());
CHECK_EQ(val, store->InputAt(2)); CHECK_EQ(t.p1, store->InputAt(2));
StoreRepresentation rep = OpParameter<StoreRepresentation>(store); StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind()); CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind());
} }
...@@ -1503,26 +1505,42 @@ TEST(LowerLoadElement_to_load) { ...@@ -1503,26 +1505,42 @@ TEST(LowerLoadElement_to_load) {
TEST(LowerStoreElement_to_store) { TEST(LowerStoreElement_to_store) {
TestingGraph t(Type::Any(), Type::Signed32()); {
TestingGraph t(Type::Any(), Type::Signed32());
for (size_t i = 0; i < arraysize(kMachineReps); i++) { for (size_t i = 0; i < arraysize(kMachineReps); i++) {
ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize, ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Type::Any(), kMachineReps[i]}; Type::Any(), kMachineReps[i]};
Node* val = t.ExampleWithOutput(kMachineReps[i]);
Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access),
t.p0, t.p1, val, t.start, t.start);
t.Effect(store);
t.Lower();
CHECK_EQ(IrOpcode::kStore, store->opcode());
CHECK_EQ(val, store->InputAt(2));
CheckElementAccessArithmetic(access, store);
Node* val = t.ExampleWithOutput(kMachineReps[i]); StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
if (kMachineReps[i] & kRepTagged) {
CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
}
CHECK_EQ(kMachineReps[i], rep.machine_type());
}
}
{
TestingGraph t(Type::Any(), Type::Signed32(),
Type::Intersect(Type::SignedSmall(), Type::TaggedSigned()));
ElementAccess access = {kTaggedBase, FixedArrayBase::kHeaderSize,
Type::Any(), kMachAnyTagged};
Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0, Node* store = t.graph()->NewNode(t.simplified()->StoreElement(access), t.p0,
t.p1, val, t.start, t.start); t.p1, t.p2, t.start, t.start);
t.Effect(store); t.Effect(store);
t.Lower(); t.Lower();
CHECK_EQ(IrOpcode::kStore, store->opcode()); CHECK_EQ(IrOpcode::kStore, store->opcode());
CHECK_EQ(val, store->InputAt(2)); CHECK_EQ(t.p2, store->InputAt(2));
CheckElementAccessArithmetic(access, store);
StoreRepresentation rep = OpParameter<StoreRepresentation>(store); StoreRepresentation rep = OpParameter<StoreRepresentation>(store);
if (kMachineReps[i] & kRepTagged) { CHECK_EQ(kNoWriteBarrier, rep.write_barrier_kind());
CHECK_EQ(kFullWriteBarrier, rep.write_barrier_kind());
}
CHECK_EQ(kMachineReps[i], rep.machine_type());
} }
} }
......
...@@ -181,7 +181,7 @@ class ChangeLowering32Test : public ChangeLoweringTest { ...@@ -181,7 +181,7 @@ class ChangeLowering32Test : public ChangeLoweringTest {
TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) { TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) {
Node* val = Parameter(0); Node* val = Parameter(0);
Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val); Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
NodeProperties::SetBounds(val, Bounds(Type::None(), Type::Signed32())); NodeProperties::SetBounds(val, Bounds(Type::None(), Type::Integral32()));
Reduction reduction = Reduce(node); Reduction reduction = Reduce(node);
ASSERT_TRUE(reduction.Changed()); ASSERT_TRUE(reduction.Changed());
...@@ -209,7 +209,7 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) { ...@@ -209,7 +209,7 @@ TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTagged) {
TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTaggedSmall) { TARGET_TEST_F(ChangeLowering32Test, ChangeInt32ToTaggedSmall) {
Node* val = Parameter(0); Node* val = Parameter(0);
Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val); Node* node = graph()->NewNode(simplified()->ChangeInt32ToTagged(), val);
NodeProperties::SetBounds(val, Bounds(Type::None(), Type::Signed31())); NodeProperties::SetBounds(val, Bounds(Type::None(), Type::SignedSmall()));
Reduction reduction = Reduce(node); Reduction reduction = Reduce(node);
ASSERT_TRUE(reduction.Changed()); ASSERT_TRUE(reduction.Changed());
......
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