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() { ...@@ -55,6 +55,20 @@ void DecompressionOptimizer::MarkNodes() {
void DecompressionOptimizer::MarkNodeInputs(Node* node) { void DecompressionOptimizer::MarkNodeInputs(Node* node) {
// Mark the value inputs. // Mark the value inputs.
switch (node->opcode()) { 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::kStore: // Fall through.
case IrOpcode::kProtectedStore: // Fall through. case IrOpcode::kProtectedStore: // Fall through.
case IrOpcode::kUnalignedStore: case IrOpcode::kUnalignedStore:
...@@ -63,15 +77,14 @@ void DecompressionOptimizer::MarkNodeInputs(Node* node) { ...@@ -63,15 +77,14 @@ void DecompressionOptimizer::MarkNodeInputs(Node* node) {
State::kEverythingObserved); // base pointer State::kEverythingObserved); // base pointer
MaybeMarkAndQueueForRevisit(node->InputAt(1), MaybeMarkAndQueueForRevisit(node->InputAt(1),
State::kEverythingObserved); // index State::kEverythingObserved); // index
// TODO(v8:7703): When the implementation is done, check if this 'if' is // TODO(v8:7703): When the implementation is done, check if this ternary
// too restrictive We only mark Tagged stores as 32 bits // operator is too restrictive, since we only mark Tagged stores as 32
if (IsAnyTagged(StoreRepresentationOf(node->op()).representation())) { // bits.
MaybeMarkAndQueueForRevisit(node->InputAt(2), MaybeMarkAndQueueForRevisit(
State::kOnly32BitsObserved); // value node->InputAt(2),
} else { IsAnyTagged(StoreRepresentationOf(node->op()).representation())
MaybeMarkAndQueueForRevisit(node->InputAt(2), ? State::kOnly32BitsObserved
State::kEverythingObserved); // value : State::kEverythingObserved); // value
}
break; break;
default: default:
// To be conservative, we assume that all value inputs need to be 64 bits // To be conservative, we assume that all value inputs need to be 64 bits
......
...@@ -406,7 +406,11 @@ class MachineRepresentationChecker { ...@@ -406,7 +406,11 @@ class MachineRepresentationChecker {
inferrer_->GetRepresentation(node->InputAt(0)))); inferrer_->GetRepresentation(node->InputAt(0))));
break; break;
case IrOpcode::kChangeTaggedToCompressed: case IrOpcode::kChangeTaggedToCompressed:
CHECK(IsAnyTagged(inferrer_->GetRepresentation(node->InputAt(0)))); if (FLAG_turbo_decompression_elimination) {
CheckValueInputIsTagged(node, 0);
} else {
CheckValueInputIsCompressedOrTagged(node, 0);
}
break; break;
case IrOpcode::kChangeTaggedPointerToCompressedPointer: case IrOpcode::kChangeTaggedPointerToCompressedPointer:
CHECK(CanBeTaggedPointer( CHECK(CanBeTaggedPointer(
......
...@@ -60,9 +60,8 @@ class DecompressionOptimizerTest : public GraphTest { ...@@ -60,9 +60,8 @@ class DecompressionOptimizerTest : public GraphTest {
// Direct Load into Store. // Direct Load into Store.
TEST_F(DecompressionOptimizerTest, DirectLoadStore) { TEST_F(DecompressionOptimizerTest, DirectLoadStore) {
// Skip test if pointer compression is disabled, or decompression elimination // Skip test if decompression elimination is enabled.
// enabled. if (FLAG_turbo_decompression_elimination) {
if (!COMPRESS_POINTERS_BOOL || FLAG_turbo_decompression_elimination) {
return; return;
} }
...@@ -82,13 +81,100 @@ TEST_F(DecompressionOptimizerTest, DirectLoadStore) { ...@@ -82,13 +81,100 @@ TEST_F(DecompressionOptimizerTest, DirectLoadStore) {
graph()->SetEnd(graph()->NewNode(machine()->Store(CreateStoreRep(types[i])), graph()->SetEnd(graph()->NewNode(machine()->Store(CreateStoreRep(types[i])),
object, index, value, effect, control)); object, index, value, effect, control));
// Change the loads, and test the change. // Change the nodes, and test the change.
Reduce(); Reduce();
EXPECT_EQ(LoadMachRep(base_pointer), types[i].representation()); EXPECT_EQ(LoadMachRep(base_pointer), types[i].representation());
EXPECT_EQ(LoadMachRep(value), CompressedMachRep(types[i])); 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 compiler
} // namespace internal } // namespace internal
} // namespace v8 } // namespace v8
...@@ -41,4 +41,10 @@ ...@@ -41,4 +41,10 @@
'BackingStoreTest.RacyGrowWasmMemoryInPlace': [SKIP], 'BackingStoreTest.RacyGrowWasmMemoryInPlace': [SKIP],
}], # tsan == True }], # 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