PPC/s390: [turbofan] Masking/poisoning in codegen (optimized code, arm)
Port 2579951648
Original Commit Message:
This introduces masking of loads with speculation bit during code generation.
At the moment, this is done only under the
--branch-load-poisoning flag, and this CL enlarges the set of supported
platforms from {x64} to {x64, arm}.
Overview of changes:
- new register configuration configuration with one register reserved for
the speculation poison/mask (kSpeculationPoisonRegister).
- in codegen, we introduce an update to the poison register at the starts
of all successors of branches (and deopts) that are marked as safety
branches (deopts).
- in memory optimizer, we lower all field and element loads to PoisonedLoads.
- poisoned loads are then masked in codegen with the poison register.
* only integer loads are masked at the moment.
R=tebbi@chromium.org, joransiu@ca.ibm.com, bjaideep@ca.ibm.com, michael_dawson@ca.ibm.com
BUG=
LOG=N
Change-Id: Idda9bf06133d8999290cda5bcf6333c064b3e6dc
Reviewed-on: https://chromium-review.googlesource.com/927163
Commit-Queue: Junliang Yan <jyan@ca.ibm.com>
Reviewed-by: Joran Siu <joransiu@ca.ibm.com>
Cr-Commit-Position: refs/heads/master@{#51528}
This commit is contained in:
parent
a988f2ecde
commit
11805b137d
@ -272,6 +272,16 @@ Condition FlagsConditionToCondition(FlagsCondition condition, ArchOpcode op) {
|
||||
UNREACHABLE();
|
||||
}
|
||||
|
||||
void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, Instruction* instr,
|
||||
PPCOperandConverter& i) {
|
||||
const MemoryAccessMode access_mode =
|
||||
static_cast<MemoryAccessMode>(MiscField::decode(instr->opcode()));
|
||||
if (access_mode == kMemoryAccessPoisoned) {
|
||||
Register value = i.OutputRegister();
|
||||
codegen->tasm()->and_(value, value, kSpeculationPoisonRegister);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
#define ASSEMBLE_FLOAT_UNOP_RC(asm_instr, round) \
|
||||
@ -1840,26 +1850,33 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
#endif
|
||||
case kPPC_LoadWordU8:
|
||||
ASSEMBLE_LOAD_INTEGER(lbz, lbzx);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kPPC_LoadWordS8:
|
||||
ASSEMBLE_LOAD_INTEGER(lbz, lbzx);
|
||||
__ extsb(i.OutputRegister(), i.OutputRegister());
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kPPC_LoadWordU16:
|
||||
ASSEMBLE_LOAD_INTEGER(lhz, lhzx);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kPPC_LoadWordS16:
|
||||
ASSEMBLE_LOAD_INTEGER(lha, lhax);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kPPC_LoadWordU32:
|
||||
ASSEMBLE_LOAD_INTEGER(lwz, lwzx);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kPPC_LoadWordS32:
|
||||
ASSEMBLE_LOAD_INTEGER(lwa, lwax);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
#if V8_TARGET_ARCH_PPC64
|
||||
case kPPC_LoadWord64:
|
||||
ASSEMBLE_LOAD_INTEGER(ld, ldx);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
#endif
|
||||
case kPPC_LoadFloat32:
|
||||
@ -1965,7 +1982,16 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
|
||||
|
||||
void CodeGenerator::AssembleBranchPoisoning(FlagsCondition condition,
|
||||
Instruction* instr) {
|
||||
UNREACHABLE();
|
||||
// TODO(John) Handle float comparisons (kUnordered[Not]Equal).
|
||||
if (condition == kUnorderedEqual || condition == kUnorderedNotEqual) {
|
||||
return;
|
||||
}
|
||||
|
||||
ArchOpcode op = instr->arch_opcode();
|
||||
condition = NegateFlagsCondition(condition);
|
||||
__ li(kScratchReg, Operand::Zero());
|
||||
__ isel(FlagsConditionToCondition(condition, op), kSpeculationPoisonRegister,
|
||||
kScratchReg, kSpeculationPoisonRegister, cr0);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
@ -2212,6 +2238,7 @@ void CodeGenerator::AssembleConstructFrame() {
|
||||
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
|
||||
osr_pc_offset_ = __ pc_offset();
|
||||
shrink_slots -= osr_helper()->UnoptimizedFrameSlots();
|
||||
InitializePoisonForLoadsIfNeeded();
|
||||
}
|
||||
|
||||
const RegList double_saves = call_descriptor->CalleeSavedFPRegisters();
|
||||
|
@ -2259,7 +2259,7 @@ InstructionSelector::AlignmentRequirements() {
|
||||
}
|
||||
|
||||
// static
|
||||
bool InstructionSelector::SupportsSpeculationPoisoning() { return false; }
|
||||
bool InstructionSelector::SupportsSpeculationPoisoning() { return true; }
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
|
@ -984,6 +984,16 @@ void AdjustStackPointerForTailCall(
|
||||
}
|
||||
}
|
||||
|
||||
void EmitWordLoadPoisoningIfNeeded(CodeGenerator* codegen, Instruction* instr,
|
||||
S390OperandConverter& i) {
|
||||
const MemoryAccessMode access_mode =
|
||||
static_cast<MemoryAccessMode>(MiscField::decode(instr->opcode()));
|
||||
if (access_mode == kMemoryAccessPoisoned) {
|
||||
Register value = i.OutputRegister();
|
||||
codegen->tasm()->AndP(value, kSpeculationPoisonRegister);
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
void CodeGenerator::AssembleTailCallBeforeGap(Instruction* instr,
|
||||
@ -2142,6 +2152,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
break;
|
||||
case kS390_LoadWordS8:
|
||||
ASSEMBLE_LOAD_INTEGER(LoadB);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_BitcastFloat32ToInt32:
|
||||
ASSEMBLE_UNARY_OP(R_DInstr(MovFloatToInt), R_MInstr(LoadlW), nullInstr);
|
||||
@ -2159,27 +2170,35 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
#endif
|
||||
case kS390_LoadWordU8:
|
||||
ASSEMBLE_LOAD_INTEGER(LoadlB);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadWordU16:
|
||||
ASSEMBLE_LOAD_INTEGER(LoadLogicalHalfWordP);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadWordS16:
|
||||
ASSEMBLE_LOAD_INTEGER(LoadHalfWordP);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadWordU32:
|
||||
ASSEMBLE_LOAD_INTEGER(LoadlW);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadWordS32:
|
||||
ASSEMBLE_LOAD_INTEGER(LoadW);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadReverse16:
|
||||
ASSEMBLE_LOAD_INTEGER(lrvh);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadReverse32:
|
||||
ASSEMBLE_LOAD_INTEGER(lrv);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadReverse64:
|
||||
ASSEMBLE_LOAD_INTEGER(lrvg);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadReverse16RR:
|
||||
__ lrvr(i.OutputRegister(), i.InputRegister(0));
|
||||
@ -2193,6 +2212,7 @@ CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
|
||||
break;
|
||||
case kS390_LoadWord64:
|
||||
ASSEMBLE_LOAD_INTEGER(lg);
|
||||
EmitWordLoadPoisoningIfNeeded(this, instr, i);
|
||||
break;
|
||||
case kS390_LoadAndTestWord32: {
|
||||
ASSEMBLE_LOADANDTEST32(ltr, lt_z);
|
||||
@ -2427,7 +2447,15 @@ void CodeGenerator::AssembleArchBranch(Instruction* instr, BranchInfo* branch) {
|
||||
|
||||
void CodeGenerator::AssembleBranchPoisoning(FlagsCondition condition,
|
||||
Instruction* instr) {
|
||||
UNREACHABLE();
|
||||
// TODO(John) Handle float comparisons (kUnordered[Not]Equal).
|
||||
if (condition == kUnorderedEqual || condition == kUnorderedNotEqual) {
|
||||
return;
|
||||
}
|
||||
|
||||
condition = NegateFlagsCondition(condition);
|
||||
__ XorP(r0, r0);
|
||||
__ LoadOnConditionP(FlagsConditionToCondition(condition, kArchNop),
|
||||
kSpeculationPoisonRegister, r0);
|
||||
}
|
||||
|
||||
void CodeGenerator::AssembleArchDeoptBranch(Instruction* instr,
|
||||
@ -2633,6 +2661,7 @@ void CodeGenerator::AssembleConstructFrame() {
|
||||
if (FLAG_code_comments) __ RecordComment("-- OSR entrypoint --");
|
||||
osr_pc_offset_ = __ pc_offset();
|
||||
shrink_slots -= osr_helper()->UnoptimizedFrameSlots();
|
||||
InitializePoisonForLoadsIfNeeded();
|
||||
}
|
||||
|
||||
const RegList double_saves = call_descriptor->CalleeSavedFPRegisters();
|
||||
|
@ -2591,7 +2591,7 @@ InstructionSelector::AlignmentRequirements() {
|
||||
}
|
||||
|
||||
// static
|
||||
bool InstructionSelector::SupportsSpeculationPoisoning() { return false; }
|
||||
bool InstructionSelector::SupportsSpeculationPoisoning() { return true; }
|
||||
|
||||
} // namespace compiler
|
||||
} // namespace internal
|
||||
|
@ -449,6 +449,11 @@ void CEntryStub::Generate(MacroAssembler* masm) {
|
||||
__ StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
__ bind(&skip);
|
||||
|
||||
// Reset the masking register.
|
||||
if (FLAG_branch_load_poisoning) {
|
||||
__ ResetSpeculationPoisonRegister();
|
||||
}
|
||||
|
||||
// Compute the handler entry address and jump to it.
|
||||
ConstantPoolUnavailableScope constant_pool_unavailable(masm);
|
||||
__ mov(ip, Operand(pending_handler_entrypoint_address));
|
||||
|
@ -2939,7 +2939,9 @@ bool AreAliased(DoubleRegister reg1, DoubleRegister reg2, DoubleRegister reg3,
|
||||
}
|
||||
#endif
|
||||
|
||||
void TurboAssembler::ResetSpeculationPoisonRegister() { UNREACHABLE(); }
|
||||
void TurboAssembler::ResetSpeculationPoisonRegister() {
|
||||
mov(kSpeculationPoisonRegister, Operand(-1));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
@ -435,6 +435,11 @@ void CEntryStub::Generate(MacroAssembler* masm) {
|
||||
__ StoreP(cp, MemOperand(fp, StandardFrameConstants::kContextOffset));
|
||||
__ bind(&skip);
|
||||
|
||||
// Reset the masking register.
|
||||
if (FLAG_branch_load_poisoning) {
|
||||
__ ResetSpeculationPoisonRegister();
|
||||
}
|
||||
|
||||
// Compute the handler entry address and jump to it.
|
||||
__ mov(r3, Operand(pending_handler_entrypoint_address));
|
||||
__ LoadP(r3, MemOperand(r3));
|
||||
|
@ -4284,7 +4284,9 @@ bool AreAliased(DoubleRegister reg1, DoubleRegister reg2, DoubleRegister reg3,
|
||||
}
|
||||
#endif
|
||||
|
||||
void TurboAssembler::ResetSpeculationPoisonRegister() { UNREACHABLE(); }
|
||||
void TurboAssembler::ResetSpeculationPoisonRegister() {
|
||||
mov(kSpeculationPoisonRegister, Operand(-1));
|
||||
}
|
||||
|
||||
} // namespace internal
|
||||
} // namespace v8
|
||||
|
Loading…
Reference in New Issue
Block a user