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

[ptr-compr][turbofan][CSA] Adding the CompressedHeapConstant node

CompressedHeapConstant is used in the DecompressionElimination Reducer to
create compressed HeapConstant values. It won't appear in the graph
up until that point.

This CL enables back the disabled tests in DecompressionElimination, as
well as generating the CompressedHeapConstant in that reducer.

The RelocInfo has already been added for x64 but not for arm64. Therefore,
the x64 version is now doing the mov on 32 bits. The support for ARM will
come in a following CL, and for now it is doing the mov in 64 bits.

Cq-Include-Trybots: luci.v8.try:v8_linux64_pointer_compression_rel_ng
Cq-Include-Trybots: luci.v8.try:v8_linux64_arm64_pointer_compression_rel_ng
Bug: v8:8977, v8:7703, v8:9298
Change-Id: If0ca4f937cfa60501679e66f6fd5ded2df38f605
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1632236Reviewed-by: 's avatarJaroslav Sevcik <jarin@chromium.org>
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Cr-Commit-Position: refs/heads/master@{#61950}
parent 3e90eee9
......@@ -130,6 +130,7 @@ class ArmOperandConverter final : public InstructionOperandConverter {
return Operand::EmbeddedStringConstant(
constant.ToDelayedStringConstant());
case Constant::kInt64:
case Constant::kCompressedHeapObject:
case Constant::kHeapObject:
// TODO(dcarney): loading RPO constants on arm.
case Constant::kRpoNumber:
......
......@@ -224,6 +224,7 @@ class Arm64OperandConverter final : public InstructionOperandConverter {
return Operand(Operand::EmbeddedNumber(constant.ToFloat64().value()));
case Constant::kExternalReference:
return Operand(constant.ToExternalReference());
case Constant::kCompressedHeapObject: // Fall through.
case Constant::kHeapObject:
return Operand(constant.ToHeapObject());
case Constant::kDelayedStringConstant:
......@@ -2669,6 +2670,15 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
} else {
__ Mov(dst, src_object);
}
} else if (src.type() == Constant::kCompressedHeapObject) {
Handle<HeapObject> src_object = src.ToHeapObject();
RootIndex index;
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
// TODO(v8:8977): Add the needed RelocInfo and make this mov on 32 bits
__ Mov(dst, src_object);
}
} else {
__ Mov(dst, g.ToImmediate(source));
}
......
......@@ -1210,6 +1210,10 @@ void CodeGenerator::AddTranslationForOperand(Translation* translation,
DCHECK_EQ(MachineRepresentation::kTagged, type.representation());
literal = DeoptimizationLiteral(constant.ToHeapObject());
break;
case Constant::kCompressedHeapObject:
DCHECK_EQ(MachineRepresentation::kCompressed, type.representation());
literal = DeoptimizationLiteral(constant.ToHeapObject());
break;
case Constant::kDelayedStringConstant:
DCHECK_EQ(MachineRepresentation::kTagged, type.representation());
literal = DeoptimizationLiteral(constant.ToDelayedStringConstant());
......
......@@ -81,6 +81,8 @@ class IA32OperandConverter : public InstructionOperandConverter {
return Immediate(constant.ToExternalReference());
case Constant::kHeapObject:
return Immediate(constant.ToHeapObject());
case Constant::kCompressedHeapObject:
break;
case Constant::kDelayedStringConstant:
return Immediate::EmbeddedStringConstant(
constant.ToDelayedStringConstant());
......
......@@ -326,6 +326,8 @@ class OperandGenerator {
}
case IrOpcode::kHeapConstant:
return Constant(HeapConstantOf(node->op()));
case IrOpcode::kCompressedHeapConstant:
return Constant(HeapConstantOf(node->op()), true);
case IrOpcode::kDelayedStringConstant:
return Constant(StringConstantBaseOf(node->op()));
case IrOpcode::kDeadValue: {
......
......@@ -1301,6 +1301,8 @@ void InstructionSelector::VisitNode(Node* node) {
return MarkAsFloat64(node), VisitConstant(node);
case IrOpcode::kHeapConstant:
return MarkAsReference(node), VisitConstant(node);
case IrOpcode::kCompressedHeapConstant:
return MarkAsCompressed(node), VisitConstant(node);
case IrOpcode::kNumberConstant: {
double value = OpParameter<double>(node->op());
if (!IsSmiDouble(value)) MarkAsReference(node);
......
......@@ -530,7 +530,7 @@ Constant::Constant(RelocatablePtrConstantInfo info) {
}
Handle<HeapObject> Constant::ToHeapObject() const {
DCHECK_EQ(kHeapObject, type());
DCHECK(kHeapObject == type() || kCompressedHeapObject == type());
Handle<HeapObject> value(
reinterpret_cast<Address*>(static_cast<intptr_t>(value_)));
return value;
......@@ -561,7 +561,8 @@ std::ostream& operator<<(std::ostream& os, const Constant& constant) {
return os << constant.ToFloat64().value();
case Constant::kExternalReference:
return os << constant.ToExternalReference().address();
case Constant::kHeapObject:
case Constant::kHeapObject: // Fall through.
case Constant::kCompressedHeapObject:
return os << Brief(*constant.ToHeapObject());
case Constant::kRpoNumber:
return os << "RPO" << constant.ToRpoNumber().ToInt();
......
......@@ -1007,6 +1007,7 @@ class V8_EXPORT_PRIVATE Constant final {
kFloat32,
kFloat64,
kExternalReference,
kCompressedHeapObject,
kHeapObject,
kRpoNumber,
kDelayedStringConstant
......@@ -1018,8 +1019,9 @@ class V8_EXPORT_PRIVATE Constant final {
explicit Constant(double v) : type_(kFloat64), value_(bit_cast<int64_t>(v)) {}
explicit Constant(ExternalReference ref)
: type_(kExternalReference), value_(bit_cast<intptr_t>(ref.address())) {}
explicit Constant(Handle<HeapObject> obj)
: type_(kHeapObject), value_(bit_cast<intptr_t>(obj)) {}
explicit Constant(Handle<HeapObject> obj, bool is_compressed = false)
: type_(is_compressed ? kCompressedHeapObject : kHeapObject),
value_(bit_cast<intptr_t>(obj)) {}
explicit Constant(RpoNumber rpo) : type_(kRpoNumber), value_(rpo.ToInt()) {}
explicit Constant(const StringConstantBase* str)
: type_(kDelayedStringConstant), value_(bit_cast<intptr_t>(str)) {}
......
......@@ -80,6 +80,7 @@ class MipsOperandConverter final : public InstructionOperandConverter {
return Operand::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kInt64:
case Constant::kExternalReference:
case Constant::kCompressedHeapObject:
case Constant::kHeapObject:
// TODO(plind): Maybe we should handle ExtRef & HeapObj here?
// maybe not done on arm due to const pool ??
......@@ -3578,6 +3579,8 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
break;
}
case Constant::kCompressedHeapObject:
UNREACHABLE();
case Constant::kRpoNumber:
UNREACHABLE(); // TODO(titzer): loading RPO numbers on mips.
break;
......
......@@ -82,6 +82,7 @@ class MipsOperandConverter final : public InstructionOperandConverter {
case Constant::kFloat64:
return Operand::EmbeddedNumber(constant.ToFloat64().value());
case Constant::kExternalReference:
case Constant::kCompressedHeapObject:
case Constant::kHeapObject:
// TODO(plind): Maybe we should handle ExtRef & HeapObj here?
// maybe not done on arm due to const pool ??
......@@ -3737,6 +3738,8 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
break;
}
case Constant::kCompressedHeapObject:
UNREACHABLE();
case Constant::kRpoNumber:
UNREACHABLE(); // TODO(titzer): loading RPO numbers on mips64.
break;
......
......@@ -79,6 +79,7 @@ class PPCOperandConverter final : public InstructionOperandConverter {
case Constant::kDelayedStringConstant:
return Operand::EmbeddedStringConstant(
constant.ToDelayedStringConstant());
case Constant::kCompressedHeapObject:
case Constant::kHeapObject:
case Constant::kRpoNumber:
break;
......@@ -2580,6 +2581,8 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
break;
}
case Constant::kCompressedHeapObject:
UNREACHABLE();
case Constant::kRpoNumber:
UNREACHABLE(); // TODO(dcarney): loading RPO constants on PPC.
break;
......
......@@ -73,6 +73,7 @@ class S390OperandConverter final : public InstructionOperandConverter {
case Constant::kDelayedStringConstant:
return Operand::EmbeddedStringConstant(
constant.ToDelayedStringConstant());
case Constant::kCompressedHeapObject:
case Constant::kHeapObject:
case Constant::kRpoNumber:
break;
......@@ -3261,6 +3262,9 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
break;
}
case Constant::kCompressedHeapObject:
UNREACHABLE();
break;
case Constant::kRpoNumber:
UNREACHABLE(); // TODO(dcarney): loading RPO constants on S390.
break;
......
......@@ -3970,6 +3970,16 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
}
break;
}
case Constant::kCompressedHeapObject: {
Handle<HeapObject> src_object = src.ToHeapObject();
RootIndex index;
if (IsMaterializableFromRoot(src_object, &index)) {
__ LoadRoot(dst, index);
} else {
__ Move(dst, src_object, RelocInfo::COMPRESSED_EMBEDDED_OBJECT);
}
break;
}
case Constant::kDelayedStringConstant: {
const StringConstantBase* src_constant = src.ToDelayedStringConstant();
__ MoveStringConstant(dst, src_constant);
......
......@@ -1216,8 +1216,18 @@ const Operator* CommonOperatorBuilder::HeapConstant(
value); // parameter
}
const Operator* CommonOperatorBuilder::CompressedHeapConstant(
const Handle<HeapObject>& value) {
return new (zone()) Operator1<Handle<HeapObject>>( // --
IrOpcode::kCompressedHeapConstant, Operator::kPure, // opcode
"CompressedHeapConstant", // name
0, 0, 0, 1, 0, 0, // counts
value); // parameter
}
Handle<HeapObject> HeapConstantOf(const Operator* op) {
DCHECK_EQ(IrOpcode::kHeapConstant, op->opcode());
DCHECK(IrOpcode::kHeapConstant == op->opcode() ||
IrOpcode::kCompressedHeapConstant == op->opcode());
return OpParameter<Handle<HeapObject>>(op);
}
......
......@@ -499,6 +499,7 @@ class V8_EXPORT_PRIVATE CommonOperatorBuilder final
const Operator* NumberConstant(volatile double);
const Operator* PointerConstant(intptr_t);
const Operator* HeapConstant(const Handle<HeapObject>&);
const Operator* CompressedHeapConstant(const Handle<HeapObject>&);
const Operator* ObjectId(uint32_t);
const Operator* RelocatableInt32Constant(int32_t value,
......
......@@ -21,10 +21,8 @@ bool DecompressionElimination::IsReducibleConstantOpcode(
IrOpcode::Value opcode) {
switch (opcode) {
case IrOpcode::kInt64Constant:
return true;
// TODO(v8:8977): Disabling HeapConstant until CompressedHeapConstant
// exists, since it breaks with verify CSA on.
case IrOpcode::kHeapConstant:
return true;
default:
return false;
}
......@@ -55,13 +53,8 @@ Node* DecompressionElimination::GetCompressedConstant(Node* constant) {
static_cast<int32_t>(OpParameter<int64_t>(constant->op()))));
break;
case IrOpcode::kHeapConstant:
// TODO(v8:8977): The HeapConstant remains as 64 bits. This does not
// affect the comparison and it will still work correctly. However, we are
// introducing a 64 bit value in the stream where a 32 bit one will
// suffice. Currently there is no "CompressedHeapConstant", and
// introducing a new opcode and handling it correctly throught the
// pipeline seems that it will involve quite a bit of work.
return constant;
return graph()->NewNode(
common()->CompressedHeapConstant(HeapConstantOf(constant->op())));
default:
UNREACHABLE();
}
......
......@@ -748,6 +748,11 @@ class MachineRepresentationChecker {
case MachineRepresentation::kCompressedPointer:
case MachineRepresentation::kCompressedSigned:
return;
case MachineRepresentation::kNone:
if (input->opcode() == IrOpcode::kCompressedHeapConstant) {
return;
}
break;
default:
break;
}
......@@ -851,6 +856,9 @@ class MachineRepresentationChecker {
case MachineRepresentation::kCompressedPointer:
return;
case MachineRepresentation::kNone: {
if (input->opcode() == IrOpcode::kCompressedHeapConstant) {
return;
}
std::ostringstream str;
str << "TypeError: node #" << input->id() << ":" << *input->op()
<< " is untyped.";
......
......@@ -45,6 +45,7 @@
V(NumberConstant) \
V(PointerConstant) \
V(HeapConstant) \
V(CompressedHeapConstant) \
V(RelocatableInt32Constant) \
V(RelocatableInt64Constant)
......
......@@ -798,6 +798,8 @@ Type Typer::Visitor::TypeHeapConstant(Node* node) {
return TypeConstant(HeapConstantOf(node->op()));
}
Type Typer::Visitor::TypeCompressedHeapConstant(Node* node) { UNREACHABLE(); }
Type Typer::Visitor::TypeExternalConstant(Node* node) {
return Type::ExternalPointer();
}
......
......@@ -431,6 +431,7 @@ void Verifier::Visitor::Check(Node* node, const AllNodes& all) {
CheckTypeIs(node, Type::Number());
break;
case IrOpcode::kHeapConstant:
case IrOpcode::kCompressedHeapConstant:
// Constants have no inputs.
CHECK_EQ(0, input_count);
// Type is anything.
......
......@@ -311,11 +311,6 @@ TEST_F(DecompressionEliminationTest,
TEST_F(DecompressionEliminationTest,
DecompressionConstantStoreElementHeapConstant) {
// TODO(v8:8977): Disabling HeapConstant until CompressedHeapConstant
// exists, since it breaks with verify CSA on.
if (COMPRESS_POINTERS_BOOL) {
return;
}
// Skip test if pointer compression is not enabled.
if (!COMPRESS_POINTERS_BOOL) {
return;
......@@ -373,9 +368,7 @@ TEST_F(DecompressionEliminationTest,
// Reduce.
Reduction r = Reduce(changeToCompressed);
ASSERT_TRUE(r.Changed());
// TODO(v8:8977): Change the IrOpcode here to kCompressedHeapConstant when
// that is in place.
EXPECT_EQ(r.replacement()->opcode(), IrOpcode::kHeapConstant);
EXPECT_EQ(r.replacement()->opcode(), IrOpcode::kCompressedHeapConstant);
}
}
}
......@@ -1015,11 +1008,6 @@ TEST_F(DecompressionEliminationTest, DecompressionConstantWord64Equal) {
}
TEST_F(DecompressionEliminationTest, DecompressionHeapConstantWord64Equal) {
// TODO(v8:8977): Disabling HeapConstant until CompressedHeapConstant
// exists, since it breaks with verify CSA on.
if (COMPRESS_POINTERS_BOOL) {
return;
}
// Skip test if pointer compression is not enabled
if (!COMPRESS_POINTERS_BOOL) {
return;
......
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