Commit d666faeb authored by Hao Xu's avatar Hao Xu Committed by V8 LUCI CQ

[x64] Transform setcc + movzxbl into xorl + setcc

xorl + setcc is more efficient than setcc + movzxbl and encodes one byte
shorter.

Change-Id: Ib6679ce9ab0ac0d34701daba5c3d4d8bb57a8fc6
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/3492946Reviewed-by: 's avatarTobias Tebbi <tebbi@chromium.org>
Commit-Queue: Hao A Xu <hao.a.xu@intel.com>
Cr-Commit-Position: refs/heads/main@{#79377}
parent c6f6626d
......@@ -1175,12 +1175,37 @@ void CodeGenerator::BailoutIfDeoptimized() {
RelocInfo::CODE_TARGET, not_zero);
}
bool ShouldClearOutputRegisterBeforeInstruction(CodeGenerator* g,
Instruction* instr) {
X64OperandConverter i(g, instr);
FlagsMode mode = FlagsModeField::decode(instr->opcode());
if (mode == kFlags_set) {
FlagsCondition condition = FlagsConditionField::decode(instr->opcode());
if (condition != kUnorderedEqual && condition != kUnorderedNotEqual) {
Register reg = i.OutputRegister(instr->OutputCount() - 1);
// Do not clear output register when it is also input register.
for (size_t index = 0; index < instr->InputCount(); ++index) {
if (HasRegisterInput(instr, index) && reg == i.InputRegister(index))
return false;
}
return true;
}
}
return false;
}
// Assembles an instruction after register allocation, producing machine code.
CodeGenerator::CodeGenResult CodeGenerator::AssembleArchInstruction(
Instruction* instr) {
X64OperandConverter i(this, instr);
InstructionCode opcode = instr->opcode();
ArchOpcode arch_opcode = ArchOpcodeField::decode(opcode);
if (ShouldClearOutputRegisterBeforeInstruction(this, instr)) {
// Transform setcc + movzxbl into xorl + setcc to avoid register stall and
// encode one byte shorter.
Register reg = i.OutputRegister(instr->OutputCount() - 1);
__ xorl(reg, reg);
}
switch (arch_opcode) {
case kArchCallCodeObject: {
if (HasImmediateInput(instr, 0)) {
......@@ -4473,7 +4498,9 @@ void CodeGenerator::AssembleArchBoolean(Instruction* instr,
}
__ bind(&check);
__ setcc(FlagsConditionToCondition(condition), reg);
__ movzxbl(reg, reg);
if (!ShouldClearOutputRegisterBeforeInstruction(this, instr)) {
__ movzxbl(reg, reg);
}
__ bind(&done);
}
......
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