Skip to content

Commit f569ada

Browse files
committed
[EarlyIfConversion] Determine if branch is predictable using new APIs.
1 parent 947374c commit f569ada

File tree

8 files changed

+112
-48
lines changed

8 files changed

+112
-48
lines changed

llvm/include/llvm/CodeGen/MachineLoopInfo.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,15 +83,17 @@ class MachineLoop : public LoopBase<MachineBasicBlock, MachineLoop> {
8383
/// ExcludeReg can be used to exclude the given register from the check
8484
/// i.e. when we're considering hoisting it's definition but not hoisted it
8585
/// yet
86-
bool isLoopInvariant(MachineInstr &I, const Register ExcludeReg = 0) const;
86+
bool isLoopInvariant(const MachineInstr &I, const Register ExcludeReg = 0,
87+
unsigned RecursionDepth = 1) const;
8788

8889
void dump() const;
8990

9091
private:
9192
friend class LoopInfoBase<MachineBasicBlock, MachineLoop>;
9293

9394
/// Returns true if the given physreg has no defs inside the loop.
94-
bool isLoopInvariantImplicitPhysReg(Register Reg) const;
95+
bool isLoopInvariantImplicitPhysReg(Register Reg, Register ExcludeReg,
96+
unsigned RecursionDepth = 1) const;
9597

9698
explicit MachineLoop(MachineBasicBlock *MBB)
9799
: LoopBase<MachineBasicBlock, MachineLoop>(MBB) {}

llvm/include/llvm/CodeGen/TargetInstrInfo.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ class InstrItineraryData;
4545
class LiveIntervals;
4646
class LiveVariables;
4747
class MachineLoop;
48+
class MachineLoopInfo;
4849
class MachineMemOperand;
4950
class MachineModuleInfo;
5051
class MachineRegisterInfo;
@@ -655,6 +656,17 @@ class TargetInstrInfo : public MCInstrInfo {
655656
return true;
656657
}
657658

659+
// Same as above but also if IsPredictable is non-null set IsPredictable to
660+
// "true" if target considers this branch to be predictable and to false
661+
// otherwise.
662+
virtual bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
663+
MachineBasicBlock *&FBB,
664+
SmallVectorImpl<MachineOperand> &Cond,
665+
bool *IsPredictable, const MachineLoopInfo *MLI,
666+
bool AllowModify = false) const {
667+
return analyzeBranch(MBB, TBB, FBB, Cond, AllowModify);
668+
}
669+
658670
/// Represents a predicate at the MachineFunction level. The control flow a
659671
/// MachineBranchPredicate represents is:
660672
///

llvm/lib/CodeGen/EarlyIfConversion.cpp

Lines changed: 9 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ class SSAIfConv {
8383
const TargetInstrInfo *TII;
8484
const TargetRegisterInfo *TRI;
8585
MachineRegisterInfo *MRI;
86+
const MachineLoopInfo *MLI;
8687

8788
public:
8889
/// The block containing the conditional branch.
@@ -121,6 +122,8 @@ class SSAIfConv {
121122

122123
/// The branch condition determined by analyzeBranch.
123124
SmallVector<MachineOperand, 4> Cond;
125+
/// Is branch predictable as determined by analyzeBranch.
126+
bool IsPredictableBranch = false;
124127

125128
private:
126129
/// Instructions in Head that define values used by the conditional blocks.
@@ -163,14 +166,15 @@ class SSAIfConv {
163166
void rewritePHIOperands();
164167

165168
public:
166-
SSAIfConv(MachineFunction &MF) {
169+
SSAIfConv(MachineFunction &MF, const MachineLoopInfo *MLI) {
167170
TII = MF.getSubtarget().getInstrInfo();
168171
TRI = MF.getSubtarget().getRegisterInfo();
169172
MRI = &MF.getRegInfo();
170173
LiveRegUnits.clear();
171174
LiveRegUnits.setUniverse(TRI->getNumRegUnits());
172175
ClobberedRegUnits.clear();
173176
ClobberedRegUnits.resize(TRI->getNumRegUnits());
177+
this->MLI = MLI;
174178
}
175179

176180
/// canConvertIf - If the sub-CFG headed by MBB can be if-converted,
@@ -484,7 +488,7 @@ bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB, bool Predicate) {
484488

485489
// The branch we're looking to eliminate must be analyzable.
486490
Cond.clear();
487-
if (TII->analyzeBranch(*Head, TBB, FBB, Cond)) {
491+
if (TII->analyzeBranch(*Head, TBB, FBB, Cond, &IsPredictableBranch, MLI)) {
488492
LLVM_DEBUG(dbgs() << "Branch not analyzable.\n");
489493
return false;
490494
}
@@ -874,33 +878,7 @@ bool EarlyIfConverter::shouldConvertIf(SSAIfConv &IfConv) {
874878
// Do not try to if-convert if the condition has a high chance of being
875879
// predictable.
876880
MachineLoop *CurrentLoop = Loops->getLoopFor(IfConv.Head);
877-
// If the condition is in a loop, consider it predictable if the condition
878-
// itself or all its operands are loop-invariant. E.g. this considers a load
879-
// from a loop-invariant address predictable; we were unable to prove that it
880-
// doesn't alias any of the memory-writes in the loop, but it is likely to
881-
// read to same value multiple times.
882-
if (CurrentLoop && any_of(IfConv.Cond, [&](MachineOperand &MO) {
883-
if (!MO.isReg() || !MO.isUse())
884-
return false;
885-
Register Reg = MO.getReg();
886-
if (Register::isPhysicalRegister(Reg))
887-
return false;
888-
889-
MachineInstr *Def = MRI->getVRegDef(Reg);
890-
return CurrentLoop->isLoopInvariant(*Def) ||
891-
all_of(Def->operands(), [&](MachineOperand &Op) {
892-
if (Op.isImm())
893-
return true;
894-
if (!MO.isReg() || !MO.isUse())
895-
return false;
896-
Register Reg = MO.getReg();
897-
if (Register::isPhysicalRegister(Reg))
898-
return false;
899-
900-
MachineInstr *Def = MRI->getVRegDef(Reg);
901-
return CurrentLoop->isLoopInvariant(*Def);
902-
});
903-
}))
881+
if (CurrentLoop && IfConv.IsPredictableBranch)
904882
return false;
905883

906884
if (!MinInstr)
@@ -1096,7 +1074,7 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
10961074
MinInstr = nullptr;
10971075

10981076
bool Changed = false;
1099-
SSAIfConv IfConv(MF);
1077+
SSAIfConv IfConv(MF, Loops);
11001078

11011079
// Visit blocks in dominator tree post-order. The post-order enables nested
11021080
// if-conversion in a single pass. The tryConvertIf() function may erase
@@ -1232,7 +1210,7 @@ bool EarlyIfPredicator::runOnMachineFunction(MachineFunction &MF) {
12321210
MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
12331211

12341212
bool Changed = false;
1235-
SSAIfConv IfConv(MF);
1213+
SSAIfConv IfConv(MF, Loops);
12361214

12371215
// Visit blocks in dominator tree post-order. The post-order enables nested
12381216
// if-conversion in a single pass. The tryConvertIf() function may erase

llvm/lib/CodeGen/MachineLoopInfo.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,8 @@ MDNode *MachineLoop::getLoopID() const {
226226
return LoopID;
227227
}
228228

229-
bool MachineLoop::isLoopInvariantImplicitPhysReg(Register Reg) const {
229+
bool MachineLoop::isLoopInvariantImplicitPhysReg(
230+
Register Reg, Register ExcludeReg, unsigned RecursionDepth) const {
230231
MachineFunction *MF = getHeader()->getParent();
231232
MachineRegisterInfo *MRI = &MF->getRegInfo();
232233

@@ -238,15 +239,20 @@ bool MachineLoop::isLoopInvariantImplicitPhysReg(Register Reg) const {
238239
->shouldAnalyzePhysregInMachineLoopInfo(Reg))
239240
return false;
240241

241-
return !llvm::any_of(
242-
MRI->def_instructions(Reg),
243-
[this](const MachineInstr &MI) { return this->contains(&MI); });
242+
return !llvm::any_of(MRI->def_instructions(Reg), [=](const MachineInstr &MI) {
243+
return (this->contains(&MI) &&
244+
!isLoopInvariant(MI, ExcludeReg, RecursionDepth - 1));
245+
});
244246
}
245247

246-
bool MachineLoop::isLoopInvariant(MachineInstr &I,
247-
const Register ExcludeReg) const {
248-
MachineFunction *MF = I.getParent()->getParent();
249-
MachineRegisterInfo *MRI = &MF->getRegInfo();
248+
bool MachineLoop::isLoopInvariant(const MachineInstr &I,
249+
const Register ExcludeReg,
250+
unsigned RecursionDepth) const {
251+
if (RecursionDepth == 0)
252+
return false;
253+
254+
const MachineFunction *MF = I.getParent()->getParent();
255+
const MachineRegisterInfo *MRI = &MF->getRegInfo();
250256
const TargetSubtargetInfo &ST = MF->getSubtarget();
251257
const TargetRegisterInfo *TRI = ST.getRegisterInfo();
252258
const TargetInstrInfo *TII = ST.getInstrInfo();
@@ -271,7 +277,7 @@ bool MachineLoop::isLoopInvariant(MachineInstr &I,
271277
// it could get allocated to something with a def during allocation.
272278
// However, if the physreg is known to always be caller saved/restored
273279
// then this use is safe to hoist.
274-
if (!isLoopInvariantImplicitPhysReg(Reg) &&
280+
if (!isLoopInvariantImplicitPhysReg(Reg, ExcludeReg, RecursionDepth) &&
275281
!(TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *I.getMF())) &&
276282
!TII->isIgnorableUse(MO))
277283
return false;
@@ -293,9 +299,11 @@ bool MachineLoop::isLoopInvariant(MachineInstr &I,
293299
assert(MRI->getVRegDef(Reg) &&
294300
"Machine instr not mapped for this vreg?!");
295301

296-
// If the loop contains the definition of an operand, then the instruction
297-
// isn't loop invariant.
298-
if (contains(MRI->getVRegDef(Reg)))
302+
// If the loop contains the definition of an operand, then it must be loop
303+
// invariant
304+
MachineInstr *VRegDefMI = MRI->getVRegDef(Reg);
305+
if (contains(VRegDefMI) &&
306+
!isLoopInvariant(*VRegDefMI, ExcludeReg, RecursionDepth - 1))
299307
return false;
300308
}
301309

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
#include "llvm/CodeGen/MachineFunction.h"
3030
#include "llvm/CodeGen/MachineInstr.h"
3131
#include "llvm/CodeGen/MachineInstrBuilder.h"
32+
#include "llvm/CodeGen/MachineLoopInfo.h"
3233
#include "llvm/CodeGen/MachineMemOperand.h"
3334
#include "llvm/CodeGen/MachineModuleInfo.h"
3435
#include "llvm/CodeGen/MachineOperand.h"
@@ -329,12 +330,27 @@ void AArch64InstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
329330
.addImm(16);
330331
}
331332

332-
// Branch analysis.
333+
bool AArch64InstrInfo::isCondBranchPredictable(
334+
const MachineInstr &CondBr, const MachineLoopInfo &MLI) const {
335+
MachineLoop *Loop = MLI.getLoopFor(CondBr.getParent());
336+
if (!Loop)
337+
return false;
338+
return Loop->isLoopInvariant(CondBr, /*ExcludeReg=*/0, /*RecursionDepth=*/2);
339+
}
340+
333341
bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
334342
MachineBasicBlock *&TBB,
335343
MachineBasicBlock *&FBB,
336344
SmallVectorImpl<MachineOperand> &Cond,
337345
bool AllowModify) const {
346+
return analyzeBranch(MBB, TBB, FBB, Cond, nullptr, nullptr, AllowModify);
347+
}
348+
349+
// Branch analysis.
350+
bool AArch64InstrInfo::analyzeBranch(
351+
MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB,
352+
SmallVectorImpl<MachineOperand> &Cond, bool *IsPredictable,
353+
const MachineLoopInfo *MLI, bool AllowModify) const {
338354
// If the block has no terminators, it just falls into the block after it.
339355
MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
340356
if (I == MBB.end())
@@ -362,6 +378,8 @@ bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
362378
if (isCondBranchOpcode(LastOpc)) {
363379
// Block ends with fall-through condbranch.
364380
parseCondBranch(LastInst, TBB, Cond);
381+
if (IsPredictable && MLI)
382+
*IsPredictable = isCondBranchPredictable(*LastInst, *MLI);
365383
return false;
366384
}
367385
return true; // Can't handle indirect branch.
@@ -404,6 +422,8 @@ bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
404422
if (isCondBranchOpcode(LastOpc)) {
405423
// Block ends with fall-through condbranch.
406424
parseCondBranch(LastInst, TBB, Cond);
425+
if (IsPredictable && MLI)
426+
*IsPredictable = isCondBranchPredictable(*LastInst, *MLI);
407427
return false;
408428
}
409429
return true; // Can't handle indirect branch.
@@ -420,6 +440,8 @@ bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
420440
if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
421441
parseCondBranch(SecondLastInst, TBB, Cond);
422442
FBB = LastInst->getOperand(0).getMBB();
443+
if (IsPredictable && MLI)
444+
*IsPredictable = isCondBranchPredictable(*SecondLastInst, *MLI);
423445
return false;
424446
}
425447

llvm/lib/Target/AArch64/AArch64InstrInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,10 +384,17 @@ class AArch64InstrInfo final : public AArch64GenInstrInfo {
384384
MachineBasicBlock &RestoreBB, const DebugLoc &DL,
385385
int64_t BrOffset, RegScavenger *RS) const override;
386386

387+
bool isCondBranchPredictable(const MachineInstr &CondBr,
388+
const MachineLoopInfo &MLI) const;
387389
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
388390
MachineBasicBlock *&FBB,
389391
SmallVectorImpl<MachineOperand> &Cond,
390392
bool AllowModify = false) const override;
393+
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
394+
MachineBasicBlock *&FBB,
395+
SmallVectorImpl<MachineOperand> &Cond, bool *IsPredictable,
396+
const MachineLoopInfo *MLI,
397+
bool AllowModify = false) const override;
391398
bool analyzeBranchPredicate(MachineBasicBlock &MBB,
392399
MachineBranchPredicate &MBP,
393400
bool AllowModify) const override;

llvm/lib/Target/PowerPC/PPCInstrInfo.cpp

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
#include "llvm/CodeGen/MachineFrameInfo.h"
2828
#include "llvm/CodeGen/MachineFunctionPass.h"
2929
#include "llvm/CodeGen/MachineInstrBuilder.h"
30+
#include "llvm/CodeGen/MachineLoopInfo.h"
3031
#include "llvm/CodeGen/MachineMemOperand.h"
3132
#include "llvm/CodeGen/MachineRegisterInfo.h"
3233
#include "llvm/CodeGen/PseudoSourceValue.h"
@@ -1255,13 +1256,28 @@ MCInst PPCInstrInfo::getNop() const {
12551256
}
12561257

12571258
// Branch analysis.
1258-
// Note: If the condition register is set to CTR or CTR8 then this is a
1259-
// BDNZ (imm == 1) or BDZ (imm == 0) branch.
1259+
bool PPCInstrInfo::isCondBranchPredictable(const MachineInstr &CondBr,
1260+
const MachineLoopInfo &MLI) const {
1261+
MachineLoop *Loop = MLI.getLoopFor(CondBr.getParent());
1262+
if (!Loop)
1263+
return false;
1264+
return Loop->isLoopInvariant(CondBr, /*ExcludeReg=*/0, /*RecursionDepth=*/2);
1265+
}
1266+
12601267
bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
12611268
MachineBasicBlock *&TBB,
12621269
MachineBasicBlock *&FBB,
12631270
SmallVectorImpl<MachineOperand> &Cond,
12641271
bool AllowModify) const {
1272+
return analyzeBranch(MBB, TBB, FBB, Cond, nullptr, nullptr, AllowModify);
1273+
}
1274+
1275+
// Note: If the condition register is set to CTR or CTR8 then this is a
1276+
// BDNZ (imm == 1) or BDZ (imm == 0) branch.
1277+
bool PPCInstrInfo::analyzeBranch(
1278+
MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB,
1279+
SmallVectorImpl<MachineOperand> &Cond, bool *IsPredictable,
1280+
const MachineLoopInfo *MLI, bool AllowModify) const {
12651281
bool isPPC64 = Subtarget.isPPC64();
12661282

12671283
// If the block has no terminators, it just falls into the block after it.
@@ -1303,6 +1319,8 @@ bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
13031319
TBB = LastInst.getOperand(2).getMBB();
13041320
Cond.push_back(LastInst.getOperand(0));
13051321
Cond.push_back(LastInst.getOperand(1));
1322+
if (IsPredictable && MLI)
1323+
*IsPredictable = isCondBranchPredictable(LastInst, *MLI);
13061324
return false;
13071325
} else if (LastInst.getOpcode() == PPC::BC) {
13081326
if (!LastInst.getOperand(1).isMBB())
@@ -1311,6 +1329,8 @@ bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
13111329
TBB = LastInst.getOperand(1).getMBB();
13121330
Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
13131331
Cond.push_back(LastInst.getOperand(0));
1332+
if (IsPredictable && MLI)
1333+
*IsPredictable = isCondBranchPredictable(LastInst, *MLI);
13141334
return false;
13151335
} else if (LastInst.getOpcode() == PPC::BCn) {
13161336
if (!LastInst.getOperand(1).isMBB())
@@ -1319,6 +1339,8 @@ bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
13191339
TBB = LastInst.getOperand(1).getMBB();
13201340
Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_UNSET));
13211341
Cond.push_back(LastInst.getOperand(0));
1342+
if (IsPredictable && MLI)
1343+
*IsPredictable = isCondBranchPredictable(LastInst, *MLI);
13221344
return false;
13231345
} else if (LastInst.getOpcode() == PPC::BDNZ8 ||
13241346
LastInst.getOpcode() == PPC::BDNZ) {
@@ -1365,6 +1387,8 @@ bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
13651387
Cond.push_back(SecondLastInst.getOperand(0));
13661388
Cond.push_back(SecondLastInst.getOperand(1));
13671389
FBB = LastInst.getOperand(0).getMBB();
1390+
if (IsPredictable && MLI)
1391+
*IsPredictable = isCondBranchPredictable(SecondLastInst, *MLI);
13681392
return false;
13691393
} else if (SecondLastInst.getOpcode() == PPC::BC &&
13701394
LastInst.getOpcode() == PPC::B) {
@@ -1375,6 +1399,8 @@ bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
13751399
Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_SET));
13761400
Cond.push_back(SecondLastInst.getOperand(0));
13771401
FBB = LastInst.getOperand(0).getMBB();
1402+
if (IsPredictable && MLI)
1403+
*IsPredictable = isCondBranchPredictable(SecondLastInst, *MLI);
13781404
return false;
13791405
} else if (SecondLastInst.getOpcode() == PPC::BCn &&
13801406
LastInst.getOpcode() == PPC::B) {
@@ -1385,6 +1411,8 @@ bool PPCInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
13851411
Cond.push_back(MachineOperand::CreateImm(PPC::PRED_BIT_UNSET));
13861412
Cond.push_back(SecondLastInst.getOperand(0));
13871413
FBB = LastInst.getOperand(0).getMBB();
1414+
if (IsPredictable && MLI)
1415+
*IsPredictable = isCondBranchPredictable(SecondLastInst, *MLI);
13881416
return false;
13891417
} else if ((SecondLastInst.getOpcode() == PPC::BDNZ8 ||
13901418
SecondLastInst.getOpcode() == PPC::BDNZ) &&

llvm/lib/Target/PowerPC/PPCInstrInfo.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -432,10 +432,17 @@ class PPCInstrInfo : public PPCGenInstrInfo {
432432

433433

434434
// Branch analysis.
435+
bool isCondBranchPredictable(const MachineInstr &CondBr,
436+
const MachineLoopInfo &MLI) const;
435437
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
436438
MachineBasicBlock *&FBB,
437439
SmallVectorImpl<MachineOperand> &Cond,
438440
bool AllowModify) const override;
441+
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
442+
MachineBasicBlock *&FBB,
443+
SmallVectorImpl<MachineOperand> &Cond, bool *IsPredictable,
444+
const MachineLoopInfo *MLI,
445+
bool AllowModify) const override;
439446
unsigned removeBranch(MachineBasicBlock &MBB,
440447
int *BytesRemoved = nullptr) const override;
441448
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB,

0 commit comments

Comments
 (0)