Skip to content

Commit

Permalink
[X86] Merge the different Jcc instructions for each condition code in…
Browse files Browse the repository at this point in the history
…to single instructions that store the condition code as an operand.

Summary:
This avoids needing an isel pattern for each condition code. And it removes translation switches for converting between Jcc instructions and condition codes.

Now the printer, encoder and disassembler take care of converting the immediate. We use InstAliases to handle the assembly matching. But we print using the asm string in the instruction definition. The instruction itself is marked IsCodeGenOnly=1 to hide it from the assembly parser.

Reviewers: spatel, lebedev.ri, courbet, gchatelet, RKSimon

Reviewed By: RKSimon

Subscribers: MatzeB, qcolombet, eraman, hiraditya, arphaman, llvm-commits

Tags: #llvm

Differential Revision: https://reviews.llvm.org/D60228

llvm-svn: 357802
  • Loading branch information
topperc committed Apr 5, 2019
1 parent 7323c2b commit 80aa229
Show file tree
Hide file tree
Showing 114 changed files with 515 additions and 560 deletions.
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/Disassembler/X86Disassembler.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -782,7 +782,7 @@ static bool translateOperand(MCInst &mcInst, const OperandSpecifier &operand,
translateRegister(mcInst, insn.opcodeRegister);
return false;
case ENCODING_CC:
mcInst.addOperand(MCOperand::createImm(insn.immediates[0]));
mcInst.addOperand(MCOperand::createImm(insn.immediates[1]));
return false;
case ENCODING_FP:
translateFPRegister(mcInst, insn.modRM & 7);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -1847,7 +1847,7 @@ static int readOperands(struct InternalInstruction* insn) {
return -1;
break;
case ENCODING_CC:
insn->immediates[0] = insn->opcode & 0xf;
insn->immediates[1] = insn->opcode & 0xf;
break;
case ENCODING_FP:
break;
Expand Down
34 changes: 2 additions & 32 deletions llvm/lib/Target/X86/MCTargetDesc/X86AsmBackend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -136,40 +136,10 @@ static unsigned getRelaxedOpcodeBranch(const MCInst &Inst, bool is16BitMode) {
switch (Op) {
default:
return Op;
case X86::JAE_1:
return (is16BitMode) ? X86::JAE_2 : X86::JAE_4;
case X86::JA_1:
return (is16BitMode) ? X86::JA_2 : X86::JA_4;
case X86::JBE_1:
return (is16BitMode) ? X86::JBE_2 : X86::JBE_4;
case X86::JB_1:
return (is16BitMode) ? X86::JB_2 : X86::JB_4;
case X86::JE_1:
return (is16BitMode) ? X86::JE_2 : X86::JE_4;
case X86::JGE_1:
return (is16BitMode) ? X86::JGE_2 : X86::JGE_4;
case X86::JG_1:
return (is16BitMode) ? X86::JG_2 : X86::JG_4;
case X86::JLE_1:
return (is16BitMode) ? X86::JLE_2 : X86::JLE_4;
case X86::JL_1:
return (is16BitMode) ? X86::JL_2 : X86::JL_4;
case X86::JCC_1:
return (is16BitMode) ? X86::JCC_2 : X86::JCC_4;
case X86::JMP_1:
return (is16BitMode) ? X86::JMP_2 : X86::JMP_4;
case X86::JNE_1:
return (is16BitMode) ? X86::JNE_2 : X86::JNE_4;
case X86::JNO_1:
return (is16BitMode) ? X86::JNO_2 : X86::JNO_4;
case X86::JNP_1:
return (is16BitMode) ? X86::JNP_2 : X86::JNP_4;
case X86::JNS_1:
return (is16BitMode) ? X86::JNS_2 : X86::JNS_4;
case X86::JO_1:
return (is16BitMode) ? X86::JO_2 : X86::JO_4;
case X86::JP_1:
return (is16BitMode) ? X86::JP_2 : X86::JP_4;
case X86::JS_1:
return (is16BitMode) ? X86::JS_2 : X86::JS_4;
}
}

Expand Down
5 changes: 5 additions & 0 deletions llvm/lib/Target/X86/MCTargetDesc/X86BaseInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -321,6 +321,10 @@ namespace X86II {
/// manual, this operand is described as pntr16:32 and pntr16:16
RawFrmImm16 = 8,

/// AddCCFrm - This form is used for Jcc that encode the condition code
/// in the lower 4 bits of the opcode.
AddCCFrm = 9,

/// MRM[0-7][rm] - These forms are used to represent instructions that use
/// a Mod/RM byte, and use the middle field to hold extended opcode
/// information. In the intel manual these are represented as /0, /1, ...
Expand Down Expand Up @@ -769,6 +773,7 @@ namespace X86II {
case X86II::RawFrmSrc:
case X86II::RawFrmDst:
case X86II::RawFrmDstSrc:
case X86II::AddCCFrm:
return -1;
case X86II::MRMDestMem:
return 0;
Expand Down
12 changes: 10 additions & 2 deletions llvm/lib/Target/X86/MCTargetDesc/X86MCCodeEmitter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1273,6 +1273,8 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
if ((TSFlags & X86II::OpMapMask) == X86II::ThreeDNow)
BaseOpcode = 0x0F; // Weird 3DNow! encoding.

unsigned OpcodeOffset = 0;

uint64_t Form = TSFlags & X86II::FormMask;
switch (Form) {
default: errs() << "FORM: " << Form << "\n";
Expand Down Expand Up @@ -1319,8 +1321,14 @@ encodeInstruction(const MCInst &MI, raw_ostream &OS,
EmitByte(BaseOpcode, CurByte, OS);
break;
}
case X86II::RawFrm: {
EmitByte(BaseOpcode, CurByte, OS);
case X86II::AddCCFrm: {
// This will be added to the opcode in the fallthrough.
OpcodeOffset = MI.getOperand(NumOps - 1).getImm();
assert(OpcodeOffset < 16 && "Unexpected opcode offset!");
--NumOps; // Drop the operand from the end.
LLVM_FALLTHROUGH;
case X86II::RawFrm:
EmitByte(BaseOpcode + OpcodeOffset, CurByte, OS);

if (!is64BitMode(STI) || !isPCRel32Branch(MI))
break;
Expand Down
2 changes: 1 addition & 1 deletion llvm/lib/Target/X86/X86CmovConversion.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ void X86CmovConverterPass::convertCmovInstsToBranches(
MBB->addSuccessor(SinkMBB);

// Create the conditional branch instruction.
BuildMI(MBB, DL, TII->get(X86::GetCondBranchFromCond(CC))).addMBB(SinkMBB);
BuildMI(MBB, DL, TII->get(X86::JCC_1)).addMBB(SinkMBB).addImm(CC);

// Add the sink block to the false block successors.
FalseMBB->addSuccessor(SinkMBB);
Expand Down
15 changes: 7 additions & 8 deletions llvm/lib/Target/X86/X86CondBrFolding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -225,10 +225,9 @@ void X86CondBrFolding::replaceBrDest(MachineBasicBlock *MBB,
MachineInstr *BrMI;
if (MBBInfo->TBB == OrigDest) {
BrMI = MBBInfo->BrInstr;
unsigned JNCC = GetCondBranchFromCond(MBBInfo->BranchCode);
MachineInstrBuilder MIB =
BuildMI(*MBB, BrMI, MBB->findDebugLoc(BrMI), TII->get(JNCC))
.addMBB(NewDest);
BuildMI(*MBB, BrMI, MBB->findDebugLoc(BrMI), TII->get(X86::JCC_1))
.addMBB(NewDest).addImm(MBBInfo->BranchCode);
MBBInfo->TBB = NewDest;
MBBInfo->BrInstr = MIB.getInstr();
} else { // Should be the unconditional jump stmt.
Expand All @@ -254,8 +253,8 @@ void X86CondBrFolding::fixupModifiedCond(MachineBasicBlock *MBB) {
MachineInstr *BrMI = MBBInfo->BrInstr;
X86::CondCode CC = MBBInfo->BranchCode;
MachineInstrBuilder MIB = BuildMI(*MBB, BrMI, MBB->findDebugLoc(BrMI),
TII->get(GetCondBranchFromCond(CC)))
.addMBB(MBBInfo->TBB);
TII->get(X86::JCC_1))
.addMBB(MBBInfo->TBB).addImm(CC);
BrMI->eraseFromParent();
MBBInfo->BrInstr = MIB.getInstr();

Expand Down Expand Up @@ -323,8 +322,8 @@ void X86CondBrFolding::optimizeCondBr(
llvm_unreachable("unexpected condtional code.");
}
BuildMI(*RootMBB, UncondBrI, RootMBB->findDebugLoc(UncondBrI),
TII->get(GetCondBranchFromCond(NewCC)))
.addMBB(RootMBBInfo->FBB);
TII->get(X86::JCC_1))
.addMBB(RootMBBInfo->FBB).addImm(NewCC);

// RootMBB: Jump to TargetMBB
BuildMI(*RootMBB, UncondBrI, RootMBB->findDebugLoc(UncondBrI),
Expand Down Expand Up @@ -512,7 +511,7 @@ X86CondBrFolding::analyzeMBB(MachineBasicBlock &MBB) {
if (I->isBranch()) {
if (TBB)
return nullptr;
CC = X86::getCondFromBranchOpc(I->getOpcode());
CC = X86::getCondFromBranch(*I);
switch (CC) {
default:
return nullptr;
Expand Down
18 changes: 9 additions & 9 deletions llvm/lib/Target/X86/X86ExpandPseudo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -100,19 +100,19 @@ void X86ExpandPseudo::ExpandICallBranchFunnel(
return NewMBB;
};

auto EmitCondJump = [&](unsigned Opcode, MachineBasicBlock *ThenMBB) {
BuildMI(*MBB, MBBI, DL, TII->get(Opcode)).addMBB(ThenMBB);
auto EmitCondJump = [&](unsigned CC, MachineBasicBlock *ThenMBB) {
BuildMI(*MBB, MBBI, DL, TII->get(X86::JCC_1)).addMBB(ThenMBB).addImm(CC);

auto *ElseMBB = CreateMBB();
MF->insert(InsPt, ElseMBB);
MBB = ElseMBB;
MBBI = MBB->end();
};

auto EmitCondJumpTarget = [&](unsigned Opcode, unsigned Target) {
auto EmitCondJumpTarget = [&](unsigned CC, unsigned Target) {
auto *ThenMBB = CreateMBB();
TargetMBBs.push_back({ThenMBB, Target});
EmitCondJump(Opcode, ThenMBB);
EmitCondJump(CC, ThenMBB);
};

auto EmitTailCall = [&](unsigned Target) {
Expand All @@ -129,23 +129,23 @@ void X86ExpandPseudo::ExpandICallBranchFunnel(

if (NumTargets == 2) {
CmpTarget(FirstTarget + 1);
EmitCondJumpTarget(X86::JB_1, FirstTarget);
EmitCondJumpTarget(X86::COND_B, FirstTarget);
EmitTailCall(FirstTarget + 1);
return;
}

if (NumTargets < 6) {
CmpTarget(FirstTarget + 1);
EmitCondJumpTarget(X86::JB_1, FirstTarget);
EmitCondJumpTarget(X86::JE_1, FirstTarget + 1);
EmitCondJumpTarget(X86::COND_B, FirstTarget);
EmitCondJumpTarget(X86::COND_E, FirstTarget + 1);
EmitBranchFunnel(FirstTarget + 2, NumTargets - 2);
return;
}

auto *ThenMBB = CreateMBB();
CmpTarget(FirstTarget + (NumTargets / 2));
EmitCondJump(X86::JB_1, ThenMBB);
EmitCondJumpTarget(X86::JE_1, FirstTarget + (NumTargets / 2));
EmitCondJump(X86::COND_B, ThenMBB);
EmitCondJumpTarget(X86::COND_E, FirstTarget + (NumTargets / 2));
EmitBranchFunnel(FirstTarget + (NumTargets / 2) + 1,
NumTargets - (NumTargets / 2) - 1);

Expand Down
28 changes: 12 additions & 16 deletions llvm/lib/Target/X86/X86FastISel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1690,26 +1690,24 @@ bool X86FastISel::X86SelectBranch(const Instruction *I) {
}

bool SwapArgs;
unsigned BranchOpc;
std::tie(CC, SwapArgs) = X86::getX86ConditionCode(Predicate);
assert(CC <= X86::LAST_VALID_COND && "Unexpected condition code.");

BranchOpc = X86::GetCondBranchFromCond(CC);
if (SwapArgs)
std::swap(CmpLHS, CmpRHS);

// Emit a compare of the LHS and RHS, setting the flags.
if (!X86FastEmitCompare(CmpLHS, CmpRHS, VT, CI->getDebugLoc()))
return false;

BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(BranchOpc))
.addMBB(TrueMBB);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JCC_1))
.addMBB(TrueMBB).addImm(CC);

// X86 requires a second branch to handle UNE (and OEQ, which is mapped
// to UNE above).
if (NeedExtraBranch) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JP_1))
.addMBB(TrueMBB);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JCC_1))
.addMBB(TrueMBB).addImm(X86::COND_P);
}

finishCondBranch(BI->getParent(), TrueMBB, FalseMBB);
Expand All @@ -1736,14 +1734,14 @@ bool X86FastISel::X86SelectBranch(const Instruction *I) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(TestOpc))
.addReg(OpReg).addImm(1);

unsigned JmpOpc = X86::JNE_1;
unsigned JmpCond = X86::COND_NE;
if (FuncInfo.MBB->isLayoutSuccessor(TrueMBB)) {
std::swap(TrueMBB, FalseMBB);
JmpOpc = X86::JE_1;
JmpCond = X86::COND_E;
}

BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(JmpOpc))
.addMBB(TrueMBB);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JCC_1))
.addMBB(TrueMBB).addImm(JmpCond);

finishCondBranch(BI->getParent(), TrueMBB, FalseMBB);
return true;
Expand All @@ -1756,10 +1754,8 @@ bool X86FastISel::X86SelectBranch(const Instruction *I) {
if (TmpReg == 0)
return false;

unsigned BranchOpc = X86::GetCondBranchFromCond(CC);

BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(BranchOpc))
.addMBB(TrueMBB);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JCC_1))
.addMBB(TrueMBB).addImm(CC);
finishCondBranch(BI->getParent(), TrueMBB, FalseMBB);
return true;
}
Expand All @@ -1783,8 +1779,8 @@ bool X86FastISel::X86SelectBranch(const Instruction *I) {
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::TEST8ri))
.addReg(OpReg)
.addImm(1);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JNE_1))
.addMBB(TrueMBB);
BuildMI(*FuncInfo.MBB, FuncInfo.InsertPt, DbgLoc, TII.get(X86::JCC_1))
.addMBB(TrueMBB).addImm(X86::COND_NE);
finishCondBranch(BI->getParent(), TrueMBB, FalseMBB);
return true;
}
Expand Down
16 changes: 7 additions & 9 deletions llvm/lib/Target/X86/X86FlagsCopyLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -251,13 +251,13 @@ static MachineBasicBlock &splitBlock(MachineBasicBlock &MBB,
"Split instruction must be in the split block!");
assert(SplitI.isBranch() &&
"Only designed to split a tail of branch instructions!");
assert(X86::getCondFromBranchOpc(SplitI.getOpcode()) != X86::COND_INVALID &&
assert(X86::getCondFromBranch(SplitI) != X86::COND_INVALID &&
"Must split on an actual jCC instruction!");

// Dig out the previous instruction to the split point.
MachineInstr &PrevI = *std::prev(SplitI.getIterator());
assert(PrevI.isBranch() && "Must split after a branch!");
assert(X86::getCondFromBranchOpc(PrevI.getOpcode()) != X86::COND_INVALID &&
assert(X86::getCondFromBranch(PrevI) != X86::COND_INVALID &&
"Must split after an actual jCC instruction!");
assert(!std::prev(PrevI.getIterator())->isTerminator() &&
"Must only have this one terminator prior to the split!");
Expand Down Expand Up @@ -587,13 +587,13 @@ bool X86FlagsCopyLoweringPass::runOnMachineFunction(MachineFunction &MF) {
// branch folding or black placement. As a consequence, we get to deal
// with the simpler formulation of conditional branches followed by tail
// calls.
if (X86::getCondFromBranchOpc(MI.getOpcode()) != X86::COND_INVALID) {
if (X86::getCondFromBranch(MI) != X86::COND_INVALID) {
auto JmpIt = MI.getIterator();
do {
JmpIs.push_back(&*JmpIt);
++JmpIt;
} while (JmpIt != UseMBB.instr_end() &&
X86::getCondFromBranchOpc(JmpIt->getOpcode()) !=
X86::getCondFromBranch(*JmpIt) !=
X86::COND_INVALID);
break;
}
Expand Down Expand Up @@ -863,7 +863,7 @@ void X86FlagsCopyLoweringPass::rewriteCondJmp(
MachineBasicBlock &TestMBB, MachineBasicBlock::iterator TestPos,
DebugLoc TestLoc, MachineInstr &JmpI, CondRegArray &CondRegs) {
// First get the register containing this specific condition.
X86::CondCode Cond = X86::getCondFromBranchOpc(JmpI.getOpcode());
X86::CondCode Cond = X86::getCondFromBranch(JmpI);
unsigned CondReg;
bool Inverted;
std::tie(CondReg, Inverted) =
Expand All @@ -876,10 +876,8 @@ void X86FlagsCopyLoweringPass::rewriteCondJmp(

// Rewrite the jump to use the !ZF flag from the test, and kill its use of
// flags afterward.
JmpI.setDesc(TII->get(
X86::GetCondBranchFromCond(Inverted ? X86::COND_E : X86::COND_NE)));
const int ImplicitEFLAGSOpIdx = 1;
JmpI.getOperand(ImplicitEFLAGSOpIdx).setIsKill(true);
JmpI.getOperand(1).setImm(Inverted ? X86::COND_E : X86::COND_NE);
JmpI.findRegisterUseOperand(X86::EFLAGS)->setIsKill(true);
LLVM_DEBUG(dbgs() << " fixed jCC: "; JmpI.dump());
}

Expand Down
10 changes: 5 additions & 5 deletions llvm/lib/Target/X86/X86FrameLowering.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -673,7 +673,7 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF,
.addReg(X86::GS);
BuildMI(&MBB, DL, TII.get(X86::CMP64rr)).addReg(FinalReg).addReg(LimitReg);
// Jump if the desired stack pointer is at or above the stack limit.
BuildMI(&MBB, DL, TII.get(X86::JAE_1)).addMBB(ContinueMBB);
BuildMI(&MBB, DL, TII.get(X86::JCC_1)).addMBB(ContinueMBB).addImm(X86::COND_AE);

// Add code to roundMBB to round the final stack pointer to a page boundary.
RoundMBB->addLiveIn(FinalReg);
Expand Down Expand Up @@ -710,7 +710,7 @@ void X86FrameLowering::emitStackProbeInline(MachineFunction &MF,
BuildMI(LoopMBB, DL, TII.get(X86::CMP64rr))
.addReg(RoundedReg)
.addReg(ProbeReg);
BuildMI(LoopMBB, DL, TII.get(X86::JNE_1)).addMBB(LoopMBB);
BuildMI(LoopMBB, DL, TII.get(X86::JCC_1)).addMBB(LoopMBB).addImm(X86::COND_NE);

MachineBasicBlock::iterator ContinueMBBI = ContinueMBB->getFirstNonPHI();

Expand Down Expand Up @@ -2416,7 +2416,7 @@ void X86FrameLowering::adjustForSegmentedStacks(

// This jump is taken if SP >= (Stacklet Limit + Stack Space required).
// It jumps to normal execution of the function body.
BuildMI(checkMBB, DL, TII.get(X86::JA_1)).addMBB(&PrologueMBB);
BuildMI(checkMBB, DL, TII.get(X86::JCC_1)).addMBB(&PrologueMBB).addImm(X86::COND_A);

// On 32 bit we first push the arguments size and then the frame size. On 64
// bit, we pass the stack frame size in r10 and the argument size in r11.
Expand Down Expand Up @@ -2646,7 +2646,7 @@ void X86FrameLowering::adjustForHiPEPrologue(
// SPLimitOffset is in a fixed heap location (pointed by BP).
addRegOffset(BuildMI(stackCheckMBB, DL, TII.get(CMPop))
.addReg(ScratchReg), PReg, false, SPLimitOffset);
BuildMI(stackCheckMBB, DL, TII.get(X86::JAE_1)).addMBB(&PrologueMBB);
BuildMI(stackCheckMBB, DL, TII.get(X86::JCC_1)).addMBB(&PrologueMBB).addImm(X86::COND_AE);

// Create new MBB for IncStack:
BuildMI(incStackMBB, DL, TII.get(CALLop)).
Expand All @@ -2655,7 +2655,7 @@ void X86FrameLowering::adjustForHiPEPrologue(
SPReg, false, -MaxStack);
addRegOffset(BuildMI(incStackMBB, DL, TII.get(CMPop))
.addReg(ScratchReg), PReg, false, SPLimitOffset);
BuildMI(incStackMBB, DL, TII.get(X86::JLE_1)).addMBB(incStackMBB);
BuildMI(incStackMBB, DL, TII.get(X86::JCC_1)).addMBB(incStackMBB).addImm(X86::COND_LE);

stackCheckMBB->addSuccessor(&PrologueMBB, {99, 100});
stackCheckMBB->addSuccessor(incStackMBB, {1, 100});
Expand Down
Loading

0 comments on commit 80aa229

Please sign in to comment.