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

[ptr-compr] Added tagged equality cases to DecompressionOptimizer

Added the opcodes kWord32Equal and kChangeTaggedToCompressed to
DecompressionOptimizer.

Currently  TaggedEqual node generates ChangeTaggedToCompressed
nodes before the Word32Equal inputs. This means we need to also
propagate kOnly32BitsObserved from kChangeTaggedToCompressed.

Bug: v8:7703
Change-Id: I61fee07269696c60e065e1bbfee3a65c1b1537fc
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1871911Reviewed-by: 's avatarJakob Gruber <jgruber@chromium.org>
Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64513}
parent 00937422
......@@ -55,6 +55,20 @@ void DecompressionOptimizer::MarkNodes() {
void DecompressionOptimizer::MarkNodeInputs(Node* node) {
// Mark the value inputs.
switch (node->opcode()) {
// TODO(v8:7703): To be removed when the TaggedEqual implementation stops
// using ChangeTaggedToCompressed.
case IrOpcode::kChangeTaggedToCompressed:
DCHECK_EQ(node->op()->ValueInputCount(), 1);
MaybeMarkAndQueueForRevisit(node->InputAt(0),
State::kOnly32BitsObserved); // value
break;
case IrOpcode::kWord32Equal:
DCHECK_EQ(node->op()->ValueInputCount(), 2);
MaybeMarkAndQueueForRevisit(node->InputAt(0),
State::kOnly32BitsObserved); // value_0
MaybeMarkAndQueueForRevisit(node->InputAt(1),
State::kOnly32BitsObserved); // value_1
break;
case IrOpcode::kStore: // Fall through.
case IrOpcode::kProtectedStore: // Fall through.
case IrOpcode::kUnalignedStore:
......@@ -63,15 +77,14 @@ void DecompressionOptimizer::MarkNodeInputs(Node* node) {
State::kEverythingObserved); // base pointer
MaybeMarkAndQueueForRevisit(node->InputAt(1),
State::kEverythingObserved); // index
// TODO(v8:7703): When the implementation is done, check if this 'if' is
// too restrictive We only mark Tagged stores as 32 bits
if (IsAnyTagged(StoreRepresentationOf(node->op()).representation())) {
MaybeMarkAndQueueForRevisit(node->InputAt(2),
State::kOnly32BitsObserved); // value
} else {
MaybeMarkAndQueueForRevisit(node->InputAt(2),
State::kEverythingObserved); // value
}
// TODO(v8:7703): When the implementation is done, check if this ternary
// operator is too restrictive, since we only mark Tagged stores as 32
// bits.
MaybeMarkAndQueueForRevisit(
node->InputAt(2),
IsAnyTagged(StoreRepresentationOf(node->op()).representation())
? State::kOnly32BitsObserved
: State::kEverythingObserved); // value
break;
default:
// To be conservative, we assume that all value inputs need to be 64 bits
......
......@@ -406,7 +406,11 @@ class MachineRepresentationChecker {
inferrer_->GetRepresentation(node->InputAt(0))));
break;
case IrOpcode::kChangeTaggedToCompressed:
CHECK(IsAnyTagged(inferrer_->GetRepresentation(node->InputAt(0))));
if (FLAG_turbo_decompression_elimination) {
CheckValueInputIsTagged(node, 0);
} else {
CheckValueInputIsCompressedOrTagged(node, 0);
}
break;
case IrOpcode::kChangeTaggedPointerToCompressedPointer:
CHECK(CanBeTaggedPointer(
......
......@@ -60,9 +60,8 @@ class DecompressionOptimizerTest : public GraphTest {
// Direct Load into Store.
TEST_F(DecompressionOptimizerTest, DirectLoadStore) {
// Skip test if pointer compression is disabled, or decompression elimination
// enabled.
if (!COMPRESS_POINTERS_BOOL || FLAG_turbo_decompression_elimination) {
// Skip test if decompression elimination is enabled.
if (FLAG_turbo_decompression_elimination) {
return;
}
......@@ -82,13 +81,100 @@ TEST_F(DecompressionOptimizerTest, DirectLoadStore) {
graph()->SetEnd(graph()->NewNode(machine()->Store(CreateStoreRep(types[i])),
object, index, value, effect, control));
// Change the loads, and test the change.
// Change the nodes, and test the change.
Reduce();
EXPECT_EQ(LoadMachRep(base_pointer), types[i].representation());
EXPECT_EQ(LoadMachRep(value), CompressedMachRep(types[i]));
}
}
// -----------------------------------------------------------------------------
// Word32Equal.
TEST_F(DecompressionOptimizerTest, Word32EqualTwoDecompresses) {
// Skip test if decompression elimination is enabled.
if (FLAG_turbo_decompression_elimination) {
return;
}
// Define variables.
Node* const control = graph()->start();
Node* object = Parameter(Type::Any(), 0);
Node* effect = graph()->start();
Node* index = Parameter(Type::UnsignedSmall(), 1);
// Test for both AnyTagged and TaggedPointer, for both loads.
for (size_t i = 0; i < arraysize(types); ++i) {
for (size_t j = 0; j < arraysize(types); ++j) {
// Create the graph.
Node* load_1 = graph()->NewNode(machine()->Load(types[i]), object, index,
effect, control);
Node* change_to_tagged_1 =
graph()->NewNode(machine()->ChangeTaggedToCompressed(), load_1);
Node* load_2 = graph()->NewNode(machine()->Load(types[j]), object, index,
effect, control);
Node* change_to_tagged_2 =
graph()->NewNode(machine()->ChangeTaggedToCompressed(), load_2);
graph()->SetEnd(graph()->NewNode(machine()->Word32Equal(),
change_to_tagged_1, change_to_tagged_2));
// Change the nodes, and test the change.
Reduce();
EXPECT_EQ(LoadMachRep(load_1), CompressedMachRep(types[i]));
EXPECT_EQ(LoadMachRep(load_2), CompressedMachRep(types[j]));
}
}
}
TEST_F(DecompressionOptimizerTest, Word32DecompressAndConstant) {
// Skip test if decompression elimination is enabled.
if (FLAG_turbo_decompression_elimination) {
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 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)};
// Test for both AnyTagged and TaggedPointer, for both loads.
for (size_t i = 0; i < arraysize(types); ++i) {
for (size_t j = 0; j < arraysize(heap_constants); ++j) {
// Create the graph.
Node* load = graph()->NewNode(machine()->Load(types[i]), object, index,
effect, control);
Node* change_to_tagged =
graph()->NewNode(machine()->ChangeTaggedToCompressed(), load);
Node* constant =
graph()->NewNode(common()->CompressedHeapConstant(heap_constants[j]));
graph()->SetEnd(graph()->NewNode(machine()->Word32Equal(),
change_to_tagged, constant));
// Change the nodes, and test the change.
Reduce();
EXPECT_EQ(LoadMachRep(load), CompressedMachRep(types[i]));
}
}
}
} // namespace compiler
} // namespace internal
} // namespace v8
......@@ -41,4 +41,10 @@
'BackingStoreTest.RacyGrowWasmMemoryInPlace': [SKIP],
}], # tsan == True
##############################################################################
['not pointer_compression', {
# Tests are irrelevant without pointer compression
'DecompressionOptimizerTest.*': [SKIP],
}], # not pointer_compression
]
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