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