Commit af1b77b1 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[ptr-compr][Turbofan] Adding the TypedStateValues decompress reduction

Decompressions before TypedStateValues can be safely skipped since
TypedStateValues always decompresses values.

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: Ic3d43c21183c0decda123cb377706ee5c3c12f87
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1617939
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61738}
parent dcf881de
...@@ -78,6 +78,21 @@ Reduction DecompressionElimination::ReduceCompress(Node* node) { ...@@ -78,6 +78,21 @@ Reduction DecompressionElimination::ReduceCompress(Node* node) {
} }
} }
Reduction DecompressionElimination::ReduceTypedStateValues(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kTypedStateValues);
bool any_change = false;
for (int i = 0; i < node->InputCount(); ++i) {
Node* input = node->InputAt(i);
if (IrOpcode::IsDecompressOpcode(input->opcode())) {
DCHECK_EQ(input->InputCount(), 1);
node->ReplaceInput(i, input->InputAt(0));
any_change = true;
}
}
return any_change ? Changed(node) : NoChange();
}
Reduction DecompressionElimination::ReduceWord64Equal(Node* node) { Reduction DecompressionElimination::ReduceWord64Equal(Node* node) {
DCHECK_EQ(node->opcode(), IrOpcode::kWord64Equal); DCHECK_EQ(node->opcode(), IrOpcode::kWord64Equal);
...@@ -123,6 +138,8 @@ Reduction DecompressionElimination::Reduce(Node* node) { ...@@ -123,6 +138,8 @@ Reduction DecompressionElimination::Reduce(Node* node) {
case IrOpcode::kChangeTaggedSignedToCompressedSigned: case IrOpcode::kChangeTaggedSignedToCompressedSigned:
case IrOpcode::kChangeTaggedPointerToCompressedPointer: case IrOpcode::kChangeTaggedPointerToCompressedPointer:
return ReduceCompress(node); return ReduceCompress(node);
case IrOpcode::kTypedStateValues:
return ReduceTypedStateValues(node);
case IrOpcode::kWord64Equal: case IrOpcode::kWord64Equal:
return ReduceWord64Equal(node); return ReduceWord64Equal(node);
default: default:
......
...@@ -48,6 +48,9 @@ class V8_EXPORT_PRIVATE DecompressionElimination final ...@@ -48,6 +48,9 @@ class V8_EXPORT_PRIVATE DecompressionElimination final
// Can be used for Any, Signed, and Pointer compressions. // Can be used for Any, Signed, and Pointer compressions.
Reduction ReduceCompress(Node* node); Reduction ReduceCompress(Node* node);
// Replaces TypedStateValues's input decompressions with their parent node.
Reduction ReduceTypedStateValues(Node* node);
// Replaces a Word64Equal with a Word32Equal if both of its inputs are // Replaces a Word64Equal with a Word32Equal if both of its inputs are
// Decompress nodes, or if one is a Decompress node and the other a constant. // Decompress nodes, or if one is a Decompress node and the other a constant.
// In the case of two decompresses, it uses the original inputs before they // In the case of two decompresses, it uses the original inputs before they
......
...@@ -250,6 +250,203 @@ TEST_F(DecompressionEliminationTest, ...@@ -250,6 +250,203 @@ TEST_F(DecompressionEliminationTest,
EXPECT_EQ(load, r.replacement()); EXPECT_EQ(load, r.replacement());
} }
// -----------------------------------------------------------------------------
// TypedStateValues
TEST_F(DecompressionEliminationTest, TypedStateValuesOneDecompress) {
// Skip test if pointer compression is not enabled
if (!COMPRESS_POINTERS_BOOL) {
return;
}
// Define variables
Node* const control = graph()->start();
Node* object = Parameter(Type::Any(), 0);
Node* effect = graph()->start();
Node* index = Parameter(Type::UnsignedSmall(), 1);
const int numberOfInputs = 1;
const ZoneVector<MachineType>* types =
new (graph()->zone()->New(sizeof(ZoneVector<MachineType>)))
ZoneVector<MachineType>(numberOfInputs, graph()->zone());
SparseInputMask dense = SparseInputMask::Dense();
const ElementAccess ElementAccesses[] = {
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::AnyTagged(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::TaggedSigned(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::TaggedPointer(),
kNoWriteBarrier}};
// For every access
for (size_t i = 0; i < arraysize(ElementAccesses); ++i) {
// Create the graph
Node* load = graph()->NewNode(simplified()->LoadElement(ElementAccesses[i]),
object, index, effect, control);
Node* changeToTagged = graph()->NewNode(
machine()->ChangeCompressedPointerToTaggedPointer(), load);
Node* typedStateValuesOneDecompress = graph()->NewNode(
common()->TypedStateValues(types, dense), changeToTagged);
// Reduce
StrictMock<MockAdvancedReducerEditor> editor;
DecompressionElimination decompression_elimination(&editor, graph(),
machine(), common());
Reduction r =
decompression_elimination.Reduce(typedStateValuesOneDecompress);
ASSERT_TRUE(r.Changed());
}
}
TEST_F(DecompressionEliminationTest, TypedStateValuesTwoDecompresses) {
// Skip test if pointer compression is not enabled
if (!COMPRESS_POINTERS_BOOL) {
return;
}
// Define variables
Node* const control = graph()->start();
Node* object = Parameter(Type::Any(), 0);
Node* effect = graph()->start();
Node* index = Parameter(Type::UnsignedSmall(), 1);
const int numberOfInputs = 3;
const ZoneVector<MachineType>* types =
new (graph()->zone()->New(sizeof(ZoneVector<MachineType>)))
ZoneVector<MachineType>(numberOfInputs, graph()->zone());
SparseInputMask dense = SparseInputMask::Dense();
const ElementAccess ElementAccesses[] = {
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::AnyTagged(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::TaggedSigned(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::TaggedPointer(),
kNoWriteBarrier}};
// For every access
for (size_t i = 0; i < arraysize(ElementAccesses); ++i) {
// Create the graph
Node* load1 =
graph()->NewNode(simplified()->LoadElement(ElementAccesses[i]), object,
index, effect, control);
Node* changeToTagged1 = graph()->NewNode(
machine()->ChangeCompressedPointerToTaggedPointer(), load1);
Node* load2 =
graph()->NewNode(simplified()->LoadElement(ElementAccesses[i]), object,
index, effect, control);
Node* changeToTagged2 = graph()->NewNode(
machine()->ChangeCompressedPointerToTaggedPointer(), load2);
Node* typedStateValuesOneDecompress =
graph()->NewNode(common()->TypedStateValues(types, dense),
changeToTagged1, load1, changeToTagged2);
// Reduce
StrictMock<MockAdvancedReducerEditor> editor;
DecompressionElimination decompression_elimination(&editor, graph(),
machine(), common());
Reduction r =
decompression_elimination.Reduce(typedStateValuesOneDecompress);
ASSERT_TRUE(r.Changed());
}
}
TEST_F(DecompressionEliminationTest, TypedStateValuesAllDecompresses) {
// Skip test if pointer compression is not enabled
if (!COMPRESS_POINTERS_BOOL) {
return;
}
// Define variables
Node* const control = graph()->start();
Node* object = Parameter(Type::Any(), 0);
Node* effect = graph()->start();
Node* index = Parameter(Type::UnsignedSmall(), 1);
const int numberOfInputs = 3;
const ZoneVector<MachineType>* types =
new (graph()->zone()->New(sizeof(ZoneVector<MachineType>)))
ZoneVector<MachineType>(numberOfInputs, graph()->zone());
SparseInputMask dense = SparseInputMask::Dense();
const ElementAccess ElementAccesses[] = {
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::AnyTagged(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::TaggedSigned(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::TaggedPointer(),
kNoWriteBarrier}};
// For every access
for (size_t i = 0; i < arraysize(ElementAccesses); ++i) {
// Create the graph
Node* load1 =
graph()->NewNode(simplified()->LoadElement(ElementAccesses[i]), object,
index, effect, control);
Node* changeToTagged1 = graph()->NewNode(
machine()->ChangeCompressedPointerToTaggedPointer(), load1);
Node* load2 =
graph()->NewNode(simplified()->LoadElement(ElementAccesses[i]), object,
index, effect, control);
Node* changeToTagged2 = graph()->NewNode(
machine()->ChangeCompressedPointerToTaggedPointer(), load2);
Node* load3 =
graph()->NewNode(simplified()->LoadElement(ElementAccesses[i]), object,
index, effect, control);
Node* changeToTagged3 = graph()->NewNode(
machine()->ChangeCompressedPointerToTaggedPointer(), load3);
Node* typedStateValuesOneDecompress =
graph()->NewNode(common()->TypedStateValues(types, dense),
changeToTagged1, changeToTagged2, changeToTagged3);
// Reduce
StrictMock<MockAdvancedReducerEditor> editor;
DecompressionElimination decompression_elimination(&editor, graph(),
machine(), common());
Reduction r =
decompression_elimination.Reduce(typedStateValuesOneDecompress);
ASSERT_TRUE(r.Changed());
}
}
TEST_F(DecompressionEliminationTest, TypedStateValuesNoDecompresses) {
// Skip test if pointer compression is not enabled
if (!COMPRESS_POINTERS_BOOL) {
return;
}
// Define variables
Node* const control = graph()->start();
Node* object = Parameter(Type::Any(), 0);
Node* effect = graph()->start();
Node* index = Parameter(Type::UnsignedSmall(), 1);
const int numberOfInputs = 3;
const ZoneVector<MachineType>* types =
new (graph()->zone()->New(sizeof(ZoneVector<MachineType>)))
ZoneVector<MachineType>(numberOfInputs, graph()->zone());
SparseInputMask dense = SparseInputMask::Dense();
const ElementAccess ElementAccesses[] = {
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::AnyTagged(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::TaggedSigned(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::TaggedPointer(),
kNoWriteBarrier}};
// For every access
for (size_t i = 0; i < arraysize(ElementAccesses); ++i) {
// Create the graph
Node* load = graph()->NewNode(simplified()->LoadElement(ElementAccesses[i]),
object, index, effect, control);
Node* typedStateValuesOneDecompress = graph()->NewNode(
common()->TypedStateValues(types, dense), load, load, load);
// Reduce
StrictMock<MockAdvancedReducerEditor> editor;
DecompressionElimination decompression_elimination(&editor, graph(),
machine(), common());
Reduction r =
decompression_elimination.Reduce(typedStateValuesOneDecompress);
ASSERT_FALSE(r.Changed());
}
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Word64Equal comparison of two decompressions // Word64Equal comparison of two decompressions
......
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