62#define DEBUG_TYPE "if-converter"
85STATISTIC(NumSimple,
"Number of simple if-conversions performed");
86STATISTIC(NumSimpleFalse,
"Number of simple (F) if-conversions performed");
87STATISTIC(NumTriangle,
"Number of triangle if-conversions performed");
88STATISTIC(NumTriangleRev,
"Number of triangle (R) if-conversions performed");
89STATISTIC(NumTriangleFalse,
"Number of triangle (F) if-conversions performed");
90STATISTIC(NumTriangleFRev,
"Number of triangle (F/R) if-conversions performed");
91STATISTIC(NumDiamonds,
"Number of diamond if-conversions performed");
92STATISTIC(NumForkedDiamonds,
"Number of forked-diamond if-conversions performed");
93STATISTIC(NumIfConvBBs,
"Number of if-converted blocks");
95STATISTIC(NumUnpred,
"Number of true blocks of diamonds unpredicated");
99class IfConverterImpl {
145 bool IsBeingAnalyzed : 1;
148 bool IsBrAnalyzable : 1;
149 bool IsBrReversible : 1;
150 bool HasFallThrough : 1;
151 bool IsUnpredicable : 1;
152 bool CannotBeCopied : 1;
153 bool ClobbersPred : 1;
154 unsigned NonPredSize = 0;
155 unsigned ExtraCost = 0;
156 unsigned ExtraCost2 = 0;
157 MachineBasicBlock *BB =
nullptr;
158 MachineBasicBlock *TrueBB =
nullptr;
159 MachineBasicBlock *FalseBB =
nullptr;
160 SmallVector<MachineOperand, 4> BrCond;
161 SmallVector<MachineOperand, 4> Predicate;
167 ClobbersPred(
false) {}
186 bool NeedSubsumption : 1;
187 bool TClobbersPred : 1;
188 bool FClobbersPred : 1;
190 IfcvtToken(BBInfo &b, IfcvtKind k,
bool s,
unsigned d,
unsigned d2 = 0,
191 bool tc =
false,
bool fc =
false)
192 : BBI(
b), Kind(
k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
193 TClobbersPred(tc), FClobbersPred(fc) {}
198 std::vector<BBInfo> BBAnalysis;
199 TargetSchedModel SchedModel;
201 const TargetLoweringBase *TLI =
nullptr;
202 const TargetInstrInfo *TII =
nullptr;
203 const TargetRegisterInfo *TRI =
nullptr;
204 const MachineBranchProbabilityInfo *MBPI =
nullptr;
205 MachineRegisterInfo *MRI =
nullptr;
209 bool PreRegAlloc =
true;
210 bool MadeChange =
false;
213 bool reverseBranchCondition(BBInfo &BBI)
const;
214 bool ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
215 BranchProbability Prediction)
const;
216 bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
bool FalseBranch,
217 unsigned &Dups, BranchProbability Prediction)
const;
218 bool CountDuplicatedInstructions(
221 unsigned &Dups1,
unsigned &Dups2, MachineBasicBlock &
TBB,
222 MachineBasicBlock &FBB,
bool SkipUnconditionalBranches)
const;
223 bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
unsigned &Dups1,
224 unsigned &Dups2, BBInfo &TrueBBICalc,
225 BBInfo &FalseBBICalc)
const;
226 bool ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
unsigned &Dups1,
227 unsigned &Dups2, BBInfo &TrueBBICalc,
228 BBInfo &FalseBBICalc)
const;
229 void AnalyzeBranches(BBInfo &BBI);
232 bool BranchUnpredicable =
false)
const;
237 BBInfo &FalseBBI)
const;
238 void AnalyzeBlock(MachineBasicBlock &
MBB,
239 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
240 bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &
Pred,
241 bool isTriangle =
false,
bool RevBranch =
false,
242 bool hasCommonTail =
false);
244 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
245 void InvalidatePreds(MachineBasicBlock &
MBB);
246 bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
247 bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
248 bool IfConvertDiamondCommon(BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
249 unsigned NumDups1,
unsigned NumDups2,
250 bool TClobbersPred,
bool FClobbersPred,
251 bool RemoveBranch,
bool MergeAddEdges);
252 bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
unsigned NumDups1,
253 unsigned NumDups2,
bool TClobbers,
bool FClobbers);
254 bool IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind Kind,
unsigned NumDups1,
255 unsigned NumDups2,
bool TClobbers,
258 SmallVectorImpl<MachineOperand> &
Cond,
259 SmallSet<MCRegister, 4> *LaterRedefs =
nullptr);
260 void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
261 SmallVectorImpl<MachineOperand> &
Cond,
262 bool IgnoreBr =
false);
263 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges =
true);
265 bool MeetIfcvtSizeLimit(MachineBasicBlock &BB,
unsigned Cycle,
unsigned Extra,
266 BranchProbability Prediction)
const {
267 return Cycle > 0 && TII->isProfitableToIfCvt(BB, Cycle, Extra, Prediction);
270 bool MeetIfcvtSizeLimit(BBInfo &TBBInfo, BBInfo &FBBInfo,
271 MachineBasicBlock &CommBB,
unsigned Dups,
272 BranchProbability Prediction,
bool Forked)
const {
280 unsigned Dups1 = 0, Dups2 = 0;
281 if (!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
282 *TBBInfo.BB, *FBBInfo.BB,
286 unsigned BranchBytes = 0;
287 unsigned CommonBytes = 0;
290 for (
auto &
I :
make_range(TBBInfo.BB->begin(), TIB)) {
292 CommonBytes += TII->getInstSizeInBytes(
I);
294 for (
auto &
I :
make_range(FBBInfo.BB->begin(), FIB)) {
296 CommonBytes += TII->getInstSizeInBytes(
I);
303 for (
auto &
I :
make_range(TIE, TBBInfo.BB->end())) {
304 if (
I.isBranch() && TBBInfo.IsBrAnalyzable && !Forked) {
306 BranchBytes += TII->predictBranchSizeForIfCvt(
I);
309 CommonBytes += TII->getInstSizeInBytes(
I);
312 for (
auto &
I :
make_range(FIE, FBBInfo.BB->end())) {
313 if (
I.isBranch() && FBBInfo.IsBrAnalyzable && !Forked) {
315 BranchBytes += TII->predictBranchSizeForIfCvt(
I);
318 CommonBytes += TII->getInstSizeInBytes(
I);
324 BranchBytes += TII->predictBranchSizeForIfCvt(
I);
333 unsigned NumPredicatedInstructions = 0;
335 if (!
I.isDebugInstr()) {
337 NumPredicatedInstructions++;
341 if (!
I.isDebugInstr()) {
343 NumPredicatedInstructions++;
349 if (NumPredicatedInstructions > 15)
354 unsigned ExtraPredicateBytes =
355 TII->extraSizeToPredicateInstructions(MF, NumPredicatedInstructions);
358 dbgs() <<
"MeetIfcvtSizeLimit(BranchBytes=" << BranchBytes
359 <<
", CommonBytes=" << CommonBytes
360 <<
", NumPredicatedInstructions=" << NumPredicatedInstructions
361 <<
", ExtraPredicateBytes=" << ExtraPredicateBytes <<
")\n");
362 return (BranchBytes + CommonBytes) > ExtraPredicateBytes;
364 unsigned TCycle = TBBInfo.NonPredSize + TBBInfo.ExtraCost - Dups;
365 unsigned FCycle = FBBInfo.NonPredSize + FBBInfo.ExtraCost - Dups;
366 bool Res = TCycle > 0 && FCycle > 0 &&
367 TII->isProfitableToIfCvt(
368 *TBBInfo.BB, TCycle, TBBInfo.ExtraCost2, *FBBInfo.BB,
369 FCycle, FBBInfo.ExtraCost2, Prediction);
370 LLVM_DEBUG(
dbgs() <<
"MeetIfcvtSizeLimit(TCycle=" << TCycle <<
", FCycle="
371 << FCycle <<
", TExtra=" << TBBInfo.ExtraCost2
372 <<
", FExtra=" << FBBInfo.ExtraCost2 <<
") = " << Res
379 bool blockAlwaysFallThrough(BBInfo &BBI)
const {
380 return BBI.IsBrAnalyzable && BBI.TrueBB ==
nullptr;
384 bool blockNeverFallThrough(BBInfo &BBI)
const {
386 if (BBI.IsBrAnalyzable)
387 return !BBI.HasFallThrough;
392 if (
I == BBI.BB->getParent()->end() || !PI->isSuccessor(&*
I))
399 static bool IfcvtTokenCmp(
const std::unique_ptr<IfcvtToken> &
C1,
400 const std::unique_ptr<IfcvtToken> &C2) {
401 int Incr1 = (
C1->Kind == ICDiamond) ? -(
int)(
C1->NumDups +
C1->NumDups2)
403 int Incr2 = (C2->Kind == ICDiamond) ? -(int)(C2->NumDups + C2->NumDups2)
407 else if (Incr1 == Incr2) {
409 if (!
C1->NeedSubsumption && C2->NeedSubsumption)
411 else if (
C1->NeedSubsumption == C2->NeedSubsumption) {
413 if ((
unsigned)
C1->Kind < (
unsigned)C2->Kind)
415 else if (
C1->Kind == C2->Kind)
416 return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
423 bool runOnMachineFunction(
424 MachineFunction &MF, function_ref<MachineBlockFrequencyInfo &()> GetMBFI,
425 function_ref<MachineBranchProbabilityInfo *()> GetMBPI,
426 function_ref<ProfileSummaryInfo *()> GetPSI,
436 IfConverterLegacy(std::function<
bool(
const MachineFunction &)> Ftor =
nullptr)
437 : MachineFunctionPass(ID), PredicateFtor(std::
move(Ftor)) {}
439 void getAnalysisUsage(AnalysisUsage &AU)
const override {
440 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
441 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
449 MachineFunctionProperties getRequiredProperties()
const override {
450 return MachineFunctionProperties().setNoVRegs();
456char IfConverterLegacy::ID = 0;
466bool IfConverterImpl::runOnMachineFunction(
471 if (PredicateFtor(MF))
475 TLI = ST.getTargetLowering();
476 TII = ST.getInstrInfo();
477 TRI = ST.getRegisterInfo();
481 MRI = &MF.getRegInfo();
482 SchedModel.
init(&ST);
484 if (!
TII)
return false;
486 PreRegAlloc =
MRI->isSSA();
488 bool BFChange =
false;
496 << MF.getName() <<
"\'");
505 BBAnalysis.resize(MF.getNumBlockIDs());
507 std::vector<std::unique_ptr<IfcvtToken>> Tokens;
509 unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
510 NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
515 AnalyzeBlocks(MF, Tokens);
516 while (!Tokens.empty()) {
517 std::unique_ptr<IfcvtToken> Token = std::move(Tokens.back());
519 BBInfo &BBI = Token->BBI;
520 IfcvtKind Kind = Token->Kind;
521 unsigned NumDups = Token->NumDups;
522 unsigned NumDups2 = Token->NumDups2;
527 BBI.IsEnqueued =
false;
531 BBI.IsEnqueued =
false;
537 case ICSimpleFalse: {
538 bool isFalse = Kind == ICSimpleFalse;
541 << (Kind == ICSimpleFalse ?
" false" :
"")
543 << ((Kind == ICSimpleFalse) ? BBI.FalseBB->getNumber()
544 : BBI.TrueBB->getNumber())
546 RetVal = IfConvertSimple(BBI, Kind);
547 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
549 if (isFalse) ++NumSimpleFalse;
556 case ICTriangleFalse:
557 case ICTriangleFRev: {
558 bool isFalse = Kind == ICTriangleFalse;
559 bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
569 <<
" (T:" << BBI.TrueBB->getNumber()
570 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
571 RetVal = IfConvertTriangle(BBI, Kind);
572 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
586 <<
" (T:" << BBI.TrueBB->getNumber()
587 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
588 RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,
589 Token->TClobbersPred,
590 Token->FClobbersPred);
591 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
592 if (RetVal) ++NumDiamonds;
594 case ICForkedDiamond:
598 <<
" (T:" << BBI.TrueBB->getNumber()
599 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
600 RetVal = IfConvertForkedDiamond(BBI, Kind, NumDups, NumDups2,
601 Token->TClobbersPred,
602 Token->FClobbersPred);
603 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
604 if (RetVal) ++NumForkedDiamonds;
608 if (RetVal &&
MRI->tracksLiveness())
613 NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
614 NumTriangleFalse + NumTriangleFRev + NumDiamonds;
621 MadeChange |= Change;
632 MadeChange |= BFChange;
640 if (SuccBB != TrueBB)
648bool IfConverterImpl::reverseBranchCondition(BBInfo &BBI)
const {
672bool IfConverterImpl::ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
673 BranchProbability Prediction)
const {
675 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
678 if (TrueBBI.IsBrAnalyzable)
681 if (TrueBBI.BB->pred_size() > 1) {
682 if (TrueBBI.CannotBeCopied ||
686 Dups = TrueBBI.NonPredSize;
697bool IfConverterImpl::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
698 bool FalseBranch,
unsigned &Dups,
699 BranchProbability Prediction)
const {
701 if (TrueBBI.BB == FalseBBI.BB)
704 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
707 if (TrueBBI.BB->pred_size() > 1) {
708 if (TrueBBI.CannotBeCopied)
711 unsigned Size = TrueBBI.NonPredSize;
712 if (TrueBBI.IsBrAnalyzable) {
713 if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
717 MachineBasicBlock *FExit = FalseBranch
718 ? TrueBBI.TrueBB : TrueBBI.FalseBB;
729 MachineBasicBlock *TExit = FalseBranch ? TrueBBI.FalseBB : TrueBBI.TrueBB;
730 if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
732 if (++
I == TrueBBI.BB->getParent()->end())
736 return TExit && TExit == FalseBBI.BB;
759bool IfConverterImpl::CountDuplicatedInstructions(
762 unsigned &Dups1,
unsigned &Dups2, MachineBasicBlock &
TBB,
763 MachineBasicBlock &FBB,
bool SkipUnconditionalBranches)
const {
764 while (TIB != TIE && FIB != FIE) {
768 if (TIB == TIE || FIB == FIE)
770 if (!TIB->isIdenticalTo(*FIB))
774 std::vector<MachineOperand> PredDefs;
778 if (!TIB->isBranch())
785 if (TIB == TIE || FIB == FIE)
797 if (SkipUnconditionalBranches) {
798 while (RTIE != RTIB && RTIE->isUnconditionalBranch())
800 while (RFIE != RFIB && RFIE->isUnconditionalBranch())
806 while (RTIE != RTIB && RFIE != RFIB) {
811 if (RTIE == RTIB || RFIE == RFIB)
813 if (!RTIE->isIdenticalTo(*RFIE))
817 if (!RTIE->isBranch())
841 BBInfo &FalseBBI)
const {
842 bool BranchUnpredicable =
true;
843 TrueBBI.IsUnpredicable = FalseBBI.IsUnpredicable =
false;
844 ScanInstructions(TrueBBI, TIB, TIE, BranchUnpredicable);
845 if (TrueBBI.IsUnpredicable)
847 ScanInstructions(FalseBBI, FIB, FIE, BranchUnpredicable);
848 if (FalseBBI.IsUnpredicable)
850 if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)
863 while (E1 != B1 && E2 != B2) {
866 if (E1 == B1 && E2 == B2)
870 assert(!E2->isBranch() &&
"Branch mis-match, one block is empty.");
874 assert(!E1->isBranch() &&
"Branch mis-match, one block is empty.");
878 if (E1->isBranch() || E2->isBranch())
879 assert(E1->isIdenticalTo(*E2) &&
880 "Branch mis-match, branch instructions don't match.");
902bool IfConverterImpl::ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
903 unsigned &Dups1,
unsigned &Dups2,
905 BBInfo &FalseBBICalc)
const {
907 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
908 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
911 if (!TrueBBI.IsBrAnalyzable || !FalseBBI.IsBrAnalyzable)
914 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
919 if (TrueBBI.BrCond.size() == 0 ||
920 FalseBBI.BrCond.size() == 0)
923 MachineBasicBlock *
TT = TrueBBI.TrueBB;
924 MachineBasicBlock *TF = TrueBBI.FalseBB;
925 MachineBasicBlock *FT = FalseBBI.TrueBB;
926 MachineBasicBlock *FF = FalseBBI.FalseBB;
941 if (!((TT == FT && TF == FF) || (TF == FT && TT == FF)))
944 bool FalseReversed =
false;
945 if (TF == FT && TT == FF) {
947 if (!FalseBBI.IsBrReversible)
949 FalseReversed =
true;
950 reverseBranchCondition(FalseBBI);
954 reverseBranchCondition(FalseBBI);
962 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
963 *TrueBBI.BB, *FalseBBI.BB,
967 TrueBBICalc.BB = TrueBBI.BB;
968 FalseBBICalc.BB = FalseBBI.BB;
969 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
970 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
971 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
977 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
978 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
984bool IfConverterImpl::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
985 unsigned &Dups1,
unsigned &Dups2,
987 BBInfo &FalseBBICalc)
const {
989 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
990 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
995 if (TrueBBI.BB == FalseBBI.BB)
998 MachineBasicBlock *
TT = TrueBBI.TrueBB;
999 MachineBasicBlock *FT = FalseBBI.TrueBB;
1001 if (!TT && blockAlwaysFallThrough(TrueBBI))
1003 if (!FT && blockAlwaysFallThrough(FalseBBI))
1007 if (!TT && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
1009 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
1013 if (TrueBBI.FalseBB || FalseBBI.FalseBB)
1020 bool SkipUnconditionalBranches =
1021 TrueBBI.IsBrAnalyzable && FalseBBI.IsBrAnalyzable;
1026 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
1027 *TrueBBI.BB, *FalseBBI.BB,
1028 SkipUnconditionalBranches))
1031 TrueBBICalc.BB = TrueBBI.BB;
1032 FalseBBICalc.BB = FalseBBI.BB;
1033 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
1034 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
1035 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
1040 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
1041 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
1047void IfConverterImpl::AnalyzeBranches(BBInfo &BBI) {
1051 BBI.TrueBB = BBI.FalseBB =
nullptr;
1053 BBI.IsBrAnalyzable =
1055 if (!BBI.IsBrAnalyzable) {
1056 BBI.TrueBB =
nullptr;
1057 BBI.FalseBB =
nullptr;
1061 SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1062 BBI.IsBrReversible = (RevCond.size() == 0) ||
1064 BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB ==
nullptr;
1066 if (BBI.BrCond.size()) {
1073 BBI.IsUnpredicable =
true;
1083void IfConverterImpl::ScanInstructions(BBInfo &BBI,
1086 bool BranchUnpredicable)
const {
1087 if (BBI.IsDone || BBI.IsUnpredicable)
1090 bool AlreadyPredicated = !BBI.Predicate.empty();
1092 BBI.NonPredSize = 0;
1095 BBI.ClobbersPred =
false;
1097 if (
MI.isDebugInstr())
1130 if (
MI.isNotDuplicable() ||
MI.isConvergent())
1131 BBI.CannotBeCopied =
true;
1134 bool isCondBr = BBI.IsBrAnalyzable &&
MI.isConditionalBranch();
1136 if (BranchUnpredicable &&
MI.isBranch()) {
1137 BBI.IsUnpredicable =
true;
1145 if (!isPredicated) {
1147 unsigned ExtraPredCost =
TII->getPredicationCost(
MI);
1148 unsigned NumCycles = SchedModel.computeInstrLatency(&
MI,
false);
1150 BBI.ExtraCost += NumCycles-1;
1151 BBI.ExtraCost2 += ExtraPredCost;
1152 }
else if (!AlreadyPredicated) {
1156 BBI.IsUnpredicable =
true;
1160 if (BBI.ClobbersPred && !isPredicated) {
1165 BBI.IsUnpredicable =
true;
1171 std::vector<MachineOperand> PredDefs;
1173 BBI.ClobbersPred =
true;
1176 BBI.IsUnpredicable =
true;
1191bool IfConverterImpl::FeasibilityAnalysis(BBInfo &BBI,
1192 SmallVectorImpl<MachineOperand> &
Pred,
1193 bool isTriangle,
bool RevBranch,
1194 bool hasCommonTail) {
1199 if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))
1205 if (BBI.Predicate.size() && !BBI.IsBrAnalyzable)
1213 if (!hasCommonTail && BBI.BrCond.size()) {
1218 SmallVector<MachineOperand, 4> RevPred(
Pred.begin(),
Pred.end());
1219 SmallVector<MachineOperand, 4>
Cond(BBI.BrCond.begin(), BBI.BrCond.end());
1234void IfConverterImpl::AnalyzeBlock(
1235 MachineBasicBlock &
MBB, std::vector<std::unique_ptr<IfcvtToken>> &Tokens) {
1237 BBState(MachineBasicBlock &
MBB) :
MBB(&
MBB) {}
1238 MachineBasicBlock *
MBB;
1241 bool SuccsAnalyzed =
false;
1247 while (!BBStack.empty()) {
1248 BBState &State = BBStack.back();
1249 MachineBasicBlock *BB = State.MBB;
1250 BBInfo &BBI = BBAnalysis[BB->
getNumber()];
1252 if (!State.SuccsAnalyzed) {
1253 if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
1259 BBI.IsBeingAnalyzed =
true;
1261 AnalyzeBranches(BBI);
1264 ScanInstructions(BBI, Begin,
End);
1268 if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
1269 BBI.IsBeingAnalyzed =
false;
1270 BBI.IsAnalyzed =
true;
1276 if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
1277 BBI.IsBeingAnalyzed =
false;
1278 BBI.IsAnalyzed =
true;
1285 BBI.IsBeingAnalyzed =
false;
1286 BBI.IsAnalyzed =
true;
1292 State.SuccsAnalyzed =
true;
1293 BBStack.push_back(*BBI.FalseBB);
1294 BBStack.push_back(*BBI.TrueBB);
1298 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1299 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1301 if (TrueBBI.IsDone && FalseBBI.IsDone) {
1302 BBI.IsBeingAnalyzed =
false;
1303 BBI.IsAnalyzed =
true;
1308 SmallVector<MachineOperand, 4>
1309 RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1314 bool TNeedSub = !TrueBBI.Predicate.empty();
1315 bool FNeedSub = !FalseBBI.Predicate.empty();
1316 bool Enqueued =
false;
1321 BBInfo TrueBBICalc, FalseBBICalc;
1322 auto feasibleDiamond = [&](
bool Forked) {
1323 bool MeetsSize = MeetIfcvtSizeLimit(TrueBBICalc, FalseBBICalc, *BB,
1324 Dups + Dups2, Prediction, Forked);
1325 bool TrueFeasible = FeasibilityAnalysis(TrueBBI, BBI.BrCond,
1328 bool FalseFeasible = FeasibilityAnalysis(FalseBBI, RevCond,
1331 return MeetsSize && TrueFeasible && FalseFeasible;
1334 if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1335 TrueBBICalc, FalseBBICalc)) {
1336 if (feasibleDiamond(
false)) {
1345 Tokens.push_back(std::make_unique<IfcvtToken>(
1346 BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1347 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1350 }
else if (ValidForkedDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1351 TrueBBICalc, FalseBBICalc)) {
1352 if (feasibleDiamond(
true)) {
1363 Tokens.push_back(std::make_unique<IfcvtToken>(
1364 BBI, ICForkedDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1365 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1371 if (ValidTriangle(TrueBBI, FalseBBI,
false, Dups, Prediction) &&
1372 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1373 TrueBBI.ExtraCost2, Prediction) &&
1374 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true)) {
1383 std::make_unique<IfcvtToken>(BBI, ICTriangle, TNeedSub, Dups));
1387 if (ValidTriangle(TrueBBI, FalseBBI,
true, Dups, Prediction) &&
1388 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1389 TrueBBI.ExtraCost2, Prediction) &&
1390 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true,
true)) {
1392 std::make_unique<IfcvtToken>(BBI, ICTriangleRev, TNeedSub, Dups));
1396 if (ValidSimple(TrueBBI, Dups, Prediction) &&
1397 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1398 TrueBBI.ExtraCost2, Prediction) &&
1399 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
1408 std::make_unique<IfcvtToken>(BBI, ICSimple, TNeedSub, Dups));
1414 if (ValidTriangle(FalseBBI, TrueBBI,
false, Dups,
1416 MeetIfcvtSizeLimit(*FalseBBI.BB,
1417 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1418 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1419 FeasibilityAnalysis(FalseBBI, RevCond,
true)) {
1420 Tokens.push_back(std::make_unique<IfcvtToken>(BBI, ICTriangleFalse,
1425 if (ValidTriangle(FalseBBI, TrueBBI,
true, Dups,
1427 MeetIfcvtSizeLimit(*FalseBBI.BB,
1428 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1429 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1430 FeasibilityAnalysis(FalseBBI, RevCond,
true,
true)) {
1432 std::make_unique<IfcvtToken>(BBI, ICTriangleFRev, FNeedSub, Dups));
1436 if (ValidSimple(FalseBBI, Dups, Prediction.
getCompl()) &&
1437 MeetIfcvtSizeLimit(*FalseBBI.BB,
1438 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1439 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1440 FeasibilityAnalysis(FalseBBI, RevCond)) {
1442 std::make_unique<IfcvtToken>(BBI, ICSimpleFalse, FNeedSub, Dups));
1447 BBI.IsEnqueued = Enqueued;
1448 BBI.IsBeingAnalyzed =
false;
1449 BBI.IsAnalyzed =
true;
1455void IfConverterImpl::AnalyzeBlocks(
1456 MachineFunction &MF, std::vector<std::unique_ptr<IfcvtToken>> &Tokens) {
1457 for (MachineBasicBlock &
MBB : MF)
1458 AnalyzeBlock(
MBB, Tokens);
1474 if (
I ==
E || !
I->empty() || !PI->isSuccessor(&*
I))
1479 return PI->isSuccessor(&*
I);
1484void IfConverterImpl::InvalidatePreds(MachineBasicBlock &
MBB) {
1486 BBInfo &PBBI = BBAnalysis[Predecessor->getNumber()];
1487 if (PBBI.IsDone || PBBI.BB == &
MBB)
1489 PBBI.IsAnalyzed =
false;
1490 PBBI.IsEnqueued =
false;
1499 TII->insertBranch(
MBB, &ToMBB,
nullptr, NoCond, dl);
1512 for (
unsigned Reg : Redefs)
1519 for (
auto Clobber : Clobbers) {
1522 unsigned Reg = Clobber.first;
1526 if (
Op.isRegMask()) {
1541 [&](
MCPhysReg S) { return LiveBeforeMI.count(S); }))
1547bool IfConverterImpl::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
1548 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1549 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1550 BBInfo *CvtBBI = &TrueBBI;
1551 BBInfo *NextBBI = &FalseBBI;
1553 SmallVector<MachineOperand, 4>
Cond(BBI.BrCond.begin(), BBI.BrCond.end());
1554 if (Kind == ICSimpleFalse)
1557 MachineBasicBlock &CvtMBB = *CvtBBI->BB;
1558 MachineBasicBlock &NextMBB = *NextBBI->BB;
1559 if (CvtBBI->IsDone ||
1560 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1562 BBI.IsAnalyzed =
false;
1563 CvtBBI->IsAnalyzed =
false;
1571 if (Kind == ICSimpleFalse)
1591 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond);
1594 BBI.BB->removeSuccessor(&CvtMBB,
true);
1597 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1601 MergeBlocks(BBI, *CvtBBI);
1604 bool IterIfcvt =
true;
1607 BBI.HasFallThrough =
false;
1624 InvalidatePreds(*BBI.BB);
1625 CvtBBI->IsDone =
true;
1632bool IfConverterImpl::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1633 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1634 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1635 BBInfo *CvtBBI = &TrueBBI;
1636 BBInfo *NextBBI = &FalseBBI;
1639 SmallVector<MachineOperand, 4>
Cond(BBI.BrCond.begin(), BBI.BrCond.end());
1640 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1643 MachineBasicBlock &CvtMBB = *CvtBBI->BB;
1644 MachineBasicBlock &NextMBB = *NextBBI->BB;
1645 if (CvtBBI->IsDone ||
1646 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1648 BBI.IsAnalyzed =
false;
1649 CvtBBI->IsAnalyzed =
false;
1657 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1661 if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
1662 if (reverseBranchCondition(*CvtBBI)) {
1668 BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
1669 if (PBBI.IsEnqueued) {
1670 PBBI.IsAnalyzed =
false;
1671 PBBI.IsEnqueued =
false;
1685 bool HasEarlyExit = CvtBBI->FalseBB !=
nullptr;
1686 BranchProbability CvtNext, CvtFalse, BBNext, BBCvt;
1703 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond,
true);
1707 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1710 MergeBlocks(BBI, *CvtBBI,
false);
1714 BBI.BB->removeSuccessor(&CvtMBB,
true);
1718 SmallVector<MachineOperand, 4> RevCond(CvtBBI->BrCond.begin(),
1719 CvtBBI->BrCond.end());
1730 auto NewNext = BBNext + BBCvt * CvtNext;
1731 auto NewTrueBBIter =
find(BBI.BB->successors(), NewTrueBB);
1732 if (NewTrueBBIter != BBI.BB->succ_end())
1733 BBI.BB->setSuccProbability(NewTrueBBIter, NewNext);
1735 auto NewFalse = BBCvt * CvtFalse;
1737 BBI.BB->addSuccessor(CvtBBI->FalseBB, NewFalse);
1742 bool FalseBBDead =
false;
1743 bool IterIfcvt =
true;
1745 if (!isFallThrough) {
1749 if (!HasEarlyExit && NextMBB.
pred_size() == 1 &&
1751 MergeBlocks(BBI, *NextBBI);
1755 BBI.HasFallThrough =
false;
1765 InvalidatePreds(*BBI.BB);
1766 CvtBBI->IsDone =
true;
1768 NextBBI->IsDone =
true;
1785bool IfConverterImpl::IfConvertDiamondCommon(
1786 BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
unsigned NumDups1,
1787 unsigned NumDups2,
bool TClobbersPred,
bool FClobbersPred,
1788 bool RemoveBranch,
bool MergeAddEdges) {
1790 if (TrueBBI.IsDone || FalseBBI.IsDone ||
1791 TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) {
1793 BBI.IsAnalyzed =
false;
1794 TrueBBI.IsAnalyzed =
false;
1795 FalseBBI.IsAnalyzed =
false;
1799 if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
1806 BBInfo *BBI1 = &TrueBBI;
1807 BBInfo *BBI2 = &FalseBBI;
1808 SmallVector<MachineOperand, 4> RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1811 SmallVector<MachineOperand, 4> *Cond1 = &BBI.BrCond;
1812 SmallVector<MachineOperand, 4> *Cond2 = &RevCond;
1815 bool DoSwap =
false;
1816 if (TClobbersPred && !FClobbersPred)
1818 else if (!TClobbersPred && !FClobbersPred) {
1819 if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
1821 }
else if (TClobbersPred && FClobbersPred)
1831 MachineBasicBlock &MBB1 = *BBI1->BB;
1832 MachineBasicBlock &MBB2 = *BBI2->BB;
1850 BBI1->NonPredSize -= NumDups1;
1851 BBI2->NonPredSize -= NumDups1;
1856 for (
unsigned i = 0; i < NumDups1; ++DI1) {
1857 if (DI1 == MBB1.
end())
1859 if (!DI1->isDebugInstr())
1862 while (NumDups1 != 0) {
1865 if (DI2->shouldUpdateAdditionalCallInfo())
1869 if (DI2 == MBB2.
end())
1871 if (!DI2->isDebugInstr())
1882 BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.
begin(), DI1);
1893 if (!BBI1->IsBrAnalyzable)
1899 while (DI1 != MBB1.
begin()) {
1901 if (!Prev->isBranch() && !Prev->isDebugInstr())
1905 for (
unsigned i = 0; i != NumDups2; ) {
1914 if (DI1->shouldUpdateAdditionalCallInfo())
1918 if (!DI1->isDebugInstr())
1923 DI2 = BBI2->BB->end();
1931 while (DI2 != MBB2.
begin()) {
1933 if (!Prev->isBranch() && !Prev->isDebugInstr())
1938 while (NumDups2 != 0) {
1944 if (!DI2->isDebugInstr())
1956 SmallSet<MCRegister, 4> RedefsByFalse;
1957 SmallSet<MCRegister, 4> ExtUses;
1958 if (
TII->isProfitableToUnpredicate(MBB1, MBB2)) {
1960 if (FI.isDebugInstr())
1963 for (
const MachineOperand &MO : FI.operands()) {
1971 }
else if (!RedefsByFalse.
count(
Reg)) {
1978 for (MCRegister
Reg : Defs) {
1986 PredicateBlock(*BBI1, MBB1.
end(), *Cond1, &RedefsByFalse);
1995 if (!MBB2.
empty() && (DI2 == MBB2.
end())) {
2000 if (BB2NonPredicated && (BB1Predicated || !BBI2->IsBrAnalyzable))
2005 PredicateBlock(*BBI2, DI2, *Cond2);
2008 MergeBlocks(BBI, *BBI1, MergeAddEdges);
2009 MergeBlocks(BBI, *BBI2, MergeAddEdges);
2015bool IfConverterImpl::IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind Kind,
2019 bool FClobbersPred) {
2020 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2021 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2026 if (TIE != TrueBBI.BB->end())
2027 dl = TIE->getDebugLoc();
2031 if (!IfConvertDiamondCommon(
2032 BBI, TrueBBI, FalseBBI,
2034 TClobbersPred, FClobbersPred,
2041 TrueBBI.BrCond, dl);
2044 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2045 InvalidatePreds(*BBI.BB);
2052bool IfConverterImpl::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
2053 unsigned NumDups1,
unsigned NumDups2,
2054 bool TClobbersPred,
bool FClobbersPred) {
2055 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2056 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2057 MachineBasicBlock *TailBB = TrueBBI.TrueBB;
2061 if (blockAlwaysFallThrough(TrueBBI))
2062 TailBB = FalseBBI.TrueBB;
2063 assert((TailBB || !TrueBBI.IsBrAnalyzable) &&
"Unexpected!");
2066 if (!IfConvertDiamondCommon(
2067 BBI, TrueBBI, FalseBBI,
2069 TClobbersPred, FClobbersPred,
2070 TrueBBI.IsBrAnalyzable,
2081 BBI.BB->removeSuccessor(TrueBBI.BB);
2082 BBI.BB->removeSuccessor(FalseBBI.BB,
true);
2084 BBInfo &TailBBI = BBAnalysis[TailBB->
getNumber()];
2086 blockNeverFallThrough(TailBBI) && !TailBBI.BB->hasAddressTaken();
2092 CanMergeTail =
false;
2095 unsigned NumPreds = TailBB->
pred_size();
2097 CanMergeTail =
false;
2098 else if (NumPreds == 1 && CanMergeTail) {
2100 if (*PI != TrueBBI.BB && *PI != FalseBBI.BB)
2101 CanMergeTail =
false;
2104 MergeBlocks(BBI, TailBBI);
2105 TailBBI.IsDone =
true;
2109 BBI.HasFallThrough =
false;
2114 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2115 InvalidatePreds(*BBI.BB);
2123 bool SawStore =
true;
2124 if (!
MI.isSafeToMove(SawStore))
2133 if (MO.isDef() && !LaterRedefs.
count(
Reg))
2143 SmallVectorImpl<MachineOperand> &
Cond,
2144 SmallSet<MCRegister, 4> *LaterRedefs) {
2145 bool AnyUnpred =
false;
2146 bool MaySpec = LaterRedefs !=
nullptr;
2147 for (MachineInstr &
I :
make_range(BBI.BB->begin(),
E)) {
2162 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2174 BBI.IsAnalyzed =
false;
2175 BBI.NonPredSize = 0;
2184void IfConverterImpl::CopyAndPredicateBlock(
2185 BBInfo &ToBBI, BBInfo &FromBBI, SmallVectorImpl<MachineOperand> &
Cond,
2189 MachineBasicBlock &FromMBB = *FromBBI.BB;
2190 for (MachineInstr &
I : FromMBB) {
2192 if (IgnoreBr &&
I.isBranch())
2195 MachineInstr *
MI = MF.CloneMachineInstr(&
I);
2197 if (
I.isCandidateForAdditionalCallInfo())
2200 ToBBI.BB->insert(ToBBI.BB->end(),
MI);
2201 ToBBI.NonPredSize++;
2202 unsigned ExtraPredCost =
TII->getPredicationCost(
I);
2203 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
2205 ToBBI.ExtraCost += NumCycles-1;
2206 ToBBI.ExtraCost2 += ExtraPredCost;
2211 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2223 std::vector<MachineBasicBlock *> Succs(FromMBB.succ_begin(),
2224 FromMBB.succ_end());
2226 MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB :
nullptr;
2228 for (MachineBasicBlock *Succ : Succs) {
2230 if (Succ == FallThrough)
2232 ToBBI.BB->addSuccessor(Succ);
2236 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2239 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2240 ToBBI.IsAnalyzed =
false;
2250void IfConverterImpl::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
2252 MachineBasicBlock &FromMBB = *FromBBI.BB;
2254 "Removing a BB whose address is taken!");
2259 for (MachineInstr &
MI : FromMBB)
2260 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
2261 for (MachineOperand &MO :
MI.operands())
2262 if (MO.isMBB() && !ToBBI.BB->isSuccessor(MO.getMBB()))
2269 ToBBI.BB->splice(ToTI, &FromMBB, FromMBB.begin(), FromTI);
2273 ToTI = ToBBI.BB->end();
2274 ToBBI.BB->splice(ToTI, &FromMBB, FromTI, FromMBB.end());
2280 if (ToBBI.IsBrAnalyzable)
2281 ToBBI.BB->normalizeSuccProbs();
2283 SmallVector<MachineBasicBlock *, 4> FromSuccs(FromMBB.successors());
2285 MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB :
nullptr;
2289 if (AddEdges && ToBBI.BB->isSuccessor(&FromMBB)) {
2293 ToBBI.BB->removeSuccessor(&FromMBB);
2296 for (MachineBasicBlock *Succ : FromSuccs) {
2298 if (Succ == FallThrough) {
2299 FromMBB.removeSuccessor(Succ);
2316 if (!To2FromProb.isZero())
2317 NewProb *= To2FromProb;
2320 FromMBB.removeSuccessor(Succ);
2345 if (ToBBI.BB->isSuccessor(Succ))
2346 ToBBI.BB->setSuccProbability(
2347 find(ToBBI.BB->successors(), Succ),
2350 ToBBI.BB->addSuccessor(Succ, NewProb);
2356 MachineBasicBlock *
Last = &*FromMBB.getParent()->rbegin();
2357 if (
Last != &FromMBB)
2358 FromMBB.moveAfter(
Last);
2362 if (ToBBI.IsBrAnalyzable && FromBBI.IsBrAnalyzable)
2363 ToBBI.BB->normalizeSuccProbs();
2365 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2366 FromBBI.Predicate.clear();
2368 ToBBI.NonPredSize += FromBBI.NonPredSize;
2369 ToBBI.ExtraCost += FromBBI.ExtraCost;
2370 ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
2371 FromBBI.NonPredSize = 0;
2372 FromBBI.ExtraCost = 0;
2373 FromBBI.ExtraCost2 = 0;
2375 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2376 ToBBI.HasFallThrough = FromBBI.HasFallThrough;
2377 ToBBI.IsAnalyzed =
false;
2378 FromBBI.IsAnalyzed =
false;
2383 return new IfConverterLegacy(std::move(Ftor));
2389 IfConverterImpl Impl;
2390 return Impl.runOnMachineFunction(
2393 return getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI();
2396 return &getAnalysis<MachineBranchProbabilityInfoWrapperPass>()
2399 [&]() {
return &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI(); },
2401 return PredicateFtor && !PredicateFtor(MF);
2407 IfConverterImpl Impl;
2408 bool Changed = Impl.runOnMachineFunction(
2417 .getCachedResult<ProfileSummaryAnalysis>(
2424 return PredicateFtor && !PredicateFtor(MF);
const TargetLowering & TLI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis false
static MachineBasicBlock * findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB)
findFalseBlock - BB has a fallthrough.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
static cl::opt< bool > DisableTriangle("disable-ifcvt-triangle", cl::init(false), cl::Hidden)
static MachineBasicBlock * findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB)
BB has a fallthrough. Find its 'false' successor given its 'true' successor.
static cl::opt< int > IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden)
static cl::opt< bool > IfCvtBranchFold("ifcvt-branch-fold", cl::init(true), cl::Hidden)
static cl::opt< bool > DisableTriangleF("disable-ifcvt-triangle-false", cl::init(false), cl::Hidden)
static cl::opt< int > IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden)
static void InsertUncondBranch(MachineBasicBlock &MBB, MachineBasicBlock &ToMBB, const TargetInstrInfo *TII)
Inserts an unconditional branch from MBB to ToMBB.
static void verifySameBranchInstructions(MachineBasicBlock *MBB1, MachineBasicBlock *MBB2)
static cl::opt< bool > DisableDiamond("disable-ifcvt-diamond", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableTriangleR("disable-ifcvt-triangle-rev", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableForkedDiamond("disable-ifcvt-forked-diamond", cl::init(false), cl::Hidden)
static MachineBasicBlock * getNextBlock(MachineBasicBlock &MBB)
Returns the next block in the function blocks ordering.
static bool MaySpeculate(const MachineInstr &MI, SmallSet< MCRegister, 4 > &LaterRedefs)
static void UpdatePredRedefs(MachineInstr &MI, LivePhysRegs &Redefs)
Behaves like LivePhysRegs::stepForward() but also adds implicit uses to all values defined in MI whic...
static cl::opt< bool > DisableSimpleF("disable-ifcvt-simple-false", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableSimple("disable-ifcvt-simple", cl::init(false), cl::Hidden)
static bool canFallThroughTo(MachineBasicBlock &MBB, MachineBasicBlock &ToMBB)
Returns true either if ToMBB is the next block after MBB or that all the intervening blocks are empty...
static cl::opt< int > IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden)
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
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)
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
This file defines the scope_exit class, which executes user-defined cleanup logic at scope exit.
This file defines the SmallSet class.
This file defines the SmallVector 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)
This file describes how to lower LLVM code to machine code.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, const TargetRegisterInfo *tri, MachineLoopInfo *mli=nullptr, bool AfterPlacement=false)
Perhaps branch folding, tail merging and other CFG optimizations on the given function.
static constexpr BranchProbability getOne()
static constexpr BranchProbability getZero()
BranchProbability getCompl() const
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
Module * getParent()
Get the module that this global value is contained inside of...
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 ClobbersPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred, bool SkipDead) const override
If the specified instruction defines any predicate or condition code register(s) used for predication...
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 isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, BranchProbability Probability) const override
Return true if it's profitable for if-converter to duplicate instructions of specified accumulated in...
bool SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
Returns true if the first specified predicate subsumes the second, e.g.
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.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
A set of physical registers with utility functions to track liveness when walking backward/forward th...
LLVM_ABI void stepForward(const MachineInstr &MI, SmallVectorImpl< std::pair< MCPhysReg, const MachineOperand * > > &Clobbers)
Simulates liveness when stepping forward over an instruction(bundle).
void init(const TargetRegisterInfo &TRI)
(re-)initializes and clears the set.
LLVM_ABI void addLiveInsNoPristines(const MachineBasicBlock &MBB)
Adds all live-in registers of basic block MBB but skips pristine registers.
unsigned pred_size() const
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the first non-debug instruction in the basic block, or end().
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator
pred_iterator pred_begin()
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool mayHaveInlineAsmBr() const
Returns true if this block may have an INLINEASM_BR (overestimate, by checking if any of the successo...
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_ABI BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) 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.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
void eraseAdditionalCallInfo(const MachineInstr *MI)
Following functions update call site info.
void copyAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New)
Copy the call site info from Old to \ New.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
MachineOperand class - Representation of each machine instruction operand.
bool tracksLiveness() const
tracksLiveness - Returns true when tracking register liveness accurately.
A set of analyses that are preserved following a run of a transformation pass.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
Wrapper class representing virtual and physical registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
SparseSet - Fast set implementation for objects that can be identified by small unsigned keys.
std::pair< iterator, bool > insert(const ValueT &Val)
insert - Attempts to insert a new element.
size_type count(const KeyT &Key) const
count - Returns 1 if this set contains an element identified by Key, 0 otherwise.
void setUniverse(unsigned U)
setUniverse - Set the universe size which determines the largest key the set can hold.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
TargetSubtargetInfo - Generic base class for all target subtargets.
An efficient, type-erasing, non-owning reference to a callable.
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
Pass manager infrastructure for declaring and invalidating analyses.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
LLVM_ABI FunctionPass * createIfConverterLegacyPass(std::function< bool(const MachineFunction &)> Ftor)
scope_exit(Callable) -> scope_exit< Callable >
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
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...
LLVM_ABI void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI char & IfConverterID
IfConverter - This pass performs machine code if conversion.
@ End
Run the machine verifier once, at the end of the pipeline.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.