Skip to content

Commit fc8a80c

Browse files
committed
[EarlyIfConversion] Determine if branch is predictable using new APIs.
1 parent adc4e45 commit fc8a80c

File tree

9 files changed

+113
-49
lines changed

9 files changed

+113
-49
lines changed

llvm/include/llvm/CodeGen/MachineLoopInfo.h

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

8788
void dump() const;
8889

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

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

9597
explicit MachineLoop(MachineBasicBlock *MBB)
9698
: 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 MachineRegisterInfo;
5051
class MCAsmInfo;
@@ -654,6 +655,17 @@ class TargetInstrInfo : public MCInstrInfo {
654655
return true;
655656
}
656657

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

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.
@@ -164,14 +167,15 @@ class SSAIfConv {
164167

165168
public:
166169
/// runOnMachineFunction - Initialize per-function data structures.
167-
void runOnMachineFunction(MachineFunction &MF) {
170+
void runOnMachineFunction(MachineFunction &MF, const MachineLoopInfo *MLI) {
168171
TII = MF.getSubtarget().getInstrInfo();
169172
TRI = MF.getSubtarget().getRegisterInfo();
170173
MRI = &MF.getRegInfo();
171174
LiveRegUnits.clear();
172175
LiveRegUnits.setUniverse(TRI->getNumRegUnits());
173176
ClobberedRegUnits.clear();
174177
ClobberedRegUnits.resize(TRI->getNumRegUnits());
178+
this->MLI = MLI;
175179
}
176180

177181
/// canConvertIf - If the sub-CFG headed by MBB can be if-converted,
@@ -485,7 +489,7 @@ bool SSAIfConv::canConvertIf(MachineBasicBlock *MBB, bool Predicate) {
485489

486490
// The branch we're looking to eliminate must be analyzable.
487491
Cond.clear();
488-
if (TII->analyzeBranch(*Head, TBB, FBB, Cond)) {
492+
if (TII->analyzeBranch(*Head, TBB, FBB, Cond, &IsPredictableBranch, MLI)) {
489493
LLVM_DEBUG(dbgs() << "Branch not analyzable.\n");
490494
return false;
491495
}
@@ -874,33 +878,7 @@ bool EarlyIfConverter::shouldConvertIf() {
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)
@@ -1095,7 +1073,7 @@ bool EarlyIfConverter::runOnMachineFunction(MachineFunction &MF) {
10951073
MinInstr = nullptr;
10961074

10971075
bool Changed = false;
1098-
IfConv.runOnMachineFunction(MF);
1076+
IfConv.runOnMachineFunction(MF, Loops);
10991077

11001078
// Visit blocks in dominator tree post-order. The post-order enables nested
11011079
// if-conversion in a single pass. The tryConvertIf() function may erase
@@ -1228,7 +1206,7 @@ bool EarlyIfPredicator::runOnMachineFunction(MachineFunction &MF) {
12281206
MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
12291207

12301208
bool Changed = false;
1231-
IfConv.runOnMachineFunction(MF);
1209+
IfConv.runOnMachineFunction(MF, Loops);
12321210

12331211
// Visit blocks in dominator tree post-order. The post-order enables nested
12341212
// 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
@@ -198,7 +198,8 @@ MDNode *MachineLoop::getLoopID() const {
198198
return LoopID;
199199
}
200200

201-
bool MachineLoop::isLoopInvariantImplicitPhysReg(Register Reg) const {
201+
bool MachineLoop::isLoopInvariantImplicitPhysReg(
202+
Register Reg, Register ExcludeReg, unsigned RecursionDepth) const {
202203
MachineFunction *MF = getHeader()->getParent();
203204
MachineRegisterInfo *MRI = &MF->getRegInfo();
204205

@@ -210,15 +211,20 @@ bool MachineLoop::isLoopInvariantImplicitPhysReg(Register Reg) const {
210211
->shouldAnalyzePhysregInMachineLoopInfo(Reg))
211212
return false;
212213

213-
return !llvm::any_of(
214-
MRI->def_instructions(Reg),
215-
[this](const MachineInstr &MI) { return this->contains(&MI); });
214+
return !llvm::any_of(MRI->def_instructions(Reg), [=](const MachineInstr &MI) {
215+
return (this->contains(&MI) &&
216+
!isLoopInvariant(MI, ExcludeReg, RecursionDepth - 1));
217+
});
216218
}
217219

218-
bool MachineLoop::isLoopInvariant(MachineInstr &I,
219-
const Register ExcludeReg) const {
220-
MachineFunction *MF = I.getParent()->getParent();
221-
MachineRegisterInfo *MRI = &MF->getRegInfo();
220+
bool MachineLoop::isLoopInvariant(const MachineInstr &I,
221+
const Register ExcludeReg,
222+
unsigned RecursionDepth) const {
223+
if (RecursionDepth == 0)
224+
return false;
225+
226+
const MachineFunction *MF = I.getParent()->getParent();
227+
const MachineRegisterInfo *MRI = &MF->getRegInfo();
222228
const TargetSubtargetInfo &ST = MF->getSubtarget();
223229
const TargetRegisterInfo *TRI = ST.getRegisterInfo();
224230
const TargetInstrInfo *TII = ST.getInstrInfo();
@@ -243,7 +249,7 @@ bool MachineLoop::isLoopInvariant(MachineInstr &I,
243249
// it could get allocated to something with a def during allocation.
244250
// However, if the physreg is known to always be caller saved/restored
245251
// then this use is safe to hoist.
246-
if (!isLoopInvariantImplicitPhysReg(Reg) &&
252+
if (!isLoopInvariantImplicitPhysReg(Reg, ExcludeReg, RecursionDepth) &&
247253
!(TRI->isCallerPreservedPhysReg(Reg.asMCReg(), *I.getMF())) &&
248254
!TII->isIgnorableUse(MO))
249255
return false;
@@ -265,9 +271,11 @@ bool MachineLoop::isLoopInvariant(MachineInstr &I,
265271
assert(MRI->getVRegDef(Reg) &&
266272
"Machine instr not mapped for this vreg?!");
267273

268-
// If the loop contains the definition of an operand, then the instruction
269-
// isn't loop invariant.
270-
if (contains(MRI->getVRegDef(Reg)))
274+
// If the loop contains the definition of an operand, then it must be loop
275+
// invariant
276+
MachineInstr *VRegDefMI = MRI->getVRegDef(Reg);
277+
if (contains(VRegDefMI) &&
278+
!isLoopInvariant(*VRegDefMI, ExcludeReg, RecursionDepth - 1))
271279
return false;
272280
}
273281

llvm/lib/Target/AArch64/AArch64InstrInfo.cpp

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "llvm/CodeGen/MachineFunction.h"
2929
#include "llvm/CodeGen/MachineInstr.h"
3030
#include "llvm/CodeGen/MachineInstrBuilder.h"
31+
#include "llvm/CodeGen/MachineLoopInfo.h"
3132
#include "llvm/CodeGen/MachineMemOperand.h"
3233
#include "llvm/CodeGen/MachineModuleInfo.h"
3334
#include "llvm/CodeGen/MachineOperand.h"
@@ -327,12 +328,27 @@ void AArch64InstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
327328
.addImm(16);
328329
}
329330

330-
// Branch analysis.
331+
bool AArch64InstrInfo::isCondBranchPredictable(
332+
const MachineInstr &CondBr, const MachineLoopInfo &MLI) const {
333+
MachineLoop *Loop = MLI.getLoopFor(CondBr.getParent());
334+
if (!Loop)
335+
return false;
336+
return Loop->isLoopInvariant(CondBr, /*ExcludeReg=*/0, /*RecursionDepth=*/2);
337+
}
338+
331339
bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
332340
MachineBasicBlock *&TBB,
333341
MachineBasicBlock *&FBB,
334342
SmallVectorImpl<MachineOperand> &Cond,
335343
bool AllowModify) const {
344+
return analyzeBranch(MBB, TBB, FBB, Cond, nullptr, nullptr, AllowModify);
345+
}
346+
347+
// Branch analysis.
348+
bool AArch64InstrInfo::analyzeBranch(
349+
MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB,
350+
SmallVectorImpl<MachineOperand> &Cond, bool *IsPredictable,
351+
const MachineLoopInfo *MLI, bool AllowModify) const {
336352
// If the block has no terminators, it just falls into the block after it.
337353
MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
338354
if (I == MBB.end())
@@ -360,6 +376,8 @@ bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
360376
if (isCondBranchOpcode(LastOpc)) {
361377
// Block ends with fall-through condbranch.
362378
parseCondBranch(LastInst, TBB, Cond);
379+
if (IsPredictable && MLI)
380+
*IsPredictable = isCondBranchPredictable(*LastInst, *MLI);
363381
return false;
364382
}
365383
return true; // Can't handle indirect branch.
@@ -402,6 +420,8 @@ bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
402420
if (isCondBranchOpcode(LastOpc)) {
403421
// Block ends with fall-through condbranch.
404422
parseCondBranch(LastInst, TBB, Cond);
423+
if (IsPredictable && MLI)
424+
*IsPredictable = isCondBranchPredictable(*LastInst, *MLI);
405425
return false;
406426
}
407427
return true; // Can't handle indirect branch.
@@ -418,6 +438,8 @@ bool AArch64InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
418438
if (isCondBranchOpcode(SecondLastOpc) && isUncondBranchOpcode(LastOpc)) {
419439
parseCondBranch(SecondLastInst, TBB, Cond);
420440
FBB = LastInst->getOperand(0).getMBB();
441+
if (IsPredictable && MLI)
442+
*IsPredictable = isCondBranchPredictable(*SecondLastInst, *MLI);
421443
return false;
422444
}
423445

llvm/lib/Target/AArch64/AArch64InstrInfo.h

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

377+
bool isCondBranchPredictable(const MachineInstr &CondBr,
378+
const MachineLoopInfo &MLI) const;
377379
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
378380
MachineBasicBlock *&FBB,
379381
SmallVectorImpl<MachineOperand> &Cond,
380382
bool AllowModify = false) const override;
383+
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB,
384+
MachineBasicBlock *&FBB,
385+
SmallVectorImpl<MachineOperand> &Cond, bool *IsPredictable,
386+
const MachineLoopInfo *MLI,
387+
bool AllowModify = false) const override;
381388
bool analyzeBranchPredicate(MachineBasicBlock &MBB,
382389
MachineBranchPredicate &MBP,
383390
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)