57#define DEBUG_TYPE "if-converter"
80STATISTIC(NumSimple,
"Number of simple if-conversions performed");
81STATISTIC(NumSimpleFalse,
"Number of simple (F) if-conversions performed");
82STATISTIC(NumTriangle,
"Number of triangle if-conversions performed");
83STATISTIC(NumTriangleRev,
"Number of triangle (R) if-conversions performed");
84STATISTIC(NumTriangleFalse,
"Number of triangle (F) if-conversions performed");
85STATISTIC(NumTriangleFRev,
"Number of triangle (F/R) if-conversions performed");
86STATISTIC(NumDiamonds,
"Number of diamond if-conversions performed");
87STATISTIC(NumForkedDiamonds,
"Number of forked-diamond if-conversions performed");
88STATISTIC(NumIfConvBBs,
"Number of if-converted blocks");
90STATISTIC(NumUnpred,
"Number of true blocks of diamonds unpredicated");
140 bool IsBeingAnalyzed : 1;
143 bool IsBrAnalyzable : 1;
144 bool IsBrReversible : 1;
145 bool HasFallThrough : 1;
146 bool IsUnpredicable : 1;
147 bool CannotBeCopied : 1;
148 bool ClobbersPred : 1;
149 unsigned NonPredSize = 0;
150 unsigned ExtraCost = 0;
151 unsigned ExtraCost2 = 0;
158 BBInfo() : IsDone(
false), IsBeingAnalyzed(
false),
162 ClobbersPred(
false) {}
181 bool NeedSubsumption : 1;
182 bool TClobbersPred : 1;
183 bool FClobbersPred : 1;
185 IfcvtToken(BBInfo &b, IfcvtKind k,
bool s,
unsigned d,
unsigned d2 = 0,
186 bool tc =
false,
bool fc =
false)
187 : BBI(
b),
Kind(
k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
188 TClobbersPred(tc), FClobbersPred(fc) {}
193 std::vector<BBInfo> BBAnalysis;
204 bool PreRegAlloc =
true;
205 bool MadeChange =
false;
212 IfConverter(std::function<
bool(
const MachineFunction &)> Ftor =
nullptr)
231 bool reverseBranchCondition(BBInfo &BBI)
const;
232 bool ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
234 bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
235 bool FalseBranch,
unsigned &Dups,
237 bool CountDuplicatedInstructions(
240 unsigned &Dups1,
unsigned &Dups2,
242 bool SkipUnconditionalBranches)
const;
243 bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
244 unsigned &Dups1,
unsigned &Dups2,
245 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
246 bool ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
247 unsigned &Dups1,
unsigned &Dups2,
248 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
249 void AnalyzeBranches(BBInfo &BBI);
250 void ScanInstructions(BBInfo &BBI,
253 bool BranchUnpredicable =
false)
const;
254 bool RescanInstructions(
257 BBInfo &TrueBBI, BBInfo &FalseBBI)
const;
259 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
261 bool isTriangle =
false,
bool RevBranch =
false,
262 bool hasCommonTail =
false);
264 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
266 bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
267 bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
268 bool IfConvertDiamondCommon(BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
269 unsigned NumDups1,
unsigned NumDups2,
270 bool TClobbersPred,
bool FClobbersPred,
271 bool RemoveBranch,
bool MergeAddEdges);
272 bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
273 unsigned NumDups1,
unsigned NumDups2,
274 bool TClobbers,
bool FClobbers);
275 bool IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind Kind,
276 unsigned NumDups1,
unsigned NumDups2,
277 bool TClobbers,
bool FClobbers);
281 void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
283 bool IgnoreBr =
false);
284 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges =
true);
287 unsigned Cycle,
unsigned Extra,
293 bool MeetIfcvtSizeLimit(BBInfo &TBBInfo, BBInfo &FBBInfo,
303 unsigned Dups1 = 0, Dups2 = 0;
304 if (!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
305 *TBBInfo.BB, *FBBInfo.BB,
309 unsigned BranchBytes = 0;
310 unsigned CommonBytes = 0;
313 for (
auto &
I :
make_range(TBBInfo.BB->begin(), TIB)) {
315 CommonBytes +=
TII->getInstSizeInBytes(
I);
317 for (
auto &
I :
make_range(FBBInfo.BB->begin(), FIB)) {
319 CommonBytes +=
TII->getInstSizeInBytes(
I);
326 for (
auto &
I :
make_range(TIE, TBBInfo.BB->end())) {
327 if (
I.isBranch() && TBBInfo.IsBrAnalyzable && !Forked) {
329 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
332 CommonBytes +=
TII->getInstSizeInBytes(
I);
335 for (
auto &
I :
make_range(FIE, FBBInfo.BB->end())) {
336 if (
I.isBranch() && FBBInfo.IsBrAnalyzable && !Forked) {
338 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
341 CommonBytes +=
TII->getInstSizeInBytes(
I);
347 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
356 unsigned NumPredicatedInstructions = 0;
358 if (!
I.isDebugInstr()) {
360 NumPredicatedInstructions++;
364 if (!
I.isDebugInstr()) {
366 NumPredicatedInstructions++;
372 if (NumPredicatedInstructions > 15)
377 unsigned ExtraPredicateBytes =
TII->extraSizeToPredicateInstructions(
378 MF, NumPredicatedInstructions);
380 LLVM_DEBUG(
dbgs() <<
"MeetIfcvtSizeLimit(BranchBytes=" << BranchBytes
381 <<
", CommonBytes=" << CommonBytes
382 <<
", NumPredicatedInstructions="
383 << NumPredicatedInstructions
384 <<
", ExtraPredicateBytes=" << ExtraPredicateBytes
386 return (BranchBytes + CommonBytes) > ExtraPredicateBytes;
388 unsigned TCycle = TBBInfo.NonPredSize + TBBInfo.ExtraCost - Dups;
389 unsigned FCycle = FBBInfo.NonPredSize + FBBInfo.ExtraCost - Dups;
390 bool Res = TCycle > 0 && FCycle > 0 &&
392 *TBBInfo.BB, TCycle, TBBInfo.ExtraCost2, *FBBInfo.BB,
393 FCycle, FBBInfo.ExtraCost2, Prediction);
395 <<
", FCycle=" << FCycle
396 <<
", TExtra=" << TBBInfo.ExtraCost2 <<
", FExtra="
397 << FBBInfo.ExtraCost2 <<
") = " << Res <<
"\n");
403 bool blockAlwaysFallThrough(BBInfo &BBI)
const {
404 return BBI.IsBrAnalyzable && BBI.TrueBB ==
nullptr;
408 bool blockNeverFallThrough(BBInfo &BBI)
const {
410 if (BBI.IsBrAnalyzable)
411 return !BBI.HasFallThrough;
416 if (
I == BBI.BB->getParent()->end() || !PI->isSuccessor(&*
I))
423 static bool IfcvtTokenCmp(
const std::unique_ptr<IfcvtToken> &C1,
424 const std::unique_ptr<IfcvtToken> &C2) {
425 int Incr1 = (C1->Kind == ICDiamond)
426 ? -(
int)(C1->NumDups + C1->NumDups2) : (
int)C1->NumDups;
427 int Incr2 = (C2->Kind == ICDiamond)
428 ? -(
int)(C2->NumDups + C2->NumDups2) : (
int)C2->NumDups;
431 else if (Incr1 == Incr2) {
433 if (!C1->NeedSubsumption && C2->NeedSubsumption)
435 else if (C1->NeedSubsumption == C2->NeedSubsumption) {
437 if ((
unsigned)C1->Kind < (
unsigned)C2->Kind)
439 else if (C1->Kind == C2->Kind)
440 return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
449char IfConverter::ID = 0;
459 if (skipFunction(MF.getFunction()) || (PredicateFtor && !PredicateFtor(MF)))
463 TLI = ST.getTargetLowering();
464 TII = ST.getInstrInfo();
465 TRI = ST.getRegisterInfo();
467 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI());
468 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
470 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
471 MRI = &MF.getRegInfo();
472 SchedModel.
init(&ST);
474 if (!
TII)
return false;
476 PreRegAlloc =
MRI->isSSA();
478 bool BFChange =
false;
486 << MF.getName() <<
"\'");
495 BBAnalysis.resize(MF.getNumBlockIDs());
497 std::vector<std::unique_ptr<IfcvtToken>> Tokens;
499 unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
500 NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
505 AnalyzeBlocks(MF, Tokens);
506 while (!Tokens.empty()) {
507 std::unique_ptr<IfcvtToken> Token = std::move(Tokens.back());
509 BBInfo &BBI = Token->BBI;
510 IfcvtKind Kind = Token->Kind;
511 unsigned NumDups = Token->NumDups;
512 unsigned NumDups2 = Token->NumDups2;
517 BBI.IsEnqueued =
false;
521 BBI.IsEnqueued =
false;
527 case ICSimpleFalse: {
528 bool isFalse = Kind == ICSimpleFalse;
531 << (Kind == ICSimpleFalse ?
" false" :
"")
533 << ((Kind == ICSimpleFalse) ? BBI.FalseBB->getNumber()
534 : BBI.TrueBB->getNumber())
536 RetVal = IfConvertSimple(BBI, Kind);
537 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
539 if (isFalse) ++NumSimpleFalse;
546 case ICTriangleFalse:
547 case ICTriangleFRev: {
548 bool isFalse = Kind == ICTriangleFalse;
549 bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
559 <<
" (T:" << BBI.TrueBB->getNumber()
560 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
561 RetVal = IfConvertTriangle(BBI, Kind);
562 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
576 <<
" (T:" << BBI.TrueBB->getNumber()
577 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
578 RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,
579 Token->TClobbersPred,
580 Token->FClobbersPred);
581 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
582 if (RetVal) ++NumDiamonds;
584 case ICForkedDiamond:
588 <<
" (T:" << BBI.TrueBB->getNumber()
589 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
590 RetVal = IfConvertForkedDiamond(BBI, Kind, NumDups, NumDups2,
591 Token->TClobbersPred,
592 Token->FClobbersPred);
593 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
594 if (RetVal) ++NumForkedDiamonds;
598 if (RetVal &&
MRI->tracksLiveness())
603 NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
604 NumTriangleFalse + NumTriangleFRev + NumDiamonds;
611 MadeChange |= Change;
622 MadeChange |= BFChange;
630 if (SuccBB != TrueBB)
638bool IfConverter::reverseBranchCondition(BBInfo &BBI)
const {
662bool IfConverter::ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
665 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
668 if (TrueBBI.IsBrAnalyzable)
671 if (TrueBBI.BB->pred_size() > 1) {
672 if (TrueBBI.CannotBeCopied ||
676 Dups = TrueBBI.NonPredSize;
687bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
688 bool FalseBranch,
unsigned &Dups,
691 if (TrueBBI.BB == FalseBBI.BB)
694 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
697 if (TrueBBI.BB->pred_size() > 1) {
698 if (TrueBBI.CannotBeCopied)
701 unsigned Size = TrueBBI.NonPredSize;
702 if (TrueBBI.IsBrAnalyzable) {
703 if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
708 ? TrueBBI.TrueBB : TrueBBI.FalseBB;
720 if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
722 if (++
I == TrueBBI.BB->getParent()->end())
726 return TExit && TExit == FalseBBI.BB;
749bool IfConverter::CountDuplicatedInstructions(
754 unsigned &Dups1,
unsigned &Dups2,
756 bool SkipUnconditionalBranches)
const {
757 while (TIB != TIE && FIB != FIE) {
761 if (TIB == TIE || FIB == FIE)
763 if (!TIB->isIdenticalTo(*FIB))
767 std::vector<MachineOperand> PredDefs;
771 if (!TIB->isBranch())
778 if (TIB == TIE || FIB == FIE)
790 if (SkipUnconditionalBranches) {
791 while (RTIE != RTIB && RTIE->isUnconditionalBranch())
793 while (RFIE != RFIB && RFIE->isUnconditionalBranch())
799 while (RTIE != RTIB && RFIE != RFIB) {
804 if (RTIE == RTIB || RFIE == RFIB)
806 if (!RTIE->isIdenticalTo(*RFIE))
810 if (!RTIE->isBranch())
829bool IfConverter::RescanInstructions(
832 BBInfo &TrueBBI, BBInfo &FalseBBI)
const {
833 bool BranchUnpredicable =
true;
834 TrueBBI.IsUnpredicable = FalseBBI.IsUnpredicable =
false;
835 ScanInstructions(TrueBBI, TIB, TIE, BranchUnpredicable);
836 if (TrueBBI.IsUnpredicable)
838 ScanInstructions(FalseBBI, FIB, FIE, BranchUnpredicable);
839 if (FalseBBI.IsUnpredicable)
841 if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)
854 while (E1 != B1 && E2 != B2) {
857 if (E1 == B1 && E2 == B2)
861 assert(!E2->isBranch() &&
"Branch mis-match, one block is empty.");
865 assert(!E1->isBranch() &&
"Branch mis-match, one block is empty.");
869 if (E1->isBranch() || E2->isBranch())
870 assert(E1->isIdenticalTo(*E2) &&
871 "Branch mis-match, branch instructions don't match.");
893bool IfConverter::ValidForkedDiamond(
894 BBInfo &TrueBBI, BBInfo &FalseBBI,
895 unsigned &Dups1,
unsigned &Dups2,
896 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
898 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
899 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
902 if (!TrueBBI.IsBrAnalyzable || !FalseBBI.IsBrAnalyzable)
905 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
910 if (TrueBBI.BrCond.size() == 0 ||
911 FalseBBI.BrCond.size() == 0)
932 if (!((TT == FT && TF == FF) || (TF == FT && TT == FF)))
935 bool FalseReversed =
false;
936 if (TF == FT && TT == FF) {
938 if (!FalseBBI.IsBrReversible)
940 FalseReversed =
true;
941 reverseBranchCondition(FalseBBI);
945 reverseBranchCondition(FalseBBI);
953 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
954 *TrueBBI.BB, *FalseBBI.BB,
958 TrueBBICalc.BB = TrueBBI.BB;
959 FalseBBICalc.BB = FalseBBI.BB;
960 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
961 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
962 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
968 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
969 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
975bool IfConverter::ValidDiamond(
976 BBInfo &TrueBBI, BBInfo &FalseBBI,
977 unsigned &Dups1,
unsigned &Dups2,
978 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
980 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
981 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
986 if (TrueBBI.BB == FalseBBI.BB)
992 if (!TT && blockAlwaysFallThrough(TrueBBI))
994 if (!FT && blockAlwaysFallThrough(FalseBBI))
998 if (!TT && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
1000 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
1004 if (TrueBBI.FalseBB || FalseBBI.FalseBB)
1011 bool SkipUnconditionalBranches =
1012 TrueBBI.IsBrAnalyzable && FalseBBI.IsBrAnalyzable;
1017 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
1018 *TrueBBI.BB, *FalseBBI.BB,
1019 SkipUnconditionalBranches))
1022 TrueBBICalc.BB = TrueBBI.BB;
1023 FalseBBICalc.BB = FalseBBI.BB;
1024 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
1025 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
1026 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
1031 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
1032 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
1038void IfConverter::AnalyzeBranches(BBInfo &BBI) {
1042 BBI.TrueBB = BBI.FalseBB =
nullptr;
1044 BBI.IsBrAnalyzable =
1046 if (!BBI.IsBrAnalyzable) {
1047 BBI.TrueBB =
nullptr;
1048 BBI.FalseBB =
nullptr;
1053 BBI.IsBrReversible = (RevCond.size() == 0) ||
1055 BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB ==
nullptr;
1057 if (BBI.BrCond.size()) {
1064 BBI.IsUnpredicable =
true;
1074void IfConverter::ScanInstructions(BBInfo &BBI,
1077 bool BranchUnpredicable)
const {
1078 if (BBI.IsDone || BBI.IsUnpredicable)
1081 bool AlreadyPredicated = !BBI.Predicate.empty();
1083 BBI.NonPredSize = 0;
1086 BBI.ClobbersPred =
false;
1088 if (
MI.isDebugInstr())
1121 if (
MI.isNotDuplicable() ||
MI.isConvergent())
1122 BBI.CannotBeCopied =
true;
1125 bool isCondBr = BBI.IsBrAnalyzable &&
MI.isConditionalBranch();
1127 if (BranchUnpredicable &&
MI.isBranch()) {
1128 BBI.IsUnpredicable =
true;
1136 if (!isPredicated) {
1138 unsigned ExtraPredCost =
TII->getPredicationCost(
MI);
1139 unsigned NumCycles = SchedModel.computeInstrLatency(&
MI,
false);
1141 BBI.ExtraCost += NumCycles-1;
1142 BBI.ExtraCost2 += ExtraPredCost;
1143 }
else if (!AlreadyPredicated) {
1147 BBI.IsUnpredicable =
true;
1151 if (BBI.ClobbersPred && !isPredicated) {
1156 BBI.IsUnpredicable =
true;
1162 std::vector<MachineOperand> PredDefs;
1164 BBI.ClobbersPred =
true;
1167 BBI.IsUnpredicable =
true;
1182bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
1184 bool isTriangle,
bool RevBranch,
1185 bool hasCommonTail) {
1190 if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))
1196 if (BBI.Predicate.size() && !BBI.IsBrAnalyzable)
1204 if (!hasCommonTail && BBI.BrCond.size()) {
1225void IfConverter::AnalyzeBlock(
1232 bool SuccsAnalyzed =
false;
1238 while (!BBStack.empty()) {
1239 BBState &State = BBStack.back();
1241 BBInfo &BBI = BBAnalysis[BB->
getNumber()];
1243 if (!State.SuccsAnalyzed) {
1244 if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
1250 BBI.IsBeingAnalyzed =
true;
1252 AnalyzeBranches(BBI);
1255 ScanInstructions(BBI, Begin,
End);
1259 if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
1260 BBI.IsBeingAnalyzed =
false;
1261 BBI.IsAnalyzed =
true;
1267 if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
1268 BBI.IsBeingAnalyzed =
false;
1269 BBI.IsAnalyzed =
true;
1276 BBI.IsBeingAnalyzed =
false;
1277 BBI.IsAnalyzed =
true;
1283 State.SuccsAnalyzed =
true;
1284 BBStack.push_back(*BBI.FalseBB);
1285 BBStack.push_back(*BBI.TrueBB);
1289 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1290 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1292 if (TrueBBI.IsDone && FalseBBI.IsDone) {
1293 BBI.IsBeingAnalyzed =
false;
1294 BBI.IsAnalyzed =
true;
1300 RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1305 bool TNeedSub = !TrueBBI.Predicate.empty();
1306 bool FNeedSub = !FalseBBI.Predicate.empty();
1307 bool Enqueued =
false;
1312 BBInfo TrueBBICalc, FalseBBICalc;
1313 auto feasibleDiamond = [&](
bool Forked) {
1314 bool MeetsSize = MeetIfcvtSizeLimit(TrueBBICalc, FalseBBICalc, *BB,
1315 Dups + Dups2, Prediction, Forked);
1316 bool TrueFeasible = FeasibilityAnalysis(TrueBBI, BBI.BrCond,
1319 bool FalseFeasible = FeasibilityAnalysis(FalseBBI, RevCond,
1322 return MeetsSize && TrueFeasible && FalseFeasible;
1325 if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1326 TrueBBICalc, FalseBBICalc)) {
1327 if (feasibleDiamond(
false)) {
1336 Tokens.push_back(std::make_unique<IfcvtToken>(
1337 BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1338 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1341 }
else if (ValidForkedDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1342 TrueBBICalc, FalseBBICalc)) {
1343 if (feasibleDiamond(
true)) {
1354 Tokens.push_back(std::make_unique<IfcvtToken>(
1355 BBI, ICForkedDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1356 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1362 if (ValidTriangle(TrueBBI, FalseBBI,
false, Dups, Prediction) &&
1363 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1364 TrueBBI.ExtraCost2, Prediction) &&
1365 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true)) {
1374 std::make_unique<IfcvtToken>(BBI, ICTriangle, TNeedSub, Dups));
1378 if (ValidTriangle(TrueBBI, FalseBBI,
true, Dups, Prediction) &&
1379 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1380 TrueBBI.ExtraCost2, Prediction) &&
1381 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true,
true)) {
1383 std::make_unique<IfcvtToken>(BBI, ICTriangleRev, TNeedSub, Dups));
1387 if (ValidSimple(TrueBBI, Dups, Prediction) &&
1388 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1389 TrueBBI.ExtraCost2, Prediction) &&
1390 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
1399 std::make_unique<IfcvtToken>(BBI, ICSimple, TNeedSub, Dups));
1405 if (ValidTriangle(FalseBBI, TrueBBI,
false, Dups,
1407 MeetIfcvtSizeLimit(*FalseBBI.BB,
1408 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1409 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1410 FeasibilityAnalysis(FalseBBI, RevCond,
true)) {
1411 Tokens.push_back(std::make_unique<IfcvtToken>(BBI, ICTriangleFalse,
1416 if (ValidTriangle(FalseBBI, TrueBBI,
true, Dups,
1418 MeetIfcvtSizeLimit(*FalseBBI.BB,
1419 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1420 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1421 FeasibilityAnalysis(FalseBBI, RevCond,
true,
true)) {
1423 std::make_unique<IfcvtToken>(BBI, ICTriangleFRev, FNeedSub, Dups));
1427 if (ValidSimple(FalseBBI, Dups, Prediction.
getCompl()) &&
1428 MeetIfcvtSizeLimit(*FalseBBI.BB,
1429 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1430 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1431 FeasibilityAnalysis(FalseBBI, RevCond)) {
1433 std::make_unique<IfcvtToken>(BBI, ICSimpleFalse, FNeedSub, Dups));
1438 BBI.IsEnqueued = Enqueued;
1439 BBI.IsBeingAnalyzed =
false;
1440 BBI.IsAnalyzed =
true;
1446void IfConverter::AnalyzeBlocks(
1447 MachineFunction &MF, std::vector<std::unique_ptr<IfcvtToken>> &Tokens) {
1449 AnalyzeBlock(
MBB, Tokens);
1465 if (
I == E || !
I->empty() || !PI->isSuccessor(&*
I))
1470 return PI->isSuccessor(&*
I);
1477 BBInfo &PBBI = BBAnalysis[Predecessor->getNumber()];
1478 if (PBBI.IsDone || PBBI.BB == &
MBB)
1480 PBBI.IsAnalyzed =
false;
1481 PBBI.IsEnqueued =
false;
1503 for (
unsigned Reg : Redefs)
1504 LiveBeforeMI.
insert(Reg);
1510 for (
auto Clobber : Clobbers) {
1513 unsigned Reg = Clobber.first;
1517 if (
Op.isRegMask()) {
1520 if (LiveBeforeMI.
count(Reg))
1532 [&](
MCPhysReg S) { return LiveBeforeMI.count(S); }))
1538bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
1539 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1540 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1541 BBInfo *CvtBBI = &TrueBBI;
1542 BBInfo *NextBBI = &FalseBBI;
1545 if (Kind == ICSimpleFalse)
1550 if (CvtBBI->IsDone ||
1551 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1553 BBI.IsAnalyzed =
false;
1554 CvtBBI->IsAnalyzed =
false;
1562 if (Kind == ICSimpleFalse)
1568 if (
MRI->tracksLiveness()) {
1582 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond);
1585 BBI.BB->removeSuccessor(&CvtMBB,
true);
1588 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1592 MergeBlocks(BBI, *CvtBBI);
1595 bool IterIfcvt =
true;
1598 BBI.HasFallThrough =
false;
1615 InvalidatePreds(*BBI.BB);
1616 CvtBBI->IsDone =
true;
1623bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1624 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1625 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1626 BBInfo *CvtBBI = &TrueBBI;
1627 BBInfo *NextBBI = &FalseBBI;
1631 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1636 if (CvtBBI->IsDone ||
1637 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1639 BBI.IsAnalyzed =
false;
1640 CvtBBI->IsAnalyzed =
false;
1648 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1652 if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
1653 if (reverseBranchCondition(*CvtBBI)) {
1659 BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
1660 if (PBBI.IsEnqueued) {
1661 PBBI.IsAnalyzed =
false;
1662 PBBI.IsEnqueued =
false;
1671 if (
MRI->tracksLiveness()) {
1676 bool HasEarlyExit = CvtBBI->FalseBB !=
nullptr;
1694 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond,
true);
1698 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1701 MergeBlocks(BBI, *CvtBBI,
false);
1705 BBI.BB->removeSuccessor(&CvtMBB,
true);
1710 CvtBBI->BrCond.end());
1721 auto NewNext = BBNext + BBCvt * CvtNext;
1722 auto NewTrueBBIter =
find(BBI.BB->successors(), NewTrueBB);
1723 if (NewTrueBBIter != BBI.BB->succ_end())
1724 BBI.BB->setSuccProbability(NewTrueBBIter, NewNext);
1726 auto NewFalse = BBCvt * CvtFalse;
1728 BBI.BB->addSuccessor(CvtBBI->FalseBB, NewFalse);
1733 bool FalseBBDead =
false;
1734 bool IterIfcvt =
true;
1736 if (!isFallThrough) {
1740 if (!HasEarlyExit && NextMBB.
pred_size() == 1 &&
1742 MergeBlocks(BBI, *NextBBI);
1746 BBI.HasFallThrough =
false;
1756 InvalidatePreds(*BBI.BB);
1757 CvtBBI->IsDone =
true;
1759 NextBBI->IsDone =
true;
1776bool IfConverter::IfConvertDiamondCommon(
1777 BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
1778 unsigned NumDups1,
unsigned NumDups2,
1779 bool TClobbersPred,
bool FClobbersPred,
1780 bool RemoveBranch,
bool MergeAddEdges) {
1782 if (TrueBBI.IsDone || FalseBBI.IsDone ||
1783 TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) {
1785 BBI.IsAnalyzed =
false;
1786 TrueBBI.IsAnalyzed =
false;
1787 FalseBBI.IsAnalyzed =
false;
1791 if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
1798 BBInfo *BBI1 = &TrueBBI;
1799 BBInfo *BBI2 = &FalseBBI;
1807 bool DoSwap =
false;
1808 if (TClobbersPred && !FClobbersPred)
1810 else if (!TClobbersPred && !FClobbersPred) {
1811 if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
1813 }
else if (TClobbersPred && FClobbersPred)
1833 if (
MRI->tracksLiveness()) {
1842 BBI1->NonPredSize -= NumDups1;
1843 BBI2->NonPredSize -= NumDups1;
1848 for (
unsigned i = 0; i < NumDups1; ++DI1) {
1849 if (DI1 == MBB1.
end())
1851 if (!DI1->isDebugInstr())
1854 while (NumDups1 != 0) {
1857 if (DI2->shouldUpdateAdditionalCallInfo())
1861 if (DI2 == MBB2.
end())
1863 if (!DI2->isDebugInstr())
1867 if (
MRI->tracksLiveness()) {
1874 BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.
begin(), DI1);
1885 if (!BBI1->IsBrAnalyzable)
1891 while (DI1 != MBB1.
begin()) {
1893 if (!Prev->isBranch() && !Prev->isDebugInstr())
1897 for (
unsigned i = 0; i != NumDups2; ) {
1906 if (DI1->shouldUpdateAdditionalCallInfo())
1910 if (!DI1->isDebugInstr())
1915 DI2 = BBI2->BB->end();
1923 while (DI2 != MBB2.
begin()) {
1925 if (!Prev->isBranch() && !Prev->isDebugInstr())
1930 while (NumDups2 != 0) {
1936 if (!DI2->isDebugInstr())
1950 if (
TII->isProfitableToUnpredicate(MBB1, MBB2)) {
1952 if (FI.isDebugInstr())
1963 }
else if (!RedefsByFalse.
count(Reg)) {
1978 PredicateBlock(*BBI1, MBB1.
end(), *Cond1, &RedefsByFalse);
1987 if (!MBB2.
empty() && (DI2 == MBB2.
end())) {
1992 if (BB2NonPredicated && (BB1Predicated || !BBI2->IsBrAnalyzable))
1997 PredicateBlock(*BBI2, DI2, *Cond2);
2000 MergeBlocks(BBI, *BBI1, MergeAddEdges);
2001 MergeBlocks(BBI, *BBI2, MergeAddEdges);
2007bool IfConverter::IfConvertForkedDiamond(
2008 BBInfo &BBI, IfcvtKind Kind,
2009 unsigned NumDups1,
unsigned NumDups2,
2010 bool TClobbersPred,
bool FClobbersPred) {
2011 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2012 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2017 if (TIE != TrueBBI.BB->end())
2018 dl = TIE->getDebugLoc();
2022 if (!IfConvertDiamondCommon(
2023 BBI, TrueBBI, FalseBBI,
2025 TClobbersPred, FClobbersPred,
2032 TrueBBI.BrCond, dl);
2035 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2036 InvalidatePreds(*BBI.BB);
2043bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
2044 unsigned NumDups1,
unsigned NumDups2,
2045 bool TClobbersPred,
bool FClobbersPred) {
2046 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2047 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2052 if (blockAlwaysFallThrough(TrueBBI))
2053 TailBB = FalseBBI.TrueBB;
2054 assert((TailBB || !TrueBBI.IsBrAnalyzable) &&
"Unexpected!");
2057 if (!IfConvertDiamondCommon(
2058 BBI, TrueBBI, FalseBBI,
2060 TClobbersPred, FClobbersPred,
2061 TrueBBI.IsBrAnalyzable,
2072 BBI.BB->removeSuccessor(TrueBBI.BB);
2073 BBI.BB->removeSuccessor(FalseBBI.BB,
true);
2075 BBInfo &TailBBI = BBAnalysis[TailBB->
getNumber()];
2077 blockNeverFallThrough(TailBBI) && !TailBBI.BB->hasAddressTaken();
2083 CanMergeTail =
false;
2086 unsigned NumPreds = TailBB->
pred_size();
2088 CanMergeTail =
false;
2089 else if (NumPreds == 1 && CanMergeTail) {
2091 if (*PI != TrueBBI.BB && *PI != FalseBBI.BB)
2092 CanMergeTail =
false;
2095 MergeBlocks(BBI, TailBBI);
2096 TailBBI.IsDone =
true;
2100 BBI.HasFallThrough =
false;
2105 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2106 InvalidatePreds(*BBI.BB);
2114 bool SawStore =
true;
2115 if (!
MI.isSafeToMove(SawStore))
2124 if (MO.isDef() && !LaterRedefs.
count(Reg))
2136 bool AnyUnpred =
false;
2137 bool MaySpec = LaterRedefs !=
nullptr;
2153 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2163 BBI.Predicate.append(
Cond.begin(),
Cond.end());
2165 BBI.IsAnalyzed =
false;
2166 BBI.NonPredSize = 0;
2175void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
2183 if (IgnoreBr &&
I.isBranch())
2188 if (
I.isCandidateForAdditionalCallInfo())
2191 ToBBI.BB->insert(ToBBI.BB->end(),
MI);
2192 ToBBI.NonPredSize++;
2193 unsigned ExtraPredCost =
TII->getPredicationCost(
I);
2194 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
2196 ToBBI.ExtraCost += NumCycles-1;
2197 ToBBI.ExtraCost2 += ExtraPredCost;
2202 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2214 std::vector<MachineBasicBlock *> Succs(FromMBB.succ_begin(),
2215 FromMBB.succ_end());
2221 if (Succ == FallThrough)
2223 ToBBI.BB->addSuccessor(Succ);
2227 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2228 ToBBI.Predicate.append(
Cond.begin(),
Cond.end());
2230 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2231 ToBBI.IsAnalyzed =
false;
2241void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges) {
2244 "Removing a BB whose address is taken!");
2250 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
2252 if (MO.isMBB() && !ToBBI.BB->isSuccessor(MO.getMBB()))
2259 ToBBI.BB->splice(ToTI, &FromMBB, FromMBB.begin(), FromTI);
2263 ToTI = ToBBI.BB->end();
2264 ToBBI.BB->splice(ToTI, &FromMBB, FromTI, FromMBB.end());
2270 if (ToBBI.IsBrAnalyzable)
2271 ToBBI.BB->normalizeSuccProbs();
2279 if (AddEdges && ToBBI.BB->isSuccessor(&FromMBB)) {
2283 ToBBI.BB->removeSuccessor(&FromMBB);
2288 if (Succ == FallThrough) {
2289 FromMBB.removeSuccessor(Succ);
2306 if (!To2FromProb.isZero())
2307 NewProb *= To2FromProb;
2310 FromMBB.removeSuccessor(Succ);
2335 if (ToBBI.BB->isSuccessor(Succ))
2336 ToBBI.BB->setSuccProbability(
2337 find(ToBBI.BB->successors(), Succ),
2340 ToBBI.BB->addSuccessor(Succ, NewProb);
2347 if (
Last != &FromMBB)
2348 FromMBB.moveAfter(
Last);
2352 if (ToBBI.IsBrAnalyzable && FromBBI.IsBrAnalyzable)
2353 ToBBI.BB->normalizeSuccProbs();
2355 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2356 FromBBI.Predicate.clear();
2358 ToBBI.NonPredSize += FromBBI.NonPredSize;
2359 ToBBI.ExtraCost += FromBBI.ExtraCost;
2360 ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
2361 FromBBI.NonPredSize = 0;
2362 FromBBI.ExtraCost = 0;
2363 FromBBI.ExtraCost2 = 0;
2365 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2366 ToBBI.HasFallThrough = FromBBI.HasFallThrough;
2367 ToBBI.IsAnalyzed =
false;
2368 FromBBI.IsAnalyzed =
false;
2373 return new IfConverter(std::move(Ftor));
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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 LiveRegUnits::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
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
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.
Represent the analysis usage information of a pass.
AnalysisUsage & addRequired()
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 BranchProbability getOne()
BranchProbability getCompl() const
static BranchProbability getZero()
This class represents an Operation in the Expression.
FunctionPass class - This class is used to implement most global optimizations.
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
A possibly irreducible generalization of a Loop.
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 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 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.
A set of physical registers with utility functions to track liveness when walking backward/forward th...
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.
void addLiveInsNoPristines(const MachineBasicBlock &MBB)
Adds all live-in registers of basic block MBB but skips pristine registers.
Wrapper class representing physical registers. Should be passed by value.
unsigned pred_size() const
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()
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()
LLVM_ABI bool mayHaveInlineAsmBr() const
Returns true if this block may have an INLINEASM_BR (overestimate, by checking if any of the successo...
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
virtual MachineFunctionProperties getRequiredProperties() const
Properties which a MachineFunction may have at a given point in time.
Function & getFunction()
Return the LLVM function that this machine code represents.
void eraseAdditionalCallInfo(const MachineInstr *MI)
Following functions update call site info.
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
Create a new MachineInstr which is a copy of Orig, identical in all ways except the instruction has n...
void copyAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New)
Copy the call site info from Old to \ New.
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, 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.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
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.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
size_type count(const KeyT &Key) const
count - Returns 1 if this set contains an element identified by Key, 0 otherwise.
std::pair< iterator, bool > insert(const ValueT &Val)
insert - Attempts to insert a new element.
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.
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
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.
TargetSubtargetInfo - Generic base class for all target subtargets.
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
Reg
All possible values of the reg field in the ModR/M byte.
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.
LLVM_ABI FunctionPass * createIfConverter(std::function< bool(const MachineFunction &)> Ftor)
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
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.
void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
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.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
LLVM_ABI void initializeIfConverterPass(PassRegistry &)
Implement std::hash so that hash_code can be used in STL containers.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.