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

[ptr-compr][turbofan] Reduction of Compress after Constant

Reduces compressions of constants, going from
     Constant <- Compress <- Child
to
     Compressed_Constant <- Child

This pattern commonly appeared when the Constant was being used as a
Store value (e.g StoreElement's value).

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: I2e71f79ddd2a6fba42cdfe782cc89fff3a8d5ac1
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1627988
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61887}
parent d34178fd
......@@ -17,7 +17,7 @@ DecompressionElimination::DecompressionElimination(
machine_(machine),
common_(common) {}
bool DecompressionElimination::IsReduceableConstantOpcode(
bool DecompressionElimination::IsReducibleConstantOpcode(
IrOpcode::Value opcode) {
switch (opcode) {
case IrOpcode::kInt64Constant:
......@@ -70,10 +70,13 @@ Reduction DecompressionElimination::ReduceCompress(Node* node) {
DCHECK_EQ(node->InputCount(), 1);
Node* input_node = node->InputAt(0);
if (IrOpcode::IsDecompressOpcode(input_node->opcode())) {
DCHECK(IsValidDecompress(node->opcode(), input_node->opcode()));
IrOpcode::Value input_opcode = input_node->opcode();
if (IrOpcode::IsDecompressOpcode(input_opcode)) {
DCHECK(IsValidDecompress(node->opcode(), input_opcode));
DCHECK_EQ(input_node->InputCount(), 1);
return Replace(input_node->InputAt(0));
} else if (IsReducibleConstantOpcode(input_opcode)) {
return Replace(GetCompressedConstant(input_node));
} else {
return NoChange();
}
......@@ -171,8 +174,8 @@ Reduction DecompressionElimination::ReduceWord64Equal(Node* node) {
return Changed(node);
}
bool lhs_is_constant = IsReduceableConstantOpcode(lhs->opcode());
bool rhs_is_constant = IsReduceableConstantOpcode(rhs->opcode());
bool lhs_is_constant = IsReducibleConstantOpcode(lhs->opcode());
bool rhs_is_constant = IsReducibleConstantOpcode(rhs->opcode());
// Case where one input is a Decompress node and the other a constant.
if ((lhs_is_decompress && rhs_is_constant) ||
......
......@@ -34,9 +34,9 @@ class V8_EXPORT_PRIVATE DecompressionElimination final
bool IsValidDecompress(IrOpcode::Value compressOpcode,
IrOpcode::Value decompressOpcode);
// Returns true if the constant opcode is a reduceable one in decompression
// Returns true if the constant opcode is a reducible one in decompression
// elimination.
bool IsReduceableConstantOpcode(IrOpcode::Value opcode);
bool IsReducibleConstantOpcode(IrOpcode::Value opcode);
// Get the new 32 bit node constant given the 64 bit one
Node* GetCompressedConstant(Node* constant);
......
......@@ -250,6 +250,131 @@ TEST_F(DecompressionEliminationTest,
EXPECT_EQ(load, r.replacement());
}
// -----------------------------------------------------------------------------
// Compress after constant
TEST_F(DecompressionEliminationTest,
DecompressionConstantStoreElementInt64Constant) {
// 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 ElementAccess element_accesses[] = {
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::AnyCompressed(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::CompressedSigned(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::CompressedPointer(),
kNoWriteBarrier}};
const Operator* compression_ops[] = {
machine()->ChangeTaggedToCompressed(),
machine()->ChangeTaggedSignedToCompressedSigned(),
machine()->ChangeTaggedPointerToCompressedPointer()};
ASSERT_EQ(arraysize(compression_ops), arraysize(element_accesses));
const int64_t constants[] = {static_cast<int64_t>(0x0000000000000000),
static_cast<int64_t>(0x0000000000000001),
static_cast<int64_t>(0x0000FFFFFFFF0000),
static_cast<int64_t>(0x7FFFFFFFFFFFFFFF),
static_cast<int64_t>(0x8000000000000000),
static_cast<int64_t>(0x8000000000000001),
static_cast<int64_t>(0x8000FFFFFFFF0000),
static_cast<int64_t>(0x8FFFFFFFFFFFFFFF),
static_cast<int64_t>(0xFFFFFFFFFFFFFFFF)};
// For every compression.
for (size_t i = 0; i < arraysize(compression_ops); ++i) {
// For every Int64Constant.
for (size_t j = 0; j < arraysize(constants); ++j) {
// Create the graph.
Node* constant = graph()->NewNode(common()->Int64Constant(constants[j]));
Node* changeToCompressed = graph()->NewNode(compression_ops[i], constant);
effect =
graph()->NewNode(simplified()->StoreElement(element_accesses[i]),
object, index, changeToCompressed, effect, control);
// Reduce.
Reduction r = Reduce(changeToCompressed);
ASSERT_TRUE(r.Changed());
EXPECT_EQ(r.replacement()->opcode(), IrOpcode::kInt32Constant);
}
}
}
TEST_F(DecompressionEliminationTest,
DecompressionConstantStoreElementHeapConstant) {
// 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 ElementAccess element_accesses[] = {
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::AnyCompressed(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::CompressedSigned(),
kNoWriteBarrier},
{kTaggedBase, kTaggedSize, Type::Any(), MachineType::CompressedPointer(),
kNoWriteBarrier}};
const Operator* compression_ops[] = {
machine()->ChangeTaggedToCompressed(),
machine()->ChangeTaggedSignedToCompressedSigned(),
machine()->ChangeTaggedPointerToCompressedPointer()};
ASSERT_EQ(arraysize(compression_ops), arraysize(element_accesses));
const Handle<HeapNumber> heap_constants[] = {
factory()->NewHeapNumber(0.0),
factory()->NewHeapNumber(-0.0),
factory()->NewHeapNumber(11.2),
factory()->NewHeapNumber(-11.2),
factory()->NewHeapNumber(3.1415 + 1.4142),
factory()->NewHeapNumber(3.1415 - 1.4142),
factory()->NewHeapNumber(0x0000000000000000),
factory()->NewHeapNumber(0x0000000000000001),
factory()->NewHeapNumber(0x0000FFFFFFFF0000),
factory()->NewHeapNumber(0x7FFFFFFFFFFFFFFF),
factory()->NewHeapNumber(0x8000000000000000),
factory()->NewHeapNumber(0x8000000000000001),
factory()->NewHeapNumber(0x8000FFFFFFFF0000),
factory()->NewHeapNumber(0x8FFFFFFFFFFFFFFF),
factory()->NewHeapNumber(0xFFFFFFFFFFFFFFFF)};
// For every compression.
for (size_t i = 0; i < arraysize(compression_ops); ++i) {
// For every HeapNumber.
for (size_t j = 0; j < arraysize(heap_constants); ++j) {
// Create the graph.
Node* constant =
graph()->NewNode(common()->HeapConstant(heap_constants[j]));
Node* changeToCompressed = graph()->NewNode(compression_ops[i], constant);
effect =
graph()->NewNode(simplified()->StoreElement(element_accesses[i]),
object, index, changeToCompressed, effect, control);
// Reduce.
Reduction r = Reduce(changeToCompressed);
ASSERT_TRUE(r.Changed());
// TODO(v8:8977): Change the IrOpcode here to kCompressedHeapConstant when
// that is in place.
EXPECT_EQ(r.replacement()->opcode(), IrOpcode::kHeapConstant);
}
}
}
// -----------------------------------------------------------------------------
// Phi
......
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