Commit 3d3ef0d3 authored by Santiago Aboy Solanes's avatar Santiago Aboy Solanes Committed by Commit Bot

[ptr-compr][codegen] Combine loads and decompressions with poison too

Also add the poison to x64 decompresses which were missing.

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:7703
Change-Id: I87fd8e56ad8132b4996749be034093566bb88301
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1700061
Commit-Queue: Santiago Aboy Solanes <solanes@chromium.org>
Reviewed-by: 's avatarSigurd Schneider <sigurds@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62743}
parent 48da24bb
...@@ -1646,11 +1646,16 @@ void InstructionSelector::VisitChangeTaggedSignedToCompressedSigned( ...@@ -1646,11 +1646,16 @@ void InstructionSelector::VisitChangeTaggedSignedToCompressedSigned(
void InstructionSelector::VisitChangeCompressedToTagged(Node* node) { void InstructionSelector::VisitChangeCompressedToTagged(Node* node) {
Arm64OperandGenerator g(this); Arm64OperandGenerator g(this);
Node* const value = node->InputAt(0); Node* const value = node->InputAt(0);
if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) { if ((value->opcode() == IrOpcode::kLoad ||
// TODO(v8:7703): Make this work with poisoned loads as well. value->opcode() == IrOpcode::kPoisonedLoad) &&
CanCover(node, value)) {
DCHECK_EQ(LoadRepresentationOf(value->op()).representation(), DCHECK_EQ(LoadRepresentationOf(value->op()).representation(),
MachineRepresentation::kCompressed); MachineRepresentation::kCompressed);
InstructionCode opcode = kArm64LdrDecompressAnyTagged; InstructionCode opcode = kArm64LdrDecompressAnyTagged;
if (value->opcode() == IrOpcode::kPoisonedLoad) {
CHECK_NE(poisoning_level_, PoisoningMitigationLevel::kDontPoison);
opcode |= MiscField::encode(kMemoryAccessPoisoned);
}
ImmediateMode immediate_mode = kLoadStoreImm32; ImmediateMode immediate_mode = kLoadStoreImm32;
MachineRepresentation rep = MachineRepresentation::kCompressed; MachineRepresentation rep = MachineRepresentation::kCompressed;
EmitLoad(this, value, opcode, immediate_mode, rep, node); EmitLoad(this, value, opcode, immediate_mode, rep, node);
...@@ -1663,10 +1668,16 @@ void InstructionSelector::VisitChangeCompressedPointerToTaggedPointer( ...@@ -1663,10 +1668,16 @@ void InstructionSelector::VisitChangeCompressedPointerToTaggedPointer(
Node* node) { Node* node) {
Arm64OperandGenerator g(this); Arm64OperandGenerator g(this);
Node* const value = node->InputAt(0); Node* const value = node->InputAt(0);
if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) { if ((value->opcode() == IrOpcode::kLoad ||
value->opcode() == IrOpcode::kPoisonedLoad) &&
CanCover(node, value)) {
DCHECK_EQ(LoadRepresentationOf(value->op()).representation(), DCHECK_EQ(LoadRepresentationOf(value->op()).representation(),
MachineRepresentation::kCompressedPointer); MachineRepresentation::kCompressedPointer);
InstructionCode opcode = kArm64LdrDecompressTaggedPointer; InstructionCode opcode = kArm64LdrDecompressTaggedPointer;
if (value->opcode() == IrOpcode::kPoisonedLoad) {
CHECK_NE(poisoning_level_, PoisoningMitigationLevel::kDontPoison);
opcode |= MiscField::encode(kMemoryAccessPoisoned);
}
ImmediateMode immediate_mode = kLoadStoreImm32; ImmediateMode immediate_mode = kLoadStoreImm32;
MachineRepresentation rep = MachineRepresentation::kCompressedPointer; MachineRepresentation rep = MachineRepresentation::kCompressedPointer;
EmitLoad(this, value, opcode, immediate_mode, rep, node); EmitLoad(this, value, opcode, immediate_mode, rep, node);
...@@ -1680,10 +1691,16 @@ void InstructionSelector::VisitChangeCompressedSignedToTaggedSigned( ...@@ -1680,10 +1691,16 @@ void InstructionSelector::VisitChangeCompressedSignedToTaggedSigned(
Node* node) { Node* node) {
Arm64OperandGenerator g(this); Arm64OperandGenerator g(this);
Node* const value = node->InputAt(0); Node* const value = node->InputAt(0);
if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) { if ((value->opcode() == IrOpcode::kLoad ||
value->opcode() == IrOpcode::kPoisonedLoad) &&
CanCover(node, value)) {
DCHECK_EQ(LoadRepresentationOf(value->op()).representation(), DCHECK_EQ(LoadRepresentationOf(value->op()).representation(),
MachineRepresentation::kCompressedSigned); MachineRepresentation::kCompressedSigned);
InstructionCode opcode = kArm64LdrDecompressTaggedSigned; InstructionCode opcode = kArm64LdrDecompressTaggedSigned;
if (value->opcode() == IrOpcode::kPoisonedLoad) {
CHECK_NE(poisoning_level_, PoisoningMitigationLevel::kDontPoison);
opcode |= MiscField::encode(kMemoryAccessPoisoned);
}
ImmediateMode immediate_mode = kLoadStoreImm32; ImmediateMode immediate_mode = kLoadStoreImm32;
MachineRepresentation rep = MachineRepresentation::kCompressedSigned; MachineRepresentation rep = MachineRepresentation::kCompressedSigned;
EmitLoad(this, value, opcode, immediate_mode, rep, node); EmitLoad(this, value, opcode, immediate_mode, rep, node);
......
...@@ -608,6 +608,8 @@ class V8_EXPORT_PRIVATE InstructionSelector final { ...@@ -608,6 +608,8 @@ class V8_EXPORT_PRIVATE InstructionSelector final {
MACHINE_SIMD_OP_LIST(DECLARE_GENERATOR) MACHINE_SIMD_OP_LIST(DECLARE_GENERATOR)
#undef DECLARE_GENERATOR #undef DECLARE_GENERATOR
// Visit the load node with a value and opcode to replace with.
void VisitLoad(Node* node, Node* value, InstructionCode opcode);
void VisitFinishRegion(Node* node); void VisitFinishRegion(Node* node);
void VisitParameter(Node* node); void VisitParameter(Node* node);
void VisitIfException(Node* node); void VisitIfException(Node* node);
......
...@@ -1953,16 +1953,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1953,16 +1953,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kX64MovqDecompressTaggedSigned: { case kX64MovqDecompressTaggedSigned: {
CHECK(instr->HasOutput()); CHECK(instr->HasOutput());
__ DecompressTaggedSigned(i.OutputRegister(), i.MemoryOperand()); __ DecompressTaggedSigned(i.OutputRegister(), i.MemoryOperand());
EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i);
break; break;
} }
case kX64MovqDecompressTaggedPointer: { case kX64MovqDecompressTaggedPointer: {
CHECK(instr->HasOutput()); CHECK(instr->HasOutput());
__ DecompressTaggedPointer(i.OutputRegister(), i.MemoryOperand()); __ DecompressTaggedPointer(i.OutputRegister(), i.MemoryOperand());
EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i);
break; break;
} }
case kX64MovqDecompressAnyTagged: { case kX64MovqDecompressAnyTagged: {
CHECK(instr->HasOutput()); CHECK(instr->HasOutput());
__ DecompressAnyTagged(i.OutputRegister(), i.MemoryOperand()); __ DecompressAnyTagged(i.OutputRegister(), i.MemoryOperand());
EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i);
break; break;
} }
case kX64MovqCompressTagged: { case kX64MovqCompressTagged: {
...@@ -1979,16 +1982,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction( ...@@ -1979,16 +1982,19 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
case kX64DecompressSigned: { case kX64DecompressSigned: {
CHECK(instr->HasOutput()); CHECK(instr->HasOutput());
ASSEMBLE_MOVX(DecompressTaggedSigned); ASSEMBLE_MOVX(DecompressTaggedSigned);
EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i);
break; break;
} }
case kX64DecompressPointer: { case kX64DecompressPointer: {
CHECK(instr->HasOutput()); CHECK(instr->HasOutput());
ASSEMBLE_MOVX(DecompressTaggedPointer); ASSEMBLE_MOVX(DecompressTaggedPointer);
EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i);
break; break;
} }
case kX64DecompressAny: { case kX64DecompressAny: {
CHECK(instr->HasOutput()); CHECK(instr->HasOutput());
ASSEMBLE_MOVX(DecompressAnyTagged); ASSEMBLE_MOVX(DecompressAnyTagged);
EmitWordLoadPoisoningIfNeeded(this, opcode, instr, i);
break; break;
} }
case kX64CompressSigned: // Fall through. case kX64CompressSigned: // Fall through.
......
...@@ -314,16 +314,14 @@ void InstructionSelector::VisitAbortCSAAssert(Node* node) { ...@@ -314,16 +314,14 @@ void InstructionSelector::VisitAbortCSAAssert(Node* node) {
Emit(kArchAbortCSAAssert, g.NoOutput(), g.UseFixed(node->InputAt(0), rdx)); Emit(kArchAbortCSAAssert, g.NoOutput(), g.UseFixed(node->InputAt(0), rdx));
} }
void InstructionSelector::VisitLoad(Node* node) { void InstructionSelector::VisitLoad(Node* node, Node* value,
LoadRepresentation load_rep = LoadRepresentationOf(node->op()); InstructionCode opcode) {
X64OperandGenerator g(this); X64OperandGenerator g(this);
ArchOpcode opcode = GetLoadOpcode(load_rep);
InstructionOperand outputs[] = {g.DefineAsRegister(node)}; InstructionOperand outputs[] = {g.DefineAsRegister(node)};
InstructionOperand inputs[3]; InstructionOperand inputs[3];
size_t input_count = 0; size_t input_count = 0;
AddressingMode mode = AddressingMode mode =
g.GetEffectiveAddressMemoryOperand(node, inputs, &input_count); g.GetEffectiveAddressMemoryOperand(value, inputs, &input_count);
InstructionCode code = opcode | AddressingModeField::encode(mode); InstructionCode code = opcode | AddressingModeField::encode(mode);
if (node->opcode() == IrOpcode::kProtectedLoad) { if (node->opcode() == IrOpcode::kProtectedLoad) {
code |= MiscField::encode(kMemoryAccessProtected); code |= MiscField::encode(kMemoryAccessProtected);
...@@ -334,6 +332,11 @@ void InstructionSelector::VisitLoad(Node* node) { ...@@ -334,6 +332,11 @@ void InstructionSelector::VisitLoad(Node* node) {
Emit(code, 1, outputs, input_count, inputs); Emit(code, 1, outputs, input_count, inputs);
} }
void InstructionSelector::VisitLoad(Node* node) {
LoadRepresentation load_rep = LoadRepresentationOf(node->op());
VisitLoad(node, node, GetLoadOpcode(load_rep));
}
void InstructionSelector::VisitPoisonedLoad(Node* node) { VisitLoad(node); } void InstructionSelector::VisitPoisonedLoad(Node* node) { VisitLoad(node); }
void InstructionSelector::VisitProtectedLoad(Node* node) { VisitLoad(node); } void InstructionSelector::VisitProtectedLoad(Node* node) { VisitLoad(node); }
...@@ -1255,60 +1258,45 @@ void InstructionSelector::VisitChangeTaggedSignedToCompressedSigned( ...@@ -1255,60 +1258,45 @@ void InstructionSelector::VisitChangeTaggedSignedToCompressedSigned(
} }
void InstructionSelector::VisitChangeCompressedToTagged(Node* node) { void InstructionSelector::VisitChangeCompressedToTagged(Node* node) {
X64OperandGenerator g(this);
Node* const value = node->InputAt(0); Node* const value = node->InputAt(0);
if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) { if ((value->opcode() == IrOpcode::kLoad ||
value->opcode() == IrOpcode::kPoisonedLoad) &&
CanCover(node, value)) {
DCHECK_EQ(LoadRepresentationOf(value->op()).representation(), DCHECK_EQ(LoadRepresentationOf(value->op()).representation(),
MachineRepresentation::kCompressed); MachineRepresentation::kCompressed);
InstructionCode opcode = kX64MovqDecompressAnyTagged; VisitLoad(node, value, kX64MovqDecompressAnyTagged);
InstructionOperand outputs[] = {g.DefineAsRegister(node)};
size_t input_count = 0;
InstructionOperand inputs[3];
AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
node->InputAt(0), inputs, &input_count);
opcode |= AddressingModeField::encode(mode);
Emit(opcode, 1, outputs, input_count, inputs);
} else { } else {
X64OperandGenerator g(this);
Emit(kX64DecompressAny, g.DefineAsRegister(node), g.Use(value)); Emit(kX64DecompressAny, g.DefineAsRegister(node), g.Use(value));
} }
} }
void InstructionSelector::VisitChangeCompressedPointerToTaggedPointer( void InstructionSelector::VisitChangeCompressedPointerToTaggedPointer(
Node* node) { Node* node) {
X64OperandGenerator g(this);
Node* const value = node->InputAt(0); Node* const value = node->InputAt(0);
if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) { if ((value->opcode() == IrOpcode::kLoad ||
value->opcode() == IrOpcode::kPoisonedLoad) &&
CanCover(node, value)) {
DCHECK_EQ(LoadRepresentationOf(value->op()).representation(), DCHECK_EQ(LoadRepresentationOf(value->op()).representation(),
MachineRepresentation::kCompressedPointer); MachineRepresentation::kCompressedPointer);
InstructionCode opcode = kX64MovqDecompressTaggedPointer; VisitLoad(node, value, kX64MovqDecompressTaggedPointer);
InstructionOperand outputs[] = {g.DefineAsRegister(node)};
size_t input_count = 0;
InstructionOperand inputs[3];
AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
node->InputAt(0), inputs, &input_count);
opcode |= AddressingModeField::encode(mode);
Emit(opcode, 1, outputs, input_count, inputs);
} else { } else {
X64OperandGenerator g(this);
Emit(kX64DecompressPointer, g.DefineAsRegister(node), g.Use(value)); Emit(kX64DecompressPointer, g.DefineAsRegister(node), g.Use(value));
} }
} }
void InstructionSelector::VisitChangeCompressedSignedToTaggedSigned( void InstructionSelector::VisitChangeCompressedSignedToTaggedSigned(
Node* node) { Node* node) {
X64OperandGenerator g(this);
Node* const value = node->InputAt(0); Node* const value = node->InputAt(0);
if (value->opcode() == IrOpcode::kLoad && CanCover(node, value)) { if ((value->opcode() == IrOpcode::kLoad ||
value->opcode() == IrOpcode::kPoisonedLoad) &&
CanCover(node, value)) {
DCHECK_EQ(LoadRepresentationOf(value->op()).representation(), DCHECK_EQ(LoadRepresentationOf(value->op()).representation(),
MachineRepresentation::kCompressedSigned); MachineRepresentation::kCompressedSigned);
InstructionCode opcode = kX64MovqDecompressTaggedSigned; VisitLoad(node, value, kX64MovqDecompressTaggedSigned);
InstructionOperand outputs[] = {g.DefineAsRegister(node)};
size_t input_count = 0;
InstructionOperand inputs[3];
AddressingMode mode = g.GetEffectiveAddressMemoryOperand(
node->InputAt(0), inputs, &input_count);
opcode |= AddressingModeField::encode(mode);
Emit(opcode, 1, outputs, input_count, inputs);
} else { } else {
X64OperandGenerator g(this);
Emit(kX64DecompressSigned, g.DefineAsRegister(node), g.Use(value)); Emit(kX64DecompressSigned, g.DefineAsRegister(node), g.Use(value));
} }
} }
......
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