51#define DEBUG_TYPE "early-ifcvt"
57 cl::desc(
"Maximum number of instructions per speculated block."));
66 cl::desc(
"Enable hard-to-predict branch analysis for if-conversion"));
72 cl::desc(
"Limit the number of steps taken when searching for a "
73 "recently loaded value"));
79 cl::desc(
"Limit the number of blocks and instructions examined when "
80 "searching for calls between a load and the condition it feeds"));
83STATISTIC(NumDiamondsConv,
"Number of diamonds converted");
85STATISTIC(NumTrianglesConv,
"Number of triangles converted");
87 "Number of data dependent conditional branches encountered");
88STATISTIC(NumLikelyBiased,
"Number of branches with a hot path encountered");
132 bool isTriangle()
const {
return TBB == Tail || FBB == Tail; }
135 MachineBasicBlock *getTPred()
const {
return TBB == Tail ? Head : TBB; }
138 MachineBasicBlock *getFPred()
const {
return FBB == Tail ? Head : FBB; }
145 TargetInstrInfo::SelectExpansion Select;
147 PHIInfo(MachineInstr *phi) : PHI(
phi) {}
153 SmallVector<MachineOperand, 4> Cond;
158 SmallPtrSet<MachineInstr*, 8> InsertAfter;
161 BitVector ClobberedRegUnits;
164 SparseSet<MCRegUnit, MCRegUnit, MCRegUnitToIndex> LiveRegUnits;
172 bool canSpeculateInstrs(MachineBasicBlock *
MBB);
176 bool canPredicateInstrs(MachineBasicBlock *
MBB);
180 bool InstrDependenciesAllowIfConv(MachineInstr *
I);
184 void PredicateBlock(MachineBasicBlock *
MBB,
bool ReversePredicate);
187 bool findInsertionPoint();
190 void replacePHIInstrs();
193 void rewritePHIOperands();
197 void clearRepeatedKillFlagsFromTBB(MachineBasicBlock *TBB,
198 MachineBasicBlock *FBB);
206 LiveRegUnits.clear();
207 LiveRegUnits.setUniverse(TRI->getNumRegUnits());
208 ClobberedRegUnits.clear();
209 ClobberedRegUnits.resize(TRI->getNumRegUnits());
216 bool canConvertIf(MachineBasicBlock *
MBB,
bool Predicate =
false);
220 void convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
221 bool Predicate =
false);
245 for (MachineInstr &
MI :
247 if (
MI.isDebugInstr())
271 bool DontMoveAcrossStore =
true;
272 if (!
MI.isSafeToMove(DontMoveAcrossStore)) {
278 if (!InstrDependenciesAllowIfConv(&
MI))
288bool SSAIfConv::InstrDependenciesAllowIfConv(MachineInstr *
I) {
289 for (
const MachineOperand &MO :
I->operands()) {
290 if (MO.isRegMask()) {
301 ClobberedRegUnits.
set(
static_cast<unsigned>(Unit));
312 LLVM_DEBUG(
dbgs() <<
"Can't insert instructions below terminator.\n");
327bool SSAIfConv::canPredicateInstrs(MachineBasicBlock *
MBB) {
342 if (
I->isDebugInstr())
370 if (!InstrDependenciesAllowIfConv(&(*
I)))
377void SSAIfConv::PredicateBlock(MachineBasicBlock *
MBB,
bool ReversePredicate) {
378 auto Condition =
Cond;
379 if (ReversePredicate) {
381 assert(CanRevCond &&
"Reversed predicate is not supported");
388 if (
I->isDebugInstr())
404bool SSAIfConv::findInsertionPoint() {
407 LiveRegUnits.
clear();
415 if (InsertAfter.
count(&*
I)) {
421 for (
const MachineOperand &MO :
I->operands()) {
431 LiveRegUnits.
erase(Unit);
437 while (!Reads.
empty())
439 if (ClobberedRegUnits.
test(
static_cast<unsigned>(Unit)))
440 LiveRegUnits.
insert(Unit);
443 if (
I != FirstTerm &&
I->isTerminator())
448 if (!LiveRegUnits.
empty()) {
450 dbgs() <<
"Would clobber";
451 for (MCRegUnit LRU : LiveRegUnits)
453 dbgs() <<
" live before " << *
I;
472bool SSAIfConv::canConvertIf(MachineBasicBlock *
MBB,
bool Predicate) {
478 MachineBasicBlock *Succ0 = Head->
succ_begin()[0];
479 MachineBasicBlock *Succ1 = Head->
succ_begin()[1];
502 if (!
Tail->livein_empty()) {
515 if (!Predicate && (
Tail->empty() || !
Tail->front().isPHI())) {
529 LLVM_DEBUG(
dbgs() <<
"analyzeBranch didn't find conditional branch.\n");
536 LLVM_DEBUG(
dbgs() <<
"analyzeBranch found an unconditional branch.\n");
542 FBB =
TBB == Succ0 ? Succ1 : Succ0;
546 MachineBasicBlock *TPred = getTPred();
547 MachineBasicBlock *FPred = getFPred();
549 I !=
E &&
I->isPHI(); ++
I) {
551 PHIInfo &PI = PHIs.
back();
553 for (
unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) {
554 if (PI.PHI->getOperand(i+1).getMBB() == TPred)
555 PI.TReg = PI.PHI->getOperand(i).getReg();
556 if (PI.PHI->getOperand(i+1).getMBB() == FPred)
557 PI.FReg = PI.PHI->getOperand(i).getReg();
559 assert(PI.TReg.isVirtual() &&
"Bad PHI");
560 assert(PI.FReg.isVirtual() &&
"Bad PHI");
563 if (!
TII->canInsertSelect(*Head,
Cond, PI.PHI->getOperand(0).getReg(),
564 PI.TReg, PI.FReg, PI.Select)) {
572 ClobberedRegUnits.
reset();
574 if (
TBB != Tail && !canPredicateInstrs(
TBB))
576 if (FBB != Tail && !canPredicateInstrs(FBB))
579 if (
TBB != Tail && !canSpeculateInstrs(
TBB))
581 if (FBB != Tail && !canSpeculateInstrs(FBB))
587 if (!findInsertionPoint())
604 if (!TReg.isVirtual() || !FReg.
isVirtual())
626 return MO.isReg() && MO.getReg().isPhysical();
631 if (!
TII->produceSameValue(*TDef, *FDef, &MRI))
637 if (TIdx == -1 || FIdx == -1)
646void SSAIfConv::replacePHIInstrs() {
647 assert(
Tail->pred_size() == 2 &&
"Cannot replace PHIs");
649 assert(FirstTerm != Head->
end() &&
"No terminators");
650 DebugLoc HeadDL = FirstTerm->getDebugLoc();
653 for (PHIInfo &PI : PHIs) {
655 Register DstReg = PI.PHI->getOperand(0).getReg();
659 BuildMI(*Head, FirstTerm, HeadDL,
TII->get(TargetOpcode::COPY), DstReg)
662 TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg,
Cond, PI.TReg,
666 PI.PHI->eraseFromParent();
674void SSAIfConv::rewritePHIOperands() {
676 assert(FirstTerm != Head->
end() &&
"No terminators");
677 DebugLoc HeadDL = FirstTerm->getDebugLoc();
680 for (PHIInfo &PI : PHIs) {
689 Register PHIDst = PI.PHI->getOperand(0).getReg();
691 TII->insertSelect(*Head, FirstTerm, HeadDL,
692 DstReg,
Cond, PI.TReg, PI.FReg);
697 for (
unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) {
698 MachineBasicBlock *
MBB = PI.PHI->getOperand(i-1).getMBB();
699 if (
MBB == getTPred()) {
700 PI.PHI->getOperand(i-1).setMBB(Head);
701 PI.PHI->getOperand(i-2).setReg(DstReg);
702 }
else if (
MBB == getFPred()) {
703 PI.PHI->removeOperand(i-1);
704 PI.PHI->removeOperand(i-2);
711void SSAIfConv::clearRepeatedKillFlagsFromTBB(MachineBasicBlock *
TBB,
712 MachineBasicBlock *FBB) {
716 SmallDenseSet<Register> FBBKilledRegs;
717 for (MachineInstr &
MI : FBB->
instrs()) {
718 for (MachineOperand &MO :
MI.operands()) {
719 if (MO.isReg() && MO.isKill() && MO.getReg().isVirtual())
720 FBBKilledRegs.
insert(MO.getReg());
724 if (FBBKilledRegs.
empty())
728 for (MachineInstr &
MI :
TBB->instrs()) {
729 for (MachineOperand &MO :
MI.operands()) {
730 if (MO.isReg() && MO.isKill() && FBBKilledRegs.
contains(MO.getReg()))
741void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
743 assert(Head && Tail &&
TBB && FBB &&
"Call canConvertIf first.");
755 if (
TBB != Tail && FBB != Tail)
756 clearRepeatedKillFlagsFromTBB(
TBB, FBB);
761 PredicateBlock(
TBB,
false);
766 PredicateBlock(FBB,
true);
770 bool ExtraPreds =
Tail->pred_size() != 2;
772 rewritePHIOperands();
780 TBB->removeSuccessor(Tail,
true);
812 if (Tail != &
Tail->getParent()->back())
813 Tail->moveAfter(&
Tail->getParent()->back());
829class EarlyIfConverter {
830 const TargetInstrInfo *
TII =
nullptr;
831 const TargetRegisterInfo *
TRI =
nullptr;
832 const TargetSubtargetInfo *STI =
nullptr;
833 MachineRegisterInfo *MRI =
nullptr;
834 MachineDominatorTree *DomTree =
nullptr;
835 MachineLoopInfo *
Loops =
nullptr;
836 MachineTraceMetrics *Traces =
nullptr;
838 MachineBranchProbabilityInfo *MBPI =
nullptr;
843 DenseMap<const MachineBasicBlock *, unsigned> NoCallBlocksCache;
846 EarlyIfConverter(MachineDominatorTree &DT, MachineLoopInfo &LI,
847 MachineTraceMetrics &MTM, MachineBranchProbabilityInfo *MBPI)
848 : DomTree(&DT),
Loops(&LI), Traces(&MTM), MBPI(MBPI) {}
849 EarlyIfConverter() =
delete;
854 bool tryConvertIf(MachineBasicBlock *);
855 void invalidateTraces();
856 bool shouldConvertIf();
857 bool isConditionDataDependent();
858 bool doOperandsComeFromMemory(
const MachineInstr *ConditionDef);
859 bool hasCallOrLoopInRange(
const MachineInstr *From,
const MachineInstr *To);
862class EarlyIfConverterLegacy :
public MachineFunctionPass {
865 EarlyIfConverterLegacy() : MachineFunctionPass(
ID) {}
866 void getAnalysisUsage(AnalysisUsage &AU)
const override;
868 StringRef getPassName()
const override {
return "Early If-Conversion"; }
872char EarlyIfConverterLegacy::ID = 0;
883void EarlyIfConverterLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
897void updateDomTree(MachineDominatorTree *DomTree,
const SSAIfConv &IfConv,
903 for (
auto *
B : Removed) {
905 assert(Node != HeadNode &&
"Cannot erase the head node");
906 while (!
Node->isLeaf()) {
907 assert(
Node->getBlock() == IfConv.Tail &&
"Unexpected children");
915void updateLoops(MachineLoopInfo *
Loops,
919 for (
auto *
B : Removed)
925void EarlyIfConverter::invalidateTraces() {
936 const PseudoSourceValue *PSV = MOp->getPseudoValue();
937 return PSV && PSV->isConstantPool();
947bool EarlyIfConverter::hasCallOrLoopInRange(
const MachineInstr *From,
948 const MachineInstr *To) {
952 LLVM_DEBUG(
dbgs() <<
" checking for a call or loop between " << *From
954 assert(DomTree->
dominates(From, To) &&
"From is expected to dominate To");
956 const MachineBasicBlock *FromBB = From->
getParent();
957 const MachineBasicBlock *ToBB = To->
getParent();
959 unsigned NumScanned = 0;
960 auto HitSearchLimit = [&](
unsigned N) {
968 auto FoundCall = [](
const MachineInstr &
MI) {
972 auto IsCallOrHitSearchLimit = [&](
const MachineInstr &
MI) {
973 if (HitSearchLimit(1))
977 return FoundCall(
MI);
981 if (FromBB == ToBB) {
985 if (IsCallOrHitSearchLimit(
MI))
994 if (IsCallOrHitSearchLimit(
MI))
996 for (
const MachineInstr &
MI :
999 if (IsCallOrHitSearchLimit(
MI))
1004 SmallPtrSet<const MachineBasicBlock *, 16> Enqueued = {FromBB, ToBB};
1006 auto Enqueue = [&](
const MachineBasicBlock *BB) {
1011 for (
const MachineBasicBlock *Pred : ToBB->
predecessors())
1014 while (!Worklist.
empty()) {
1020 if (
const MachineLoop *BBLoop =
Loops->getLoopFor(BB)) {
1021 if (!BBLoop->contains(ToBB) && !BBLoop->contains(FromBB)) {
1029 auto CacheIt = NoCallBlocksCache.find(BB);
1030 if (CacheIt != NoCallBlocksCache.end()) {
1031 if (HitSearchLimit(CacheIt->second))
1034 unsigned NumBlockInstrs = 0;
1035 for (
const MachineInstr &
MI :
1039 if (IsCallOrHitSearchLimit(
MI))
1042 NoCallBlocksCache[BB] = NumBlockInstrs;
1045 for (
const MachineBasicBlock *Pred : BB->
predecessors())
1058bool EarlyIfConverter::doOperandsComeFromMemory(
1059 const MachineInstr *ConditionDef) {
1064 LLVM_DEBUG(
dbgs() <<
" doOperandsComeFromMemory starting from reg "
1070 MachineLoop *IfConvLoop =
Loops->getLoopFor(IfConv.Head);
1073 SmallPtrSet<const MachineInstr *, 8> VisitedInstrs;
1074 SmallVector<const MachineInstr *> Worklist;
1086 if (!VisitedInstrs.
insert(
MI).second)
1095 const MachineBasicBlock *Parent =
MI->getParent();
1096 MachineLoop *ParentLoop =
Loops->getLoopFor(Parent);
1099 if (IfConvLoop && ParentLoop != IfConvLoop)
1106 !
MI->isDereferenceableInvariantLoad()) {
1111 if (!DomTree->
dominates(
MI, Br) || hasCallOrLoopInRange(
MI, Br))
1118 for (
const MachineOperand &MO :
MI->operands()) {
1119 if (!MO.isReg() || !MO.isUse())
1126 if (!VisitedInstrs.
count(UseDef)) {
1137bool EarlyIfConverter::isConditionDataDependent() {
1138 TargetInstrInfo::MachineBranchPredicate MBP;
1139 if (
TII->analyzeBranchPredicate(*IfConv.Head, MBP,
false))
1150 if (TBBProb != FBBProb) {
1168 if (Delta < 0 && Cyc + Delta > Cyc)
1180 return R <<
ore::NV(
C.Key,
C.Value) << (
C.Value == 1 ?
" cycle" :
" cycles");
1187bool EarlyIfConverter::shouldConvertIf() {
1194 MachineLoop *CurrentLoop =
Loops->getLoopFor(IfConv.Head);
1200 if (CurrentLoop &&
any_of(IfConv.Cond, [&](MachineOperand &MO) {
1201 if (!MO.isReg() || !MO.isUse())
1203 Register Reg = MO.getReg();
1204 if (Reg.isPhysical())
1207 MachineInstr *Def = MRI->getVRegDef(Reg);
1208 return CurrentLoop->isLoopInvariant(*Def) ||
1209 all_of(Def->operands(), [&](MachineOperand &Op) {
1212 if (!Op.isReg() || !Op.isUse())
1214 Register Reg = Op.getReg();
1215 if (Reg.isPhysical())
1218 MachineInstr *Def = MRI->getVRegDef(Reg);
1219 return CurrentLoop->isLoopInvariant(*Def);
1225 MinInstr = Traces->getEnsemble(MachineTraceStrategy::TS_MinInstrCount);
1229 LLVM_DEBUG(
dbgs() <<
"TBB: " << TBBTrace <<
"FBB: " << FBBTrace);
1236 bool DataDependent =
false;
1238 DataDependent = isConditionDataDependent();
1240 unsigned CritLimit = DataDependent ? STI->getMispredictionPenalty()
1241 : STI->getMispredictionPenalty() / 2;
1243 MachineBasicBlock &
MBB = *IfConv.Head;
1247 if (DataDependent) {
1249 return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE,
1250 "DataDependentCondition",
1252 <<
"branch condition is data-dependent (from memory load), "
1253 <<
"using higher CritLimit of " <<
ore::NV(
"CritLimit", CritLimit)
1262 if (IfConv.TBB != IfConv.Tail)
1266 <<
", minimal critical path " << MinCrit <<
'\n');
1267 if (ResLength > MinCrit + CritLimit) {
1270 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"IfConversion",
1272 R <<
"did not if-convert branch: the resulting critical path ("
1273 << Cycles{
"ResLength", ResLength}
1274 <<
") would extend the shorter leg's critical path ("
1275 << Cycles{
"MinCrit", MinCrit} <<
") by more than the threshold of "
1276 << Cycles{
"CritLimit", CritLimit}
1277 <<
", which cannot be hidden by available ILP.";
1287 unsigned BranchDepth =
1294 struct CriticalPathInfo {
1298 CriticalPathInfo
Cond{};
1299 CriticalPathInfo TBlock{};
1300 CriticalPathInfo FBlock{};
1301 bool ShouldConvert =
true;
1302 for (SSAIfConv::PHIInfo &PI : IfConv.PHIs) {
1309 if (CondDepth > MaxDepth) {
1310 unsigned Extra = CondDepth - MaxDepth;
1311 LLVM_DEBUG(
dbgs() <<
"Condition adds " << Extra <<
" cycles.\n");
1312 if (Extra >
Cond.Extra)
1313 Cond = {Extra, CondDepth};
1314 if (Extra > CritLimit) {
1316 ShouldConvert =
false;
1323 if (TDepth > MaxDepth) {
1324 unsigned Extra = TDepth - MaxDepth;
1326 if (Extra > TBlock.Extra)
1327 TBlock = {Extra, TDepth};
1328 if (Extra > CritLimit) {
1330 ShouldConvert =
false;
1337 if (FDepth > MaxDepth) {
1338 unsigned Extra = FDepth - MaxDepth;
1340 if (Extra > FBlock.Extra)
1341 FBlock = {Extra, FDepth};
1342 if (Extra > CritLimit) {
1344 ShouldConvert =
false;
1352 const CriticalPathInfo
Short = TBlock.Extra > FBlock.Extra ? FBlock : TBlock;
1353 const CriticalPathInfo
Long = TBlock.Extra > FBlock.Extra ? TBlock : FBlock;
1355 if (ShouldConvert) {
1357 MachineOptimizationRemark
R(
DEBUG_TYPE,
"IfConversion",
1359 R <<
"performing if-conversion on branch: the condition adds "
1360 << Cycles{
"CondCycles",
Cond.Extra} <<
" to the critical path";
1361 if (
Short.Extra > 0)
1362 R <<
", and the short leg adds another "
1363 << Cycles{
"ShortCycles",
Short.Extra};
1365 R <<
", and the long leg adds another "
1366 << Cycles{
"LongCycles",
Long.Extra};
1367 R <<
", each staying under the threshold of "
1368 << Cycles{
"CritLimit", CritLimit} <<
".";
1373 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"IfConversion",
1375 R <<
"did not if-convert branch: the condition would add "
1376 << Cycles{
"CondCycles",
Cond.Extra} <<
" to the critical path";
1377 if (
Cond.Extra > CritLimit)
1378 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1379 if (
Short.Extra > 0) {
1380 R <<
", and the short leg would add another "
1381 << Cycles{
"ShortCycles",
Short.Extra};
1382 if (
Short.Extra > CritLimit)
1383 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1385 if (
Long.Extra > 0) {
1386 R <<
", and the long leg would add another "
1387 << Cycles{
"LongCycles",
Long.Extra};
1388 if (
Long.Extra > CritLimit)
1389 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1396 return ShouldConvert;
1401bool EarlyIfConverter::tryConvertIf(MachineBasicBlock *
MBB) {
1403 while (IfConv.canConvertIf(
MBB) && shouldConvertIf()) {
1406 SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
1407 IfConv.convertIf(RemoveBlocks);
1409 updateDomTree(DomTree, IfConv, RemoveBlocks);
1410 updateLoops(
Loops, RemoveBlocks);
1413 NoCallBlocksCache.erase(IfConv.Head);
1414 for (MachineBasicBlock *
MBB : RemoveBlocks) {
1415 NoCallBlocksCache.erase(
MBB);
1423 LLVM_DEBUG(
dbgs() <<
"********** EARLY IF-CONVERSION **********\n"
1424 <<
"********** Function: " << MF.
getName() <<
'\n');
1444 if (tryConvertIf(DomNode->getBlock()))
1460 EarlyIfConverter Impl(MDT, LI, MTM, MBPI);
1472bool EarlyIfConverterLegacy::runOnMachineFunction(
MachineFunction &MF) {
1477 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1478 MachineLoopInfo &LI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1480 getAnalysis<MachineTraceMetricsWrapperPass>().getMTM();
1483 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1485 return EarlyIfConverter(MDT, LI, MTM, MBPI).run(MF);
1506 void getAnalysisUsage(AnalysisUsage &AU)
const override;
1508 StringRef getPassName()
const override {
return "Early If-predicator"; }
1511 bool tryConvertIf(MachineBasicBlock *);
1512 bool shouldConvertIf();
1517#define DEBUG_TYPE "early-if-predicator"
1519char EarlyIfPredicator::ID = 0;
1529void EarlyIfPredicator::getAnalysisUsage(
AnalysisUsage &AU)
const {
1539bool EarlyIfPredicator::shouldConvertIf() {
1541 if (IfConv.isTriangle()) {
1542 MachineBasicBlock &IfBlock =
1543 (IfConv.TBB == IfConv.Tail) ? *IfConv.FBB : *IfConv.
TBB;
1545 unsigned ExtraPredCost = 0;
1546 unsigned Cycles = 0;
1547 for (MachineInstr &
I : IfBlock) {
1548 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1550 Cycles += NumCycles - 1;
1551 ExtraPredCost +=
TII->getPredicationCost(
I);
1557 unsigned TExtra = 0;
1558 unsigned FExtra = 0;
1559 unsigned TCycle = 0;
1560 unsigned FCycle = 0;
1561 for (MachineInstr &
I : *IfConv.TBB) {
1562 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1564 TCycle += NumCycles - 1;
1565 TExtra +=
TII->getPredicationCost(
I);
1567 for (MachineInstr &
I : *IfConv.FBB) {
1568 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1570 FCycle += NumCycles - 1;
1571 FExtra +=
TII->getPredicationCost(
I);
1574 FCycle, FExtra, TrueProbability);
1579bool EarlyIfPredicator::tryConvertIf(MachineBasicBlock *
MBB) {
1581 while (IfConv.canConvertIf(
MBB,
true) && shouldConvertIf()) {
1583 SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
1584 IfConv.convertIf(RemoveBlocks,
true);
1586 updateDomTree(DomTree, IfConv, RemoveBlocks);
1587 updateLoops(
Loops, RemoveBlocks);
1588 for (MachineBasicBlock *
MBB : RemoveBlocks)
1595 LLVM_DEBUG(
dbgs() <<
"********** EARLY IF-PREDICATOR **********\n"
1596 <<
"********** Function: " << MF.
getName() <<
'\n');
1604 SchedModel.
init(&STI);
1605 DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1606 Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1607 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1617 if (tryConvertIf(DomNode->getBlock()))
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static unsigned InstrCount
This file defines the DenseMap class.
This file defines the DenseSet and SmallDenseSet classes.
static cl::opt< unsigned > MaxRegionInstrs("early-ifcvt-max-region-instrs", cl::Hidden, cl::init(64), cl::desc("Limit the number of blocks and instructions examined when " "searching for calls between a load and the condition it feeds"))
static cl::opt< unsigned > MaxNumSteps("early-ifcvt-max-steps", cl::Hidden, cl::init(16), cl::desc("Limit the number of steps taken when searching for a " "recently loaded value"))
static bool hasSameValue(const MachineRegisterInfo &MRI, const TargetInstrInfo *TII, Register TReg, Register FReg)
static unsigned adjCycles(unsigned Cyc, int Delta)
static cl::opt< bool > Stress("stress-early-ifcvt", cl::Hidden, cl::desc("Turn all knobs to 11"))
static cl::opt< unsigned > BlockInstrLimit("early-ifcvt-limit", cl::init(30), cl::Hidden, cl::desc("Maximum number of instructions per speculated block."))
static bool isConstantPoolLoad(const MachineInstr *MI)
static cl::opt< bool > EnableDataDependentBranchAnalysis("enable-early-ifcvt-data-dependent", cl::Hidden, cl::init(false), cl::desc("Enable hard-to-predict branch analysis for if-conversion"))
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the SmallPtrSet class.
This file defines the SparseSet class derived from the version described in Briggs,...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
bool test(unsigned Idx) const
Returns true if bit Idx is set.
BitVector & reset()
Reset all bits in the bitvector.
BitVector & set()
Set all bits in the bitvector.
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
void eraseNode(NodeT *BB)
eraseNode - Removes a node from the dominator tree.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
bool analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
Return true if it's profitable to predicate instructions with accumulated instruction latency of "Num...
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Cond) const override
Convert the instruction into a predicated instruction.
bool isPredicable(const MachineInstr &MI) const override
Return true if the specified instruction can be predicated.
unsigned pred_size() const
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator instr_begin()
succ_iterator succ_begin()
bool livein_empty() const
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
instr_iterator instr_end()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI void moveAfter(MachineBasicBlock *NewBefore)
LLVM_ABI BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & back() const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
LLVM_ABI bool isDereferenceableInvariantLoad() const
Return true if this load instruction never traps and points to a memory location whose value doesn't ...
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
mop_range uses()
Returns all operands which may be register uses.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI int findRegisterDefOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false) const
Returns the operand index that is a def of the specified register or -1 if it is not found.
Analysis pass that exposes the MachineLoopInfo for a machine function.
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI LLVM_READONLY MachineInstr * getUniqueVRegDef(Register Reg) const
getUniqueVRegDef - Return the unique machine instr that defines the specified virtual register or nul...
LLVM_ABI unsigned getResourceLength(ArrayRef< const MachineBasicBlock * > Extrablocks={}, ArrayRef< const MCSchedClassDesc * > ExtraInstrs={}, ArrayRef< const MCSchedClassDesc * > RemoveInstrs={}) const
Return the resource length of the trace.
InstrCycles getInstrCycles(const MachineInstr &MI) const
Return the depth and height of MI.
LLVM_ABI unsigned getInstrSlack(const MachineInstr &MI) const
Return the slack of MI.
unsigned getCriticalPath() const
Return the length of the (data dependency) critical path through the trace.
LLVM_ABI unsigned getPHIDepth(const MachineInstr &PHI) const
Return the Depth of a PHI instruction in a trace center block successor.
LLVM_ABI void verifyAnalysis() const
LLVM_ABI void invalidate(const MachineBasicBlock *MBB)
Invalidate cached information about MBB.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void push_back(const T &Elt)
iterator erase(iterator I)
erase - Erases an existing element identified by a valid iterator.
void clear()
clear - Clears the set.
std::pair< iterator, bool > insert(const ValueT &Val)
insert - Attempts to insert a new element.
bool empty() const
empty - Returns true if the set is empty.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Provide an instruction scheduling machine model to CodeGen passes.
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual bool enableEarlyIfConversion() const
Enable the use of the early if conversion pass.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
self_iterator getIterator()
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI Printable printRegUnit(MCRegUnit Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI char & EarlyIfConverterLegacyID
EarlyIfConverter - This pass performs if-conversion on SSA form by inserting cmov instructions.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto post_order(const T &G)
Post-order traversal of a graph.
auto instructionsWithoutDebug(IterT It, IterT End, bool SkipPseudoOp=true)
Construct a range iterator which begins at It and moves forwards until End is reached,...
LLVM_ABI char & EarlyIfPredicatorID
EarlyIfPredicator - This pass performs if-conversion on SSA form by predicating if/else block and ins...
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned Depth
Earliest issue cycle as determined by data dependencies and instruction latencies from the beginning ...
MachineInstr * ConditionDef