58 #define DEBUG_TYPE "x86-condbr-folding" 60 STATISTIC(NumFixedCondBrs,
"Number of x86 condbr folded");
68 StringRef getPassName()
const override {
return "X86 CondBr Folding"; }
83 INITIALIZE_PASS(X86CondBrFoldingPass,
"X86CondBrFolding",
"X86CondBrFolding",
false,
false)
86 return new X86CondBrFoldingPass();
91 struct TargetMBBInfo {
104 class X86CondBrFolding {
109 :
TII(TII), MBPI(MBPI), MF(MF) {}
116 std::vector<std::unique_ptr<TargetMBBInfo>> MBBInfos;
127 static bool analyzeCompare(
const MachineInstr &
MI,
unsigned &SrcReg,
142 bool X86CondBrFolding::findPath(
144 TargetMBBInfo *MBBInfo = getMBBInfo(MBB);
145 assert(MBBInfo &&
"Expecting a candidate MBB");
146 int CmpValue = MBBInfo->CmpValue;
151 TargetMBBInfo *PredMBBInfo = getMBBInfo(PredMBB);
152 if (!PredMBBInfo || PredMBBInfo->SrcReg != MBBInfo->SrcReg)
155 assert(SaveMBB == PredMBBInfo->TBB || SaveMBB == PredMBBInfo->FBB);
156 bool IsFalseBranch = (SaveMBB == PredMBBInfo->FBB);
160 int PredCmpValue = PredMBBInfo->CmpValue;
161 bool ValueCmpTrue = ((CmpValue < PredCmpValue && CC ==
X86::COND_L) ||
165 if (!(ValueCmpTrue ^ IsFalseBranch)) {
172 if ((CmpValue == PredCmpValue) ||
173 (CmpValue == PredCmpValue - 1 && CC ==
X86::COND_L) ||
174 (CmpValue == PredCmpValue + 1 && CC ==
X86::COND_G))
178 if (PredMBB->
pred_size() != 1 || !PredMBBInfo->CmpBrOnly)
190 if (NewMBB == OldMBB)
193 MI != ME &&
MI->isPHI(); ++
MI)
194 for (
unsigned i = 2, e =
MI->getNumOperands() + 1; i != e; i += 2) {
196 if (MO.
getMBB() == OldMBB)
216 return MI.getOpcode() == X86::JMP_1;
225 TargetMBBInfo *MBBInfo = getMBBInfo(MBB);
227 if (MBBInfo->TBB == OrigDest) {
228 BrMI = MBBInfo->BrInstr;
233 MBBInfo->TBB = NewDest;
239 MBBInfo->FBB = NewDest;
245 setBranchProb(MBB, NewDest, MBPI->getEdgeProbability(MBB, OrigDest));
251 TargetMBBInfo *MBBInfo = getMBBInfo(MBB);
252 if (!MBBInfo->Modified)
259 .addMBB(MBBInfo->TBB);
265 .addMBB(MBBInfo->FBB);
266 MBB->
erase(UncondBrI);
267 MBBInfo->Modified =
false;
284 void X86CondBrFolding::optimizeCondBr(
288 TargetMBBInfo *MBBInfo = getMBBInfo(&MBB);
289 assert(MBBInfo &&
"Expecting a candidate MBB");
295 TargetMBBInfo *PredMBBInfo = getMBBInfo(PredMBB);
296 assert(PredMBBInfo &&
"Expecting a candidate MBB");
297 if (PredMBBInfo->Modified)
298 fixupModifiedCond(PredMBB);
299 CC = PredMBBInfo->BranchCode;
303 replaceBrDest(PredMBB, &MBB, MBBInfo->FBB);
306 TargetMBBInfo *RootMBBInfo = getMBBInfo(RootMBB);
307 assert(RootMBBInfo &&
"Expecting a candidate MBB");
308 if (RootMBBInfo->Modified)
309 fixupModifiedCond(RootMBB);
310 CC = RootMBBInfo->BranchCode;
328 .addMBB(RootMBBInfo->FBB);
332 TII->get(X86::JMP_1))
336 RootMBB->
erase(UncondBrI);
338 replaceBrDest(RootMBB, RootMBBInfo->TBB, TargetMBB);
343 if (RootMBBInfo->CmpValue != MBBInfo->CmpValue) {
346 RootMBB->
insert(RootMBBInfo->CmpInstr, NewCmp);
347 RootMBBInfo->CmpInstr->eraseFromParent();
353 for (
auto &
I : BranchPath) {
358 Prob = MBPI->getEdgeProbability(ThisMBB, NextMBB);
361 TargetProb = Prob * TargetProb;
362 Prob = Prob - TargetProb;
364 if (ThisMBB == RootMBB) {
368 if (ThisMBB == RootMBB)
375 fixBranchProb(MBBInfo->FBB);
382 MBBInfos[RootMBB->
getNumber()] =
nullptr;
384 LLVM_DEBUG(
dbgs() <<
"After optimization:\nRootMBB is: " << *RootMBB <<
"\n");
385 if (BranchPath.
size() > 1)
391 bool X86CondBrFolding::optimize() {
392 bool Changed =
false;
393 LLVM_DEBUG(
dbgs() <<
"***** X86CondBr Folding on Function: " << MF.getName()
396 MBBInfos.resize(MF.getNumBlockIDs());
398 MBBInfos[MBB.
getNumber()] = analyzeMBB(MBB);
400 for (
auto &MBB : MF) {
401 TargetMBBInfo *MBBInfo = getMBBInfo(&MBB);
402 if (!MBBInfo || !MBBInfo->CmpBrOnly)
407 <<
" CmpValue: " << MBBInfo->CmpValue <<
"\n");
409 if (!findPath(&MBB, BranchPath))
413 LLVM_DEBUG(
dbgs() <<
"Found one path (len=" << BranchPath.size() <<
"):\n");
416 for (
auto I = BranchPath.rbegin();
I != BranchPath.rend(); ++
I, ++
Index) {
418 TargetMBBInfo *PMBBInfo = getMBBInfo(PMBB);
419 LLVM_DEBUG(
dbgs() <<
"Path MBB (" << Index <<
" of " << BranchPath.size()
420 <<
") is " << *PMBB);
422 <<
" Val=" << PMBBInfo->CmpValue
423 <<
" CmpBrOnly=" << PMBBInfo->CmpBrOnly <<
"\n\n");
426 optimizeCondBr(MBB, BranchPath);
429 NumFixedCondBrs += RemoveList.size();
430 for (
auto MBBI : RemoveList) {
431 while (!MBBI->succ_empty())
432 MBBI->removeSuccessor(MBBI->succ_end() - 1);
434 MBBI->eraseFromParent();
441 bool X86CondBrFolding::analyzeCompare(
const MachineInstr &
MI,
unsigned &SrcReg,
443 unsigned SrcRegIndex = 0;
444 unsigned ValueIndex = 0;
484 std::unique_ptr<TargetMBBInfo>
503 while (I != MBB.
begin()) {
505 if (I->isDebugValue())
507 if (I->getOpcode() == X86::JMP_1) {
510 FBB = I->getOperand(0).getMBB();
528 TBB = I->getOperand(0).getMBB();
532 if (analyzeCompare(*I, SrcReg, CmpValue)) {
542 if (!TBB || !FBB || !CmpInstr)
554 if (CmpValue == INT_MAX)
561 if (CmpValue == INT_MIN)
571 return llvm::make_unique<TargetMBBInfo>(TargetMBBInfo{
572 TBB, FBB, BrInstr, CmpInstr, CC, SrcReg, CmpValue, Modified, CmpBrOnly});
581 &getAnalysis<MachineBranchProbabilityInfo>();
583 X86CondBrFolding CondBr(TII, MBPI, MF);
584 return CondBr.optimize();
bool hasSuccessorProbabilities() const
Return true if any of the successors have probabilities attached to them.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
instr_iterator instr_begin()
instr_iterator instr_end()
MachineBasicBlock * getMBB() const
This class represents lattice values for constants.
static bool setBranchProb(MachineBasicBlock *MBB, MachineBasicBlock *SuccMBB, BranchProbability Prob)
const X86InstrInfo * getInstrInfo() const override
void push_back(const T &Elt)
unsigned getReg() const
getReg - Returns the register number.
STATISTIC(NumFunctions, "Total number of functions")
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
AnalysisUsage & addRequired()
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
const HexagonInstrInfo * TII
MachineBasicBlock iterator that automatically skips over MIs that are inside bundles (i...
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
CondCode getCondFromBranchOpc(unsigned Opc)
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
void initializeX86CondBrFoldingPassPass(PassRegistry &)
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
void setSuccProbability(succ_iterator I, BranchProbability Prob)
Set successor probability of a given iterator.
instr_iterator insert(instr_iterator I, MachineInstr *M)
Insert MI into the instruction list before I, possibly inside a bundle.
void normalizeSuccProbs()
Normalize probabilities of all successors so that the sum of them becomes one.
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any DBG_VALUE and DBG_LABEL instructions...
void setMBB(MachineBasicBlock *MBB)
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
auto find_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::find_if which take ranges instead of having to pass begin/end explicitly...
static unsigned GetCondBranchFromCond(XCore::CondCode CC)
GetCondBranchFromCond - Return the Branch instruction opcode that matches the cc. ...
succ_iterator succ_begin()
pred_iterator pred_begin()
auto find(R &&Range, const T &Val) -> decltype(adl_begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
bool threewayBranchProfitable() const
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly. ...
unsigned pred_size() const
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
static MachineBasicBlock::iterator findUncondBrI(MachineBasicBlock *MBB)
unsigned succ_size() const
Representation of each machine instruction.
static void fixPHIsInSucc(MachineBasicBlock *MBB, MachineBasicBlock *OldMBB, MachineBasicBlock *NewMBB)
void push_back(MachineInstr *MI)
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
FunctionPass * createX86CondBrFolding()
Return a pass that folds conditional branch jumps.
MachineInstr * removeFromParent()
Unlink 'this' from the containing basic block, and return it without deleting it. ...
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
StringRef - Represent a constant reference to a string, i.e.
const MachineOperand & getOperand(unsigned i) const