[ptr-compr][turbofan] Tagged to Compressed representation and type changes
This is the first CL that aims to eliminate the straggler tagged loads and
stores.
Cq-Include-Trybots: luci.v8.try:v8_linux64_pointer_compression_rel_ng
Cq-Include-Trybots: luci.v8.try:v8_linux64_arm64_pointer_compression_rel_ng
Bug: v8:8977, v8:7703
Change-Id: If3782c0c7047d4c7d8669e12fb423cc0c74bc58a
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1587392
Reviewed-by: Michael Stanton <mvstanton@chromium.org>
Reviewed-by: Jaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61180}
diff --git a/src/compiler/backend/instruction-selector.cc b/src/compiler/backend/instruction-selector.cc
index 5cbc5d5..704dccf 100644
--- a/src/compiler/backend/instruction-selector.cc
+++ b/src/compiler/backend/instruction-selector.cc
@@ -458,7 +458,7 @@
case IrOpcode::kDelayedStringConstant:
return g->UseImmediate(input);
case IrOpcode::kHeapConstant: {
- if (!CanBeTaggedPointer(rep)) {
+ if (!CanBeTaggedOrCompressedPointer(rep)) {
// If we have inconsistent static and dynamic types, e.g. if we
// smi-check a string, we can get here with a heap object that
// says it is a smi. In that case, we return an invalid instruction
diff --git a/src/compiler/js-native-context-specialization.cc b/src/compiler/js-native-context-specialization.cc
index ef71f8f..07c76b2 100644
--- a/src/compiler/js-native-context-specialization.cc
+++ b/src/compiler/js-native-context-specialization.cc
@@ -768,9 +768,11 @@
Type type, MaybeHandle<Map> map,
NameRef const& name) {
WriteBarrierKind kind = kFullWriteBarrier;
- if (representation == MachineRepresentation::kTaggedSigned) {
+ if (representation == MachineRepresentation::kTaggedSigned ||
+ representation == MachineRepresentation::kCompressedSigned) {
kind = kNoWriteBarrier;
- } else if (representation == MachineRepresentation::kTaggedPointer) {
+ } else if (representation == MachineRepresentation::kTaggedPointer ||
+ representation == MachineRepresentation::kCompressedPointer) {
kind = kPointerWriteBarrier;
}
MachineType r = MachineType::TypeForRepresentation(representation);
@@ -882,20 +884,21 @@
// Load from constant type cell can benefit from type feedback.
MaybeHandle<Map> map;
Type property_cell_value_type = Type::NonInternal();
- MachineRepresentation representation = MachineRepresentation::kTagged;
+ MachineRepresentation representation =
+ MachineType::RepCompressedTagged();
if (property_details.cell_type() == PropertyCellType::kConstantType) {
// Compute proper type based on the current value in the cell.
if (property_cell_value.IsSmi()) {
property_cell_value_type = Type::SignedSmall();
- representation = MachineRepresentation::kTaggedSigned;
+ representation = MachineType::RepCompressedTaggedSigned();
} else if (property_cell_value.IsHeapNumber()) {
property_cell_value_type = Type::Number();
- representation = MachineRepresentation::kTaggedPointer;
+ representation = MachineType::RepCompressedTaggedPointer();
} else {
MapRef property_cell_value_map =
property_cell_value.AsHeapObject().map();
property_cell_value_type = Type::For(property_cell_value_map);
- representation = MachineRepresentation::kTaggedPointer;
+ representation = MachineType::RepCompressedTaggedPointer();
// We can only use the property cell value map for map check
// elimination if it's stable, i.e. the HeapObject wasn't
@@ -938,7 +941,8 @@
// cell.
dependencies()->DependOnGlobalProperty(property_cell);
Type property_cell_value_type;
- MachineRepresentation representation = MachineRepresentation::kTagged;
+ MachineRepresentation representation =
+ MachineType::RepCompressedTagged();
if (property_cell_value.IsHeapObject()) {
// We cannot do anything if the {property_cell_value}s map is no
// longer stable.
@@ -957,13 +961,13 @@
ZoneHandleSet<Map>(property_cell_value_map.object())),
value, effect, control);
property_cell_value_type = Type::OtherInternal();
- representation = MachineRepresentation::kTaggedPointer;
+ representation = MachineType::RepCompressedTaggedPointer();
} else {
// Check that the {value} is a Smi.
value = effect = graph()->NewNode(
simplified()->CheckSmi(VectorSlotPair()), value, effect, control);
property_cell_value_type = Type::SignedSmall();
- representation = MachineRepresentation::kTaggedSigned;
+ representation = MachineType::RepCompressedTaggedSigned();
}
effect = graph()->NewNode(simplified()->StoreField(ForPropertyCellValue(
representation, property_cell_value_type,
@@ -978,7 +982,7 @@
dependencies()->DependOnGlobalProperty(property_cell);
effect = graph()->NewNode(
simplified()->StoreField(ForPropertyCellValue(
- MachineRepresentation::kTagged, Type::NonInternal(),
+ MachineType::RepCompressedTagged(), Type::NonInternal(),
MaybeHandle<Map>(), name)),
jsgraph()->Constant(property_cell), value, effect, control);
break;
@@ -2269,14 +2273,18 @@
value = effect = a.Finish();
field_access.type = Type::Any();
- field_access.machine_type = MachineType::TaggedPointer();
+ field_access.machine_type =
+ MachineType::TypeCompressedTaggedPointer();
field_access.write_barrier_kind = kPointerWriteBarrier;
} else {
// We just store directly to the MutableHeapNumber.
FieldAccess const storage_access = {
- kTaggedBase, field_index.offset(),
- name.object(), MaybeHandle<Map>(),
- Type::OtherInternal(), MachineType::TaggedPointer(),
+ kTaggedBase,
+ field_index.offset(),
+ name.object(),
+ MaybeHandle<Map>(),
+ Type::OtherInternal(),
+ MachineType::TypeCompressedTaggedPointer(),
kPointerWriteBarrier};
storage = effect =
graph()->NewNode(simplified()->LoadField(storage_access),
@@ -2815,13 +2823,13 @@
// Compute the element access.
Type element_type = Type::NonInternal();
- MachineType element_machine_type = MachineType::AnyTagged();
+ MachineType element_machine_type = MachineType::TypeCompressedTagged();
if (IsDoubleElementsKind(elements_kind)) {
element_type = Type::Number();
element_machine_type = MachineType::Float64();
} else if (IsSmiElementsKind(elements_kind)) {
element_type = Type::SignedSmall();
- element_machine_type = MachineType::TaggedSigned();
+ element_machine_type = MachineType::TypeCompressedTaggedSigned();
}
ElementAccess element_access = {
kTaggedBase, FixedArray::kHeaderSize,
@@ -2838,7 +2846,7 @@
}
if (elements_kind == HOLEY_ELEMENTS ||
elements_kind == HOLEY_SMI_ELEMENTS) {
- element_access.machine_type = MachineType::AnyTagged();
+ element_access.machine_type = MachineType::TypeCompressedTagged();
}
// Check if we can return undefined for out-of-bounds loads.
@@ -2946,7 +2954,7 @@
if (elements_kind == HOLEY_ELEMENTS ||
elements_kind == HOLEY_SMI_ELEMENTS) {
- element_access.machine_type = MachineType::AnyTagged();
+ element_access.machine_type = MachineType::TypeCompressedTagged();
}
Node* if_true = graph()->NewNode(common()->IfTrue(), branch);
diff --git a/src/compiler/load-elimination.cc b/src/compiler/load-elimination.cc
index 468ef20..29810d6 100644
--- a/src/compiler/load-elimination.cc
+++ b/src/compiler/load-elimination.cc
@@ -798,7 +798,7 @@
if (state == nullptr) return NoChange();
if (access.offset == HeapObject::kMapOffset &&
access.base_is_tagged == kTaggedBase) {
- DCHECK(IsAnyTagged(access.machine_type.representation()));
+ DCHECK(IsAnyCompressedTagged(access.machine_type.representation()));
ZoneHandleSet<Map> object_maps;
if (state->LookupMaps(object, &object_maps) && object_maps.size() == 1) {
Node* value = jsgraph()->HeapConstant(object_maps[0]);
@@ -847,7 +847,7 @@
if (state == nullptr) return NoChange();
if (access.offset == HeapObject::kMapOffset &&
access.base_is_tagged == kTaggedBase) {
- DCHECK(IsAnyTagged(access.machine_type.representation()));
+ DCHECK(IsAnyCompressedTagged(access.machine_type.representation()));
// Kill all potential knowledge about the {object}s map.
state = state->KillMaps(object, zone());
Type const new_value_type = NodeProperties::GetType(new_value);
@@ -890,12 +890,6 @@
switch (access.machine_type.representation()) {
case MachineRepresentation::kNone:
case MachineRepresentation::kBit:
- // TODO(solanes): Create the code for the compressed values
- case MachineRepresentation::kCompressedSigned:
- case MachineRepresentation::kCompressedPointer:
- case MachineRepresentation::kCompressed:
- UNREACHABLE();
- break;
case MachineRepresentation::kWord8:
case MachineRepresentation::kWord16:
case MachineRepresentation::kWord32:
@@ -908,6 +902,9 @@
case MachineRepresentation::kTaggedSigned:
case MachineRepresentation::kTaggedPointer:
case MachineRepresentation::kTagged:
+ case MachineRepresentation::kCompressedSigned:
+ case MachineRepresentation::kCompressedPointer:
+ case MachineRepresentation::kCompressed:
if (Node* replacement = state->LookupElement(
object, index, access.machine_type.representation())) {
// Make sure we don't resurrect dead {replacement} nodes.
@@ -948,12 +945,6 @@
switch (access.machine_type.representation()) {
case MachineRepresentation::kNone:
case MachineRepresentation::kBit:
- // TODO(solanes): Create the code for the compressed values
- case MachineRepresentation::kCompressedSigned:
- case MachineRepresentation::kCompressedPointer:
- case MachineRepresentation::kCompressed:
- UNREACHABLE();
- break;
case MachineRepresentation::kWord8:
case MachineRepresentation::kWord16:
case MachineRepresentation::kWord32:
@@ -966,6 +957,9 @@
case MachineRepresentation::kTaggedSigned:
case MachineRepresentation::kTaggedPointer:
case MachineRepresentation::kTagged:
+ case MachineRepresentation::kCompressedSigned:
+ case MachineRepresentation::kCompressedPointer:
+ case MachineRepresentation::kCompressed:
state = state->AddElement(object, index, new_value,
access.machine_type.representation(), zone());
break;
diff --git a/src/compiler/memory-optimizer.cc b/src/compiler/memory-optimizer.cc
index d375d77..7aec86a 100644
--- a/src/compiler/memory-optimizer.cc
+++ b/src/compiler/memory-optimizer.cc
@@ -467,13 +467,13 @@
ElementAccess const& access = ElementAccessOf(node->op());
Node* index = node->InputAt(1);
node->ReplaceInput(1, ComputeIndex(access, index));
+ MachineType type = access.machine_type;
if (NeedsPoisoning(access.load_sensitivity) &&
- access.machine_type.representation() !=
- MachineRepresentation::kTaggedPointer) {
- NodeProperties::ChangeOp(node,
- machine()->PoisonedLoad(access.machine_type));
+ type.representation() != MachineRepresentation::kTaggedPointer &&
+ type.representation() != MachineRepresentation::kCompressedPointer) {
+ NodeProperties::ChangeOp(node, machine()->PoisonedLoad(type));
} else {
- NodeProperties::ChangeOp(node, machine()->Load(access.machine_type));
+ NodeProperties::ChangeOp(node, machine()->Load(type));
}
EnqueueUses(node, state);
}
@@ -483,13 +483,13 @@
FieldAccess const& access = FieldAccessOf(node->op());
Node* offset = jsgraph()->IntPtrConstant(access.offset - access.tag());
node->InsertInput(graph()->zone(), 1, offset);
+ MachineType type = access.machine_type;
if (NeedsPoisoning(access.load_sensitivity) &&
- access.machine_type.representation() !=
- MachineRepresentation::kTaggedPointer) {
- NodeProperties::ChangeOp(node,
- machine()->PoisonedLoad(access.machine_type));
+ type.representation() != MachineRepresentation::kTaggedPointer &&
+ type.representation() != MachineRepresentation::kCompressedPointer) {
+ NodeProperties::ChangeOp(node, machine()->PoisonedLoad(type));
} else {
- NodeProperties::ChangeOp(node, machine()->Load(access.machine_type));
+ NodeProperties::ChangeOp(node, machine()->Load(type));
}
EnqueueUses(node, state);
}
diff --git a/src/compiler/simplified-lowering.cc b/src/compiler/simplified-lowering.cc
index ad3e114..9d066bd 100644
--- a/src/compiler/simplified-lowering.cc
+++ b/src/compiler/simplified-lowering.cc
@@ -2803,9 +2803,10 @@
access.machine_type.representation();
// Convert to Smi if possible, such that we can avoid a write barrier.
- if (field_representation == MachineRepresentation::kTagged &&
+ if ((field_representation == MachineRepresentation::kTagged ||
+ field_representation == MachineRepresentation::kCompressed) &&
TypeOf(value_node).Is(Type::SignedSmall())) {
- field_representation = MachineRepresentation::kTaggedSigned;
+ field_representation = MachineType::RepCompressedTaggedSigned();
}
WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
access.base_is_tagged, field_representation, access.offset,
@@ -2845,9 +2846,10 @@
access.machine_type.representation();
// Convert to Smi if possible, such that we can avoid a write barrier.
- if (element_representation == MachineRepresentation::kTagged &&
+ if ((element_representation == MachineRepresentation::kTagged ||
+ element_representation == MachineRepresentation::kCompressed) &&
TypeOf(value_node).Is(Type::SignedSmall())) {
- element_representation = MachineRepresentation::kTaggedSigned;
+ element_representation = MachineType::RepCompressedTaggedSigned();
}
WriteBarrierKind write_barrier_kind = WriteBarrierKindFor(
access.base_is_tagged, element_representation, access.type,
diff --git a/src/machine-type.h b/src/machine-type.h
index 73e9780..0eddf6c 100644
--- a/src/machine-type.h
+++ b/src/machine-type.h
@@ -235,6 +235,77 @@
return MachineType(MachineRepresentation::kBit, MachineSemantic::kNone);
}
+ // These methods return compressed representations when the compressed
+ // pointer flag is enabled. Otherwise, they returned the corresponding tagged
+ // one.
+ constexpr static MachineRepresentation RepCompressedTagged() {
+#ifdef V8_COMPRESS_POINTERS
+ return MachineRepresentation::kCompressed;
+#else
+ return MachineRepresentation::kTagged;
+#endif
+ }
+ constexpr static MachineRepresentation RepCompressedTaggedSigned() {
+#ifdef V8_COMPRESS_POINTERS
+ return MachineRepresentation::kCompressedSigned;
+#else
+ return MachineRepresentation::kTaggedSigned;
+#endif
+ }
+ constexpr static MachineRepresentation RepCompressedTaggedPointer() {
+#ifdef V8_COMPRESS_POINTERS
+ return MachineRepresentation::kCompressedPointer;
+#else
+ return MachineRepresentation::kTaggedPointer;
+#endif
+ }
+
+ constexpr static MachineType TypeCompressedTagged() {
+#ifdef V8_COMPRESS_POINTERS
+ return MachineType::AnyCompressed();
+#else
+ return MachineType::AnyTagged();
+#endif
+ }
+ constexpr static MachineType TypeCompressedTaggedSigned() {
+#ifdef V8_COMPRESS_POINTERS
+ return MachineType::CompressedSigned();
+#else
+ return MachineType::TaggedSigned();
+#endif
+ }
+ constexpr static MachineType TypeCompressedTaggedPointer() {
+#ifdef V8_COMPRESS_POINTERS
+ return MachineType::CompressedPointer();
+#else
+ return MachineType::TaggedPointer();
+#endif
+ }
+
+ constexpr bool IsCompressedTagged() const {
+#ifdef V8_COMPRESS_POINTERS
+ return IsCompressed();
+#else
+ return IsTagged();
+#endif
+ }
+
+ constexpr bool IsCompressedTaggedSigned() const {
+#ifdef V8_COMPRESS_POINTERS
+ return IsCompressedSigned();
+#else
+ return IsTaggedSigned();
+#endif
+ }
+
+ constexpr bool IsCompressedTaggedPointer() const {
+#ifdef V8_COMPRESS_POINTERS
+ return IsCompressedPointer();
+#else
+ return IsTaggedPointer();
+#endif
+ }
+
static MachineType TypeForRepresentation(const MachineRepresentation& rep,
bool isSigned = true) {
switch (rep) {
@@ -333,6 +404,16 @@
rep == MachineRepresentation::kCompressedSigned;
}
+// TODO(solanes): remove '|| IsAnyTagged(rep)' when all the representation
+// changes are in place
+inline bool IsAnyCompressedTagged(MachineRepresentation rep) {
+#ifdef V8_COMPRESS_POINTERS
+ return IsAnyCompressed(rep) || IsAnyTagged(rep);
+#else
+ return IsAnyTagged(rep);
+#endif
+}
+
// Gets the log2 of the element size in bytes of the machine type.
V8_EXPORT_PRIVATE inline int ElementSizeLog2Of(MachineRepresentation rep) {
switch (rep) {