[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 <solanes@chromium.org> Reviewed-by: Georg Neis <neis@chromium.org> Commit-Queue: Igor Sheludko <ishell@chromium.org> Cr-Commit-Position: refs/heads/master@{#63991}
This commit is contained in:
parent
53780c06b7
commit
4ce267a832
@ -295,7 +295,9 @@ void TurboAssembler::Mov(const Register& rd, const Operand& operand,
|
|||||||
} else if (RelocInfo::IsEmbeddedObjectMode(operand.ImmediateRMode())) {
|
} else if (RelocInfo::IsEmbeddedObjectMode(operand.ImmediateRMode())) {
|
||||||
Handle<HeapObject> x(
|
Handle<HeapObject> x(
|
||||||
reinterpret_cast<Address*>(operand.ImmediateValue()));
|
reinterpret_cast<Address*>(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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -510,9 +510,12 @@ class V8_EXPORT_PRIVATE CodeStubAssembler
|
|||||||
uintptr_t ConstexprWordNot(uintptr_t a) { return ~a; }
|
uintptr_t ConstexprWordNot(uintptr_t a) { return ~a; }
|
||||||
|
|
||||||
TNode<BoolT> TaggedEqual(TNode<AnyTaggedT> a, TNode<AnyTaggedT> b) {
|
TNode<BoolT> TaggedEqual(TNode<AnyTaggedT> a, TNode<AnyTaggedT> b) {
|
||||||
// In pointer-compressed architectures, the instruction selector will narrow
|
#ifdef V8_COMPRESS_POINTERS
|
||||||
// this comparison to a 32-bit one.
|
return Word32Equal(ChangeTaggedToCompressed(a),
|
||||||
|
ChangeTaggedToCompressed(b));
|
||||||
|
#else
|
||||||
return WordEqual(ReinterpretCast<WordT>(a), ReinterpretCast<WordT>(b));
|
return WordEqual(ReinterpretCast<WordT>(a), ReinterpretCast<WordT>(b));
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
TNode<BoolT> TaggedNotEqual(TNode<AnyTaggedT> a, TNode<AnyTaggedT> b) {
|
TNode<BoolT> TaggedNotEqual(TNode<AnyTaggedT> a, TNode<AnyTaggedT> b) {
|
||||||
|
@ -1461,6 +1461,8 @@ void TurboAssembler::Move(Register result, Handle<HeapObject> object,
|
|||||||
RelocInfo::Mode rmode) {
|
RelocInfo::Mode rmode) {
|
||||||
if (FLAG_embedded_builtins) {
|
if (FLAG_embedded_builtins) {
|
||||||
if (root_array_available_ && options().isolate_independent_code) {
|
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);
|
IndirectLoadConstant(result, object);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -302,6 +302,7 @@ TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
|
|||||||
V(ChangeInt32ToInt64, Int64T, Int32T) \
|
V(ChangeInt32ToInt64, Int64T, Int32T) \
|
||||||
V(ChangeUint32ToFloat64, Float64T, Word32T) \
|
V(ChangeUint32ToFloat64, Float64T, Word32T) \
|
||||||
V(ChangeUint32ToUint64, Uint64T, Word32T) \
|
V(ChangeUint32ToUint64, Uint64T, Word32T) \
|
||||||
|
V(ChangeTaggedToCompressed, TaggedT, AnyTaggedT) \
|
||||||
V(BitcastInt32ToFloat32, Float32T, Word32T) \
|
V(BitcastInt32ToFloat32, Float32T, Word32T) \
|
||||||
V(BitcastFloat32ToInt32, Uint32T, Float32T) \
|
V(BitcastFloat32ToInt32, Uint32T, Float32T) \
|
||||||
V(RoundFloat64ToInt32, Int32T, Float64T) \
|
V(RoundFloat64ToInt32, Int32T, Float64T) \
|
||||||
|
@ -167,6 +167,42 @@ Reduction DecompressionElimination::ReduceTypedStateValues(Node* node) {
|
|||||||
return any_change ? Changed(node) : NoChange();
|
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) {
|
Reduction DecompressionElimination::ReduceWord64Equal(Node* node) {
|
||||||
DCHECK_EQ(node->opcode(), IrOpcode::kWord64Equal);
|
DCHECK_EQ(node->opcode(), IrOpcode::kWord64Equal);
|
||||||
|
|
||||||
@ -220,6 +256,8 @@ Reduction DecompressionElimination::Reduce(Node* node) {
|
|||||||
return ReducePhi(node);
|
return ReducePhi(node);
|
||||||
case IrOpcode::kTypedStateValues:
|
case IrOpcode::kTypedStateValues:
|
||||||
return ReduceTypedStateValues(node);
|
return ReduceTypedStateValues(node);
|
||||||
|
case IrOpcode::kWord32Equal:
|
||||||
|
return ReduceWord32Equal(node);
|
||||||
case IrOpcode::kWord64Equal:
|
case IrOpcode::kWord64Equal:
|
||||||
return ReduceWord64Equal(node);
|
return ReduceWord64Equal(node);
|
||||||
default:
|
default:
|
||||||
|
@ -65,6 +65,11 @@ class V8_EXPORT_PRIVATE DecompressionElimination final
|
|||||||
// value of that constant.
|
// value of that constant.
|
||||||
Reduction ReduceWord64Equal(Node* node);
|
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_; }
|
Graph* graph() const { return graph_; }
|
||||||
MachineOperatorBuilder* machine() const { return machine_; }
|
MachineOperatorBuilder* machine() const { return machine_; }
|
||||||
CommonOperatorBuilder* common() const { return common_; }
|
CommonOperatorBuilder* common() const { return common_; }
|
||||||
|
@ -99,7 +99,12 @@ Node* GraphAssembler::IntPtrEqual(Node* left, Node* right) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Node* GraphAssembler::TaggedEqual(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);
|
return WordEqual(left, right);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
Node* GraphAssembler::Float64RoundDown(Node* value) {
|
Node* GraphAssembler::Float64RoundDown(Node* value) {
|
||||||
|
@ -461,7 +461,7 @@ class MachineRepresentationChecker {
|
|||||||
CheckValueInputForFloat64Op(node, 0);
|
CheckValueInputForFloat64Op(node, 0);
|
||||||
break;
|
break;
|
||||||
case IrOpcode::kWord64Equal:
|
case IrOpcode::kWord64Equal:
|
||||||
if (Is64()) {
|
if (Is64() && !COMPRESS_POINTERS_BOOL) {
|
||||||
CheckValueInputIsTaggedOrPointer(node, 0);
|
CheckValueInputIsTaggedOrPointer(node, 0);
|
||||||
CheckValueInputIsTaggedOrPointer(node, 1);
|
CheckValueInputIsTaggedOrPointer(node, 1);
|
||||||
if (!is_stub_) {
|
if (!is_stub_) {
|
||||||
|
Loading…
Reference in New Issue
Block a user