From 4ce267a83212eb771178730b661bd086103b7602 Mon Sep 17 00:00:00 2001 From: Igor Sheludko Date: Wed, 25 Sep 2019 14:14:00 +0200 Subject: [PATCH] [ptr-compr] Generate TaggedEqual as Word32Equal of compressed values ... in both CSA code and TurboFan. This is a prerequisite for smi-corrupting decompression. The decompression eliminator changes is a workaround to ensure that the result of comparisons of two constant Smis is still a constexpr (the failing test is cctest/test-torque/TestLoadEliminationFixed). Better optimizations will be landed in a follow-up CLs. Bug: v8:9706 Change-Id: Ie2d90f6a7714aa749439e3f457d90d663d0efe49 Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1815133 Reviewed-by: Santiago Aboy Solanes Reviewed-by: Georg Neis Commit-Queue: Igor Sheludko Cr-Commit-Position: refs/heads/master@{#63991} --- src/codegen/arm64/macro-assembler-arm64.cc | 4 ++- src/codegen/code-stub-assembler.h | 7 ++-- src/codegen/x64/macro-assembler-x64.cc | 2 ++ src/compiler/code-assembler.h | 1 + src/compiler/decompression-elimination.cc | 38 ++++++++++++++++++++++ src/compiler/decompression-elimination.h | 5 +++ src/compiler/graph-assembler.cc | 5 +++ src/compiler/machine-graph-verifier.cc | 2 +- 8 files changed, 60 insertions(+), 4 deletions(-) diff --git a/src/codegen/arm64/macro-assembler-arm64.cc b/src/codegen/arm64/macro-assembler-arm64.cc index ab971fcf17..5a1cc61778 100644 --- a/src/codegen/arm64/macro-assembler-arm64.cc +++ b/src/codegen/arm64/macro-assembler-arm64.cc @@ -295,7 +295,9 @@ void TurboAssembler::Mov(const Register& rd, const Operand& operand, } else if (RelocInfo::IsEmbeddedObjectMode(operand.ImmediateRMode())) { Handle x( reinterpret_cast(operand.ImmediateValue())); - IndirectLoadConstant(rd, x); + // TODO(v8:9706): Fix-it! This load will always uncompress the value + // even when we are loading a compressed embedded object. + IndirectLoadConstant(rd.X(), x); return; } } diff --git a/src/codegen/code-stub-assembler.h b/src/codegen/code-stub-assembler.h index 55550f1804..1804c557c6 100644 --- a/src/codegen/code-stub-assembler.h +++ b/src/codegen/code-stub-assembler.h @@ -510,9 +510,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler uintptr_t ConstexprWordNot(uintptr_t a) { return ~a; } TNode TaggedEqual(TNode a, TNode b) { - // In pointer-compressed architectures, the instruction selector will narrow - // this comparison to a 32-bit one. +#ifdef V8_COMPRESS_POINTERS + return Word32Equal(ChangeTaggedToCompressed(a), + ChangeTaggedToCompressed(b)); +#else return WordEqual(ReinterpretCast(a), ReinterpretCast(b)); +#endif } TNode TaggedNotEqual(TNode a, TNode b) { diff --git a/src/codegen/x64/macro-assembler-x64.cc b/src/codegen/x64/macro-assembler-x64.cc index 5c0edc2270..5e10115a04 100644 --- a/src/codegen/x64/macro-assembler-x64.cc +++ b/src/codegen/x64/macro-assembler-x64.cc @@ -1461,6 +1461,8 @@ void TurboAssembler::Move(Register result, Handle object, RelocInfo::Mode rmode) { if (FLAG_embedded_builtins) { if (root_array_available_ && options().isolate_independent_code) { + // TODO(v8:9706): Fix-it! This load will always uncompress the value + // even when we are loading a compressed embedded object. IndirectLoadConstant(result, object); return; } diff --git a/src/compiler/code-assembler.h b/src/compiler/code-assembler.h index 700a063320..1a6943d7e2 100644 --- a/src/compiler/code-assembler.h +++ b/src/compiler/code-assembler.h @@ -302,6 +302,7 @@ TNode Float64Add(TNode a, TNode b); V(ChangeInt32ToInt64, Int64T, Int32T) \ V(ChangeUint32ToFloat64, Float64T, Word32T) \ V(ChangeUint32ToUint64, Uint64T, Word32T) \ + V(ChangeTaggedToCompressed, TaggedT, AnyTaggedT) \ V(BitcastInt32ToFloat32, Float32T, Word32T) \ V(BitcastFloat32ToInt32, Uint32T, Float32T) \ V(RoundFloat64ToInt32, Int32T, Float64T) \ diff --git a/src/compiler/decompression-elimination.cc b/src/compiler/decompression-elimination.cc index 537744652b..ae9eb7e432 100644 --- a/src/compiler/decompression-elimination.cc +++ b/src/compiler/decompression-elimination.cc @@ -167,6 +167,42 @@ Reduction DecompressionElimination::ReduceTypedStateValues(Node* node) { return any_change ? Changed(node) : NoChange(); } +Reduction DecompressionElimination::ReduceWord32Equal(Node* node) { + DCHECK_EQ(node->opcode(), IrOpcode::kWord32Equal); + + DCHECK_EQ(node->InputCount(), 2); + Node* lhs = node->InputAt(0); + Node* rhs = node->InputAt(1); + + if (!IrOpcode::IsCompressOpcode(lhs->opcode()) || + !IrOpcode::IsCompressOpcode(rhs->opcode())) { + return NoChange(); + } + // Input nodes for compress operation. + lhs = lhs->InputAt(0); + rhs = rhs->InputAt(0); + + bool changed = false; + + if (lhs->opcode() == IrOpcode::kBitcastWordToTaggedSigned) { + Node* input = lhs->InputAt(0); + if (IsReducibleConstantOpcode(input->opcode())) { + node->ReplaceInput(0, GetCompressedConstant(input)); + changed = true; + } + } + + if (rhs->opcode() == IrOpcode::kBitcastWordToTaggedSigned) { + Node* input = rhs->InputAt(0); + if (IsReducibleConstantOpcode(input->opcode())) { + node->ReplaceInput(1, GetCompressedConstant(input)); + changed = true; + } + } + + return changed ? Changed(node) : NoChange(); +} + Reduction DecompressionElimination::ReduceWord64Equal(Node* node) { DCHECK_EQ(node->opcode(), IrOpcode::kWord64Equal); @@ -220,6 +256,8 @@ Reduction DecompressionElimination::Reduce(Node* node) { return ReducePhi(node); case IrOpcode::kTypedStateValues: return ReduceTypedStateValues(node); + case IrOpcode::kWord32Equal: + return ReduceWord32Equal(node); case IrOpcode::kWord64Equal: return ReduceWord64Equal(node); default: diff --git a/src/compiler/decompression-elimination.h b/src/compiler/decompression-elimination.h index 85a6c98aa0..6b2be009c6 100644 --- a/src/compiler/decompression-elimination.h +++ b/src/compiler/decompression-elimination.h @@ -65,6 +65,11 @@ class V8_EXPORT_PRIVATE DecompressionElimination final // value of that constant. Reduction ReduceWord64Equal(Node* node); + // This is a workaround for load elimination test. + // Replaces Compress -> BitcastWordToTaggedSigned -> ReducibleConstant + // to CompressedConstant on both inputs of Word32Equal operation. + Reduction ReduceWord32Equal(Node* node); + Graph* graph() const { return graph_; } MachineOperatorBuilder* machine() const { return machine_; } CommonOperatorBuilder* common() const { return common_; } diff --git a/src/compiler/graph-assembler.cc b/src/compiler/graph-assembler.cc index 4ebd1a0719..525b176f3c 100644 --- a/src/compiler/graph-assembler.cc +++ b/src/compiler/graph-assembler.cc @@ -99,7 +99,12 @@ Node* GraphAssembler::IntPtrEqual(Node* left, Node* right) { } Node* GraphAssembler::TaggedEqual(Node* left, Node* right) { +#ifdef V8_COMPRESS_POINTERS + return Word32Equal(ChangeTaggedToCompressed(left), + ChangeTaggedToCompressed(right)); +#else return WordEqual(left, right); +#endif } Node* GraphAssembler::Float64RoundDown(Node* value) { diff --git a/src/compiler/machine-graph-verifier.cc b/src/compiler/machine-graph-verifier.cc index 1bbfa41341..ba105237ed 100644 --- a/src/compiler/machine-graph-verifier.cc +++ b/src/compiler/machine-graph-verifier.cc @@ -461,7 +461,7 @@ class MachineRepresentationChecker { CheckValueInputForFloat64Op(node, 0); break; case IrOpcode::kWord64Equal: - if (Is64()) { + if (Is64() && !COMPRESS_POINTERS_BOOL) { CheckValueInputIsTaggedOrPointer(node, 0); CheckValueInputIsTaggedOrPointer(node, 1); if (!is_stub_) {