Commit 56429fc1 authored by mvstanton's avatar mvstanton Committed by Commit bot

[Turbofan]: Use new MachineTypes in access-builder.

Introduced MachineType::TaggedSigned() and TaggedPointer().

The idea is to quit using the representational dimension of Type, and
instead encode this information in the MachineRepresentation (itself
lightly wrapped in MachineType, along with MachineSemantic).

There are three parts to the whole change:

1) Places that set the machine representation - constant nodes, loads nad
   stores, global object and native context specialization.

2) Places that propagate type/representation - this is representation
   inference (aka simplified lowering). At the end of this process we
   expect to have a MachineRepresentation for every node. An interesting
   part of this is phi merging.

3) Places that examine representation - WriteBarrier elimination does this.
   Currently it's looking at the Type representation dimension, but as
   a part of this change (or in a soon-to-follow change) it can simply
   examine the MachineRepresentation.

BUG=

Review-Url: https://codereview.chromium.org/2258073002
Cr-Commit-Position: refs/heads/master@{#38978}
parent cad8e915
......@@ -230,7 +230,7 @@ FieldAccess AccessBuilder::ForJSArrayBufferViewBuffer() {
JSArrayBufferView::kBufferOffset,
MaybeHandle<Name>(),
Type::TaggedPointer(),
MachineType::AnyTagged(),
MachineType::TaggedPointer(),
kPointerWriteBarrier};
return access;
}
......@@ -366,7 +366,7 @@ FieldAccess AccessBuilder::ForDescriptorArrayEnumCache() {
DescriptorArray::kEnumCacheOffset,
Handle<Name>(),
Type::TaggedPointer(),
MachineType::AnyTagged(),
MachineType::TaggedPointer(),
kPointerWriteBarrier};
return access;
}
......@@ -378,7 +378,7 @@ FieldAccess AccessBuilder::ForDescriptorArrayEnumCacheBridgeCache() {
DescriptorArray::kEnumCacheBridgeCacheOffset,
Handle<Name>(),
Type::TaggedPointer(),
MachineType::AnyTagged(),
MachineType::TaggedPointer(),
kPointerWriteBarrier};
return access;
}
......@@ -404,9 +404,12 @@ FieldAccess AccessBuilder::ForMapBitField3() {
// static
FieldAccess AccessBuilder::ForMapDescriptors() {
FieldAccess access = {
kTaggedBase, Map::kDescriptorsOffset, Handle<Name>(),
Type::TaggedPointer(), MachineType::AnyTagged(), kPointerWriteBarrier};
FieldAccess access = {kTaggedBase,
Map::kDescriptorsOffset,
Handle<Name>(),
Type::TaggedPointer(),
MachineType::TaggedPointer(),
kPointerWriteBarrier};
return access;
}
......@@ -422,9 +425,12 @@ FieldAccess AccessBuilder::ForMapInstanceType() {
// static
FieldAccess AccessBuilder::ForMapPrototype() {
FieldAccess access = {
kTaggedBase, Map::kPrototypeOffset, Handle<Name>(),
Type::TaggedPointer(), MachineType::AnyTagged(), kPointerWriteBarrier};
FieldAccess access = {kTaggedBase,
Map::kPrototypeOffset,
Handle<Name>(),
Type::TaggedPointer(),
MachineType::TaggedPointer(),
kPointerWriteBarrier};
return access;
}
......@@ -610,9 +616,17 @@ FieldAccess AccessBuilder::ForPropertyCellValue() {
// static
FieldAccess AccessBuilder::ForPropertyCellValue(Type* type) {
// Extract representation dimension of {type} into MachineType {r}.
MachineType r = MachineType::AnyTagged();
WriteBarrierKind w = kFullWriteBarrier;
if (type->Is(Type::TaggedSigned())) {
r = MachineType::TaggedSigned();
w = kNoWriteBarrier;
} else if (type->Is(Type::TaggedPointer())) {
r = MachineType::TaggedPointer();
}
FieldAccess access = {
kTaggedBase, PropertyCell::kValueOffset, Handle<Name>(),
type, MachineType::AnyTagged(), kFullWriteBarrier};
kTaggedBase, PropertyCell::kValueOffset, Handle<Name>(), type, r, w};
return access;
}
......@@ -630,6 +644,7 @@ ElementAccess AccessBuilder::ForFixedArrayElement(ElementsKind kind) {
switch (kind) {
case FAST_SMI_ELEMENTS:
access.type = TypeCache::Get().kSmi;
access.machine_type = MachineType::TaggedSigned();
access.write_barrier_kind = kNoWriteBarrier;
break;
case FAST_HOLEY_SMI_ELEMENTS:
......
......@@ -424,7 +424,7 @@ void InstructionSelector::VisitStore(Node* node) {
MachineRepresentation rep = store_rep.representation();
if (write_barrier_kind != kNoWriteBarrier) {
DCHECK_EQ(MachineRepresentation::kTagged, rep);
DCHECK(CanBeTaggedPointer(rep));
AddressingMode addressing_mode;
InstructionOperand inputs[3];
size_t input_count = 0;
......
......@@ -606,7 +606,7 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(arm64): I guess this could be done in a better way.
if (write_barrier_kind != kNoWriteBarrier) {
DCHECK_EQ(MachineRepresentation::kTagged, rep);
DCHECK(CanBeTaggedPointer(rep));
AddressingMode addressing_mode;
InstructionOperand inputs[3];
size_t input_count = 0;
......
......@@ -820,7 +820,7 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
} else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
type == MachineType::Uint32()) {
translation->StoreUint32StackSlot(LocationOperand::cast(op)->index());
} else if (type.representation() == MachineRepresentation::kTagged) {
} else if (IsAnyTagged(type.representation())) {
translation->StoreStackSlot(LocationOperand::cast(op)->index());
} else {
CHECK(false);
......@@ -842,7 +842,7 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
} else if (type == MachineType::Uint8() || type == MachineType::Uint16() ||
type == MachineType::Uint32()) {
translation->StoreUint32Register(converter.ToRegister(op));
} else if (type.representation() == MachineRepresentation::kTagged) {
} else if (IsAnyTagged(type.representation())) {
translation->StoreRegister(converter.ToRegister(op));
} else {
CHECK(false);
......@@ -861,7 +861,8 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
Handle<Object> constant_object;
switch (constant.type()) {
case Constant::kInt32:
if (type.representation() == MachineRepresentation::kTagged) {
if (type.representation() == MachineRepresentation::kTagged ||
type.representation() == MachineRepresentation::kTaggedSigned) {
// When pointers are 4 bytes, we can use int32 constants to represent
// Smis.
DCHECK_EQ(4, kPointerSize);
......@@ -883,7 +884,8 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
case Constant::kInt64:
// When pointers are 8 bytes, we can use int64 constants to represent
// Smis.
DCHECK_EQ(type.representation(), MachineRepresentation::kTagged);
DCHECK(type.representation() == MachineRepresentation::kTagged ||
type.representation() == MachineRepresentation::kTaggedSigned);
DCHECK_EQ(8, kPointerSize);
constant_object =
handle(reinterpret_cast<Smi*>(constant.ToInt64()), isolate());
......@@ -891,16 +893,16 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
break;
case Constant::kFloat32:
DCHECK(type.representation() == MachineRepresentation::kFloat32 ||
type.representation() == MachineRepresentation::kTagged);
CanBeTaggedPointer(type.representation()));
constant_object = isolate()->factory()->NewNumber(constant.ToFloat32());
break;
case Constant::kFloat64:
DCHECK(type.representation() == MachineRepresentation::kFloat64 ||
type.representation() == MachineRepresentation::kTagged);
CanBeTaggedPointer(type.representation()));
constant_object = isolate()->factory()->NewNumber(constant.ToFloat64());
break;
case Constant::kHeapObject:
DCHECK(type.representation() == MachineRepresentation::kTagged);
DCHECK(CanBeTaggedPointer(type.representation()));
constant_object = constant.ToHeapObject();
break;
default:
......
......@@ -262,7 +262,7 @@ void InstructionSelector::VisitStore(Node* node) {
MachineRepresentation rep = store_rep.representation();
if (write_barrier_kind != kNoWriteBarrier) {
DCHECK_EQ(MachineRepresentation::kTagged, rep);
DCHECK(CanBeTaggedPointer(rep));
AddressingMode addressing_mode;
InstructionOperand inputs[3];
size_t input_count = 0;
......
......@@ -1340,8 +1340,7 @@ class InstructionSequence final : public ZoneObject {
void MarkAsRepresentation(MachineRepresentation rep, int virtual_register);
bool IsReference(int virtual_register) const {
return GetRepresentation(virtual_register) ==
MachineRepresentation::kTagged;
return CanBeTaggedPointer(GetRepresentation(virtual_register));
}
bool IsFP(int virtual_register) const {
return IsFloatingPoint(GetRepresentation(virtual_register));
......
......@@ -37,9 +37,11 @@ MachineType reptyp(Representation representation) {
case Representation::kInteger32:
return MachineType::Int32();
case Representation::kSmi:
return MachineType::TaggedSigned();
case Representation::kTagged:
case Representation::kHeapObject:
return MachineType::AnyTagged();
case Representation::kHeapObject:
return MachineType::TaggedPointer();
case Representation::kDouble:
return MachineType::Float64();
case Representation::kExternal:
......
......@@ -422,6 +422,8 @@ MachineRepresentation AtomicStoreRepresentationOf(Operator const* op) {
V(Int64) \
V(Uint64) \
V(Pointer) \
V(TaggedSigned) \
V(TaggedPointer) \
V(AnyTagged)
#define MACHINE_REPRESENTATION_LIST(V) \
......
......@@ -198,7 +198,7 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(mips): I guess this could be done in a better way.
if (write_barrier_kind != kNoWriteBarrier) {
DCHECK_EQ(MachineRepresentation::kTagged, rep);
DCHECK(CanBeTaggedPointer(rep));
InstructionOperand inputs[3];
size_t input_count = 0;
inputs[input_count++] = g.UseUniqueRegister(base);
......
......@@ -212,7 +212,7 @@ void InstructionSelector::VisitStore(Node* node) {
// TODO(mips): I guess this could be done in a better way.
if (write_barrier_kind != kNoWriteBarrier) {
DCHECK_EQ(MachineRepresentation::kTagged, rep);
DCHECK(CanBeTaggedPointer(rep));
InstructionOperand inputs[3];
size_t input_count = 0;
inputs[input_count++] = g.UseUniqueRegister(base);
......
......@@ -3273,8 +3273,8 @@ void ReferenceMapPopulator::PopulateReferenceMaps() {
spill_operand = range->GetSpillRangeOperand();
}
DCHECK(spill_operand.IsStackSlot());
DCHECK_EQ(MachineRepresentation::kTagged,
AllocatedOperand::cast(spill_operand).representation());
DCHECK(CanBeTaggedPointer(
AllocatedOperand::cast(spill_operand).representation()));
}
LiveRange* cur = range;
......@@ -3336,8 +3336,8 @@ void ReferenceMapPopulator::PopulateReferenceMaps() {
safe_point);
InstructionOperand operand = cur->GetAssignedOperand();
DCHECK(!operand.IsStackSlot());
DCHECK_EQ(MachineRepresentation::kTagged,
AllocatedOperand::cast(operand).representation());
DCHECK(CanBeTaggedPointer(
AllocatedOperand::cast(operand).representation()));
map->RecordReference(AllocatedOperand::cast(operand));
}
}
......
......@@ -142,7 +142,11 @@ Node* RepresentationChanger::GetRepresentationFor(
switch (use_info.representation()) {
case MachineRepresentation::kTaggedSigned:
DCHECK(use_info.type_check() == TypeCheckKind::kNone);
return GetTaggedSignedRepresentationFor(node, output_rep, output_type);
case MachineRepresentation::kTaggedPointer:
DCHECK(use_info.type_check() == TypeCheckKind::kNone);
return GetTaggedPointerRepresentationFor(node, output_rep, output_type);
case MachineRepresentation::kTagged:
DCHECK(use_info.type_check() == TypeCheckKind::kNone);
return GetTaggedRepresentationFor(node, output_rep, output_type);
......@@ -174,6 +178,89 @@ Node* RepresentationChanger::GetRepresentationFor(
return nullptr;
}
Node* RepresentationChanger::GetTaggedSignedRepresentationFor(
Node* node, MachineRepresentation output_rep, Type* output_type) {
// Eagerly fold representation changes for constants.
switch (node->opcode()) {
case IrOpcode::kNumberConstant: {
int32_t value = OpParameter<int32_t>(node);
if (Smi::IsValid(value)) {
return jsgraph()->Constant(value);
}
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
}
case IrOpcode::kHeapConstant:
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
case IrOpcode::kInt32Constant:
if (output_type->Is(Type::SignedSmall())) {
int32_t value = OpParameter<int32_t>(node);
return jsgraph()->Constant(value);
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
}
case IrOpcode::kFloat64Constant:
case IrOpcode::kFloat32Constant:
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
default:
break;
}
// Select the correct X -> Tagged operator.
const Operator* op;
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Constant(0);
} else if (IsWord(output_rep)) {
if (output_type->Is(Type::Signed31())) {
op = simplified()->ChangeInt31ToTaggedSigned();
} else if (machine()->Is64() && output_type->Is(Type::Signed32())) {
op = simplified()->ChangeInt32ToTagged();
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
}
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedSigned);
}
return jsgraph()->graph()->NewNode(op, node);
}
Node* RepresentationChanger::GetTaggedPointerRepresentationFor(
Node* node, MachineRepresentation output_rep, Type* output_type) {
// Eagerly fold representation changes for constants.
switch (node->opcode()) {
case IrOpcode::kHeapConstant:
return node; // No change necessary.
case IrOpcode::kInt32Constant:
if (output_type->Is(Type::Boolean())) {
return OpParameter<int32_t>(node) == 0 ? jsgraph()->FalseConstant()
: jsgraph()->TrueConstant();
} else {
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedPointer);
}
case IrOpcode::kFloat64Constant:
case IrOpcode::kFloat32Constant:
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedPointer);
default:
break;
}
// Select the correct X -> Tagged operator.
if (output_type->Is(Type::None())) {
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->TheHoleConstant();
}
return TypeError(node, output_rep, output_type,
MachineRepresentation::kTaggedPointer);
}
Node* RepresentationChanger::GetTaggedRepresentationFor(
Node* node, MachineRepresentation output_rep, Type* output_type) {
// Eagerly fold representation changes for constants.
......@@ -202,6 +289,11 @@ Node* RepresentationChanger::GetTaggedRepresentationFor(
default:
break;
}
if (output_rep == MachineRepresentation::kTaggedSigned ||
output_rep == MachineRepresentation::kTaggedPointer) {
// this is a no-op.
return node;
}
// Select the correct X -> Tagged operator.
const Operator* op;
if (output_type->Is(Type::None())) {
......@@ -303,7 +395,8 @@ Node* RepresentationChanger::GetFloat32RepresentationFor(
node = jsgraph()->graph()->NewNode(op, node);
op = machine()->TruncateFloat64ToFloat32();
}
} else if (output_rep == MachineRepresentation::kTagged) {
} else if (output_rep == MachineRepresentation::kTagged ||
output_rep == MachineRepresentation::kTaggedPointer) {
if (output_type->Is(Type::NumberOrOddball())) {
// tagged -> float64 -> float32
if (output_type->Is(Type::Number())) {
......@@ -367,7 +460,9 @@ Node* RepresentationChanger::GetFloat64RepresentationFor(
}
} else if (output_rep == MachineRepresentation::kBit) {
op = machine()->ChangeUint32ToFloat64();
} else if (output_rep == MachineRepresentation::kTagged) {
} else if (output_rep == MachineRepresentation::kTagged ||
output_rep == MachineRepresentation::kTaggedSigned ||
output_rep == MachineRepresentation::kTaggedPointer) {
if (output_type->Is(Type::Undefined())) {
return jsgraph()->Float64Constant(
std::numeric_limits<double>::quiet_NaN());
......@@ -470,10 +565,19 @@ Node* RepresentationChanger::GetWord32RepresentationFor(
? CheckForMinusZeroMode::kCheckForMinusZero
: CheckForMinusZeroMode::kDontCheckForMinusZero);
}
} else if (output_rep == MachineRepresentation::kTagged) {
if (output_type->Is(Type::TaggedSigned())) {
} else if (output_rep == MachineRepresentation::kTaggedSigned) {
if (output_type->Is(Type::Signed32())) {
op = simplified()->ChangeTaggedSignedToInt32();
} else if (output_type->Is(Type::Unsigned32())) {
} else if (use_info.truncation().IsUsedAsWord32()) {
if (use_info.type_check() != TypeCheckKind::kNone) {
op = simplified()->CheckedTruncateTaggedToWord32();
} else {
op = simplified()->TruncateTaggedToWord32();
}
}
} else if (output_rep == MachineRepresentation::kTagged ||
output_rep == MachineRepresentation::kTaggedPointer) {
if (output_type->Is(Type::Unsigned32())) {
op = simplified()->ChangeTaggedToUint32();
} else if (output_type->Is(Type::Signed32())) {
op = simplified()->ChangeTaggedToInt32();
......@@ -555,7 +659,9 @@ Node* RepresentationChanger::GetBitRepresentationFor(
// This is an impossible value; it should not be used at runtime.
// We just provide a dummy value here.
return jsgraph()->Int32Constant(0);
} else if (output_rep == MachineRepresentation::kTagged) {
} else if (output_rep == MachineRepresentation::kTagged ||
output_rep == MachineRepresentation::kTaggedSigned ||
output_rep == MachineRepresentation::kTaggedPointer) {
op = simplified()->ChangeTaggedToBit();
} else {
return TypeError(node, output_rep, output_type,
......
......@@ -232,6 +232,12 @@ class RepresentationChanger final {
bool testing_type_errors_; // If {true}, don't abort on a type error.
bool type_error_; // Set when a type error is detected.
Node* GetTaggedSignedRepresentationFor(Node* node,
MachineRepresentation output_rep,
Type* output_type);
Node* GetTaggedPointerRepresentationFor(Node* node,
MachineRepresentation output_rep,
Type* output_type);
Node* GetTaggedRepresentationFor(Node* node, MachineRepresentation output_rep,
Type* output_type);
Node* GetFloat32RepresentationFor(Node* node,
......
......@@ -1031,7 +1031,7 @@ class RepresentationSelector {
MachineRepresentation field_representation, Type* field_type,
Node* value) {
if (base_taggedness == kTaggedBase &&
field_representation == MachineRepresentation::kTagged) {
CanBeTaggedPointer(field_representation)) {
Type* value_type = NodeProperties::GetType(value);
if (field_type->Is(Type::TaggedSigned()) ||
value_type->Is(Type::TaggedSigned())) {
......
......@@ -212,7 +212,7 @@ void InstructionSelector::VisitStore(Node* node) {
MachineRepresentation rep = store_rep.representation();
if (write_barrier_kind != kNoWriteBarrier) {
DCHECK_EQ(MachineRepresentation::kTagged, rep);
DCHECK(CanBeTaggedPointer(rep));
AddressingMode addressing_mode;
InstructionOperand inputs[3];
size_t input_count = 0;
......
......@@ -119,6 +119,14 @@ class MachineType {
return MachineType(MachineRepresentation::kWord64,
MachineSemantic::kUint64);
}
static MachineType TaggedPointer() {
return MachineType(MachineRepresentation::kTaggedPointer,
MachineSemantic::kAny);
}
static MachineType TaggedSigned() {
return MachineType(MachineRepresentation::kTaggedSigned,
MachineSemantic::kInt32);
}
static MachineType AnyTagged() {
return MachineType(MachineRepresentation::kTagged, MachineSemantic::kAny);
}
......@@ -214,6 +222,15 @@ inline bool IsFloatingPoint(MachineRepresentation rep) {
rep == MachineRepresentation::kSimd128;
}
inline bool CanBeTaggedPointer(MachineRepresentation rep) {
return rep == MachineRepresentation::kTagged ||
rep == MachineRepresentation::kTaggedPointer;
}
inline bool IsAnyTagged(MachineRepresentation rep) {
return CanBeTaggedPointer(rep) || rep == MachineRepresentation::kTaggedSigned;
}
// Gets the log2 of the element size in bytes of the machine type.
inline int ElementSizeLog2Of(MachineRepresentation rep) {
switch (rep) {
......
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