From 904eaecbc62275e5679796ca3742e416af0e1f42 Mon Sep 17 00:00:00 2001 From: Santiago Aboy Solanes Date: Wed, 8 Jan 2020 14:43:10 +0000 Subject: [PATCH] [ptr-compr] Added BitcastTaggedToWord* to DecompressionOptimizer We were missing some possible load compressions due to not having these bitcasts as cases. Bug: v8:7703 Change-Id: I866196c4fd09d313d3a461cb7f8f80bc92278e13 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1989830 Reviewed-by: Tobias Tebbi Commit-Queue: Santiago Aboy Solanes Cr-Commit-Position: refs/heads/master@{#65647} --- src/compiler/decompression-optimizer.cc | 7 ++ src/compiler/machine-graph-verifier.cc | 16 ++++- .../decompression-optimizer-unittest.cc | 65 +++++++++++++++++++ 3 files changed, 87 insertions(+), 1 deletion(-) diff --git a/src/compiler/decompression-optimizer.cc b/src/compiler/decompression-optimizer.cc index 3943e9ba77..9b2362c9ef 100644 --- a/src/compiler/decompression-optimizer.cc +++ b/src/compiler/decompression-optimizer.cc @@ -65,6 +65,13 @@ void DecompressionOptimizer::MarkNodeInputs(Node* node) { // Mark the value inputs. switch (node->opcode()) { // UNOPS. + case IrOpcode::kBitcastTaggedToWord: + case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits: + // Replicate the bitcast's state for its input. + DCHECK_EQ(node->op()->ValueInputCount(), 1); + MaybeMarkAndQueueForRevisit(node->InputAt(0), + states_.Get(node)); // value + break; case IrOpcode::kTruncateInt64ToInt32: DCHECK_EQ(node->op()->ValueInputCount(), 1); MaybeMarkAndQueueForRevisit(node->InputAt(0), diff --git a/src/compiler/machine-graph-verifier.cc b/src/compiler/machine-graph-verifier.cc index dded1561d7..8b318d1430 100644 --- a/src/compiler/machine-graph-verifier.cc +++ b/src/compiler/machine-graph-verifier.cc @@ -393,6 +393,12 @@ class MachineRepresentationChecker { break; case IrOpcode::kBitcastTaggedToWord: case IrOpcode::kBitcastTaggedToWordForTagAndSmiBits: + if (COMPRESS_POINTERS_BOOL) { + CheckValueInputIsCompressedOrTagged(node, 0); + } else { + CheckValueInputIsTagged(node, 0); + } + break; case IrOpcode::kTaggedPoisonOnSpeculation: CheckValueInputIsTagged(node, 0); break; @@ -617,11 +623,19 @@ class MachineRepresentationChecker { switch (inferrer_->GetRepresentation(node)) { case MachineRepresentation::kTagged: case MachineRepresentation::kTaggedPointer: - case MachineRepresentation::kTaggedSigned: for (int i = 0; i < node->op()->ValueInputCount(); ++i) { CheckValueInputIsTagged(node, i); } break; + case MachineRepresentation::kTaggedSigned: + for (int i = 0; i < node->op()->ValueInputCount(); ++i) { + if (COMPRESS_POINTERS_BOOL) { + CheckValueInputIsCompressedOrTagged(node, i); + } else { + CheckValueInputIsTagged(node, i); + } + } + break; case MachineRepresentation::kCompressed: case MachineRepresentation::kCompressedPointer: for (int i = 0; i < node->op()->ValueInputCount(); ++i) { diff --git a/test/unittests/compiler/decompression-optimizer-unittest.cc b/test/unittests/compiler/decompression-optimizer-unittest.cc index 41531f9ff6..46122ff1a4 100644 --- a/test/unittests/compiler/decompression-optimizer-unittest.cc +++ b/test/unittests/compiler/decompression-optimizer-unittest.cc @@ -424,6 +424,71 @@ TEST_F(DecompressionOptimizerTest, Int32LessThanOrEqualFromSpeculative) { EXPECT_EQ(LoadMachRep(load), CompressedMachRep(MachineType::AnyTagged())); } +// ----------------------------------------------------------------------------- +// Bitcast cases. + +TEST_F(DecompressionOptimizerTest, BitcastTaggedToWord) { + // 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* bitcast_1 = graph()->NewNode(machine()->BitcastTaggedToWord(), + load_1, effect, control); + Node* load_2 = graph()->NewNode(machine()->Load(types[j]), object, index, + effect, control); + Node* bitcast_2 = graph()->NewNode(machine()->BitcastTaggedToWord(), + load_2, effect, control); + Node* equal = + graph()->NewNode(machine()->Word32Equal(), bitcast_1, bitcast_2); + graph()->SetEnd(equal); + + // 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, BitcastTaggedToWordForTagAndSmiBits) { + // 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* bitcast_1 = graph()->NewNode( + machine()->BitcastTaggedToWordForTagAndSmiBits(), load_1); + Node* load_2 = graph()->NewNode(machine()->Load(types[j]), object, index, + effect, control); + Node* bitcast_2 = graph()->NewNode( + machine()->BitcastTaggedToWordForTagAndSmiBits(), load_2); + Node* equal = + graph()->NewNode(machine()->Word32Equal(), bitcast_1, bitcast_2); + graph()->SetEnd(equal); + + // Change the nodes, and test the change. + Reduce(); + EXPECT_EQ(LoadMachRep(load_1), CompressedMachRep(types[i])); + EXPECT_EQ(LoadMachRep(load_2), CompressedMachRep(types[j])); + } + } +} + } // namespace compiler } // namespace internal } // namespace v8