58#define DEBUG_TYPE "if-converter"
81STATISTIC(NumSimple,
"Number of simple if-conversions performed");
82STATISTIC(NumSimpleFalse,
"Number of simple (F) if-conversions performed");
83STATISTIC(NumTriangle,
"Number of triangle if-conversions performed");
84STATISTIC(NumTriangleRev,
"Number of triangle (R) if-conversions performed");
85STATISTIC(NumTriangleFalse,
"Number of triangle (F) if-conversions performed");
86STATISTIC(NumTriangleFRev,
"Number of triangle (F/R) if-conversions performed");
87STATISTIC(NumDiamonds,
"Number of diamond if-conversions performed");
88STATISTIC(NumForkedDiamonds,
"Number of forked-diamond if-conversions performed");
89STATISTIC(NumIfConvBBs,
"Number of if-converted blocks");
91STATISTIC(NumUnpred,
"Number of true blocks of diamonds unpredicated");
134 bool IsBeingAnalyzed : 1;
137 bool IsBrAnalyzable : 1;
138 bool IsBrReversible : 1;
139 bool HasFallThrough : 1;
140 bool IsUnpredicable : 1;
141 bool CannotBeCopied : 1;
142 bool ClobbersPred : 1;
143 unsigned NonPredSize = 0;
144 unsigned ExtraCost = 0;
145 unsigned ExtraCost2 = 0;
152 BBInfo() : IsDone(
false), IsBeingAnalyzed(
false),
156 ClobbersPred(
false) {}
175 bool NeedSubsumption : 1;
176 bool TClobbersPred : 1;
177 bool FClobbersPred : 1;
179 IfcvtToken(BBInfo &b, IfcvtKind k,
bool s,
unsigned d,
unsigned d2 = 0,
180 bool tc =
false,
bool fc =
false)
181 : BBI(
b),
Kind(
k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
182 TClobbersPred(tc), FClobbersPred(fc) {}
187 std::vector<BBInfo> BBAnalysis;
198 bool PreRegAlloc =
true;
199 bool MadeChange =
false;
206 IfConverter(std::function<
bool(
const MachineFunction &)> Ftor =
nullptr)
222 MachineFunctionProperties::Property::NoVRegs);
226 bool reverseBranchCondition(BBInfo &BBI)
const;
227 bool ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
229 bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
230 bool FalseBranch,
unsigned &Dups,
232 bool CountDuplicatedInstructions(
235 unsigned &Dups1,
unsigned &Dups2,
237 bool SkipUnconditionalBranches)
const;
238 bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
239 unsigned &Dups1,
unsigned &Dups2,
240 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
241 bool ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
242 unsigned &Dups1,
unsigned &Dups2,
243 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
244 void AnalyzeBranches(BBInfo &BBI);
245 void ScanInstructions(BBInfo &BBI,
248 bool BranchUnpredicable =
false)
const;
249 bool RescanInstructions(
252 BBInfo &TrueBBI, BBInfo &FalseBBI)
const;
254 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
256 bool isTriangle =
false,
bool RevBranch =
false,
257 bool hasCommonTail =
false);
259 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
261 bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
262 bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
263 bool IfConvertDiamondCommon(BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
264 unsigned NumDups1,
unsigned NumDups2,
265 bool TClobbersPred,
bool FClobbersPred,
266 bool RemoveBranch,
bool MergeAddEdges);
267 bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
268 unsigned NumDups1,
unsigned NumDups2,
269 bool TClobbers,
bool FClobbers);
270 bool IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind Kind,
271 unsigned NumDups1,
unsigned NumDups2,
272 bool TClobbers,
bool FClobbers);
273 void PredicateBlock(BBInfo &BBI,
277 void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
279 bool IgnoreBr =
false);
280 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges =
true);
283 unsigned Cycle,
unsigned Extra,
289 bool MeetIfcvtSizeLimit(BBInfo &TBBInfo, BBInfo &FBBInfo,
299 unsigned Dups1 = 0, Dups2 = 0;
300 if (!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
301 *TBBInfo.BB, *FBBInfo.BB,
305 unsigned BranchBytes = 0;
306 unsigned CommonBytes = 0;
309 for (
auto &
I :
make_range(TBBInfo.BB->begin(), TIB)) {
311 CommonBytes +=
TII->getInstSizeInBytes(
I);
313 for (
auto &
I :
make_range(FBBInfo.BB->begin(), FIB)) {
315 CommonBytes +=
TII->getInstSizeInBytes(
I);
322 for (
auto &
I :
make_range(TIE, TBBInfo.BB->end())) {
323 if (
I.isBranch() && TBBInfo.IsBrAnalyzable && !Forked) {
325 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
328 CommonBytes +=
TII->getInstSizeInBytes(
I);
331 for (
auto &
I :
make_range(FIE, FBBInfo.BB->end())) {
332 if (
I.isBranch() && FBBInfo.IsBrAnalyzable && !Forked) {
334 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
337 CommonBytes +=
TII->getInstSizeInBytes(
I);
343 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
352 unsigned NumPredicatedInstructions = 0;
354 if (!
I.isDebugInstr()) {
356 NumPredicatedInstructions++;
360 if (!
I.isDebugInstr()) {
362 NumPredicatedInstructions++;
368 if (NumPredicatedInstructions > 15)
373 unsigned ExtraPredicateBytes =
TII->extraSizeToPredicateInstructions(
374 MF, NumPredicatedInstructions);
376 LLVM_DEBUG(
dbgs() <<
"MeetIfcvtSizeLimit(BranchBytes=" << BranchBytes
377 <<
", CommonBytes=" << CommonBytes
378 <<
", NumPredicatedInstructions="
379 << NumPredicatedInstructions
380 <<
", ExtraPredicateBytes=" << ExtraPredicateBytes
382 return (BranchBytes + CommonBytes) > ExtraPredicateBytes;
384 unsigned TCycle = TBBInfo.NonPredSize + TBBInfo.ExtraCost - Dups;
385 unsigned FCycle = FBBInfo.NonPredSize + FBBInfo.ExtraCost - Dups;
386 bool Res = TCycle > 0 && FCycle > 0 &&
388 *TBBInfo.BB, TCycle, TBBInfo.ExtraCost2, *FBBInfo.BB,
389 FCycle, FBBInfo.ExtraCost2, Prediction);
391 <<
", FCycle=" << FCycle
392 <<
", TExtra=" << TBBInfo.ExtraCost2 <<
", FExtra="
393 << FBBInfo.ExtraCost2 <<
") = " << Res <<
"\n");
399 bool blockAlwaysFallThrough(BBInfo &BBI)
const {
400 return BBI.IsBrAnalyzable && BBI.TrueBB ==
nullptr;
404 static bool IfcvtTokenCmp(
const std::unique_ptr<IfcvtToken> &C1,
405 const std::unique_ptr<IfcvtToken> &C2) {
406 int Incr1 = (C1->Kind == ICDiamond)
407 ? -(
int)(C1->NumDups + C1->NumDups2) : (
int)C1->NumDups;
408 int Incr2 = (C2->Kind == ICDiamond)
409 ? -(
int)(C2->NumDups + C2->NumDups2) : (
int)C2->NumDups;
412 else if (Incr1 == Incr2) {
414 if (!C1->NeedSubsumption && C2->NeedSubsumption)
416 else if (C1->NeedSubsumption == C2->NeedSubsumption) {
418 if ((
unsigned)C1->Kind < (
unsigned)C2->Kind)
420 else if (C1->Kind == C2->Kind)
421 return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
430char IfConverter::ID = 0;
440 if (skipFunction(MF.getFunction()) || (PredicateFtor && !PredicateFtor(MF)))
444 TLI = ST.getTargetLowering();
445 TII = ST.getInstrInfo();
446 TRI = ST.getRegisterInfo();
448 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI());
449 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
451 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
452 MRI = &MF.getRegInfo();
453 SchedModel.
init(&ST);
455 if (!
TII)
return false;
457 PreRegAlloc =
MRI->isSSA();
459 bool BFChange =
false;
467 << MF.getName() <<
"\'");
476 BBAnalysis.resize(MF.getNumBlockIDs());
478 std::vector<std::unique_ptr<IfcvtToken>> Tokens;
480 unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
481 NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
486 AnalyzeBlocks(MF, Tokens);
487 while (!Tokens.empty()) {
488 std::unique_ptr<IfcvtToken> Token = std::move(Tokens.back());
490 BBInfo &BBI = Token->BBI;
491 IfcvtKind Kind = Token->Kind;
492 unsigned NumDups = Token->NumDups;
493 unsigned NumDups2 = Token->NumDups2;
498 BBI.IsEnqueued =
false;
502 BBI.IsEnqueued =
false;
508 case ICSimpleFalse: {
509 bool isFalse = Kind == ICSimpleFalse;
512 << (Kind == ICSimpleFalse ?
" false" :
"")
514 << ((Kind == ICSimpleFalse) ? BBI.FalseBB->getNumber()
515 : BBI.TrueBB->getNumber())
517 RetVal = IfConvertSimple(BBI, Kind);
518 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
520 if (isFalse) ++NumSimpleFalse;
527 case ICTriangleFalse:
528 case ICTriangleFRev: {
529 bool isFalse = Kind == ICTriangleFalse;
530 bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
540 <<
" (T:" << BBI.TrueBB->getNumber()
541 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
542 RetVal = IfConvertTriangle(BBI, Kind);
543 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
557 <<
" (T:" << BBI.TrueBB->getNumber()
558 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
559 RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,
560 Token->TClobbersPred,
561 Token->FClobbersPred);
562 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
563 if (RetVal) ++NumDiamonds;
565 case ICForkedDiamond:
569 <<
" (T:" << BBI.TrueBB->getNumber()
570 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
571 RetVal = IfConvertForkedDiamond(BBI, Kind, NumDups, NumDups2,
572 Token->TClobbersPred,
573 Token->FClobbersPred);
574 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
575 if (RetVal) ++NumForkedDiamonds;
579 if (RetVal &&
MRI->tracksLiveness())
584 NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
585 NumTriangleFalse + NumTriangleFRev + NumDiamonds;
592 MadeChange |= Change;
603 MadeChange |= BFChange;
611 if (SuccBB != TrueBB)
619bool IfConverter::reverseBranchCondition(BBInfo &BBI)
const {
643bool IfConverter::ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
646 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
649 if (TrueBBI.IsBrAnalyzable)
652 if (TrueBBI.BB->pred_size() > 1) {
653 if (TrueBBI.CannotBeCopied ||
657 Dups = TrueBBI.NonPredSize;
668bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
669 bool FalseBranch,
unsigned &Dups,
672 if (TrueBBI.BB == FalseBBI.BB)
675 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
678 if (TrueBBI.BB->pred_size() > 1) {
679 if (TrueBBI.CannotBeCopied)
682 unsigned Size = TrueBBI.NonPredSize;
683 if (TrueBBI.IsBrAnalyzable) {
684 if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
689 ? TrueBBI.TrueBB : TrueBBI.FalseBB;
701 if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
703 if (++
I == TrueBBI.BB->getParent()->end())
707 return TExit && TExit == FalseBBI.BB;
730bool IfConverter::CountDuplicatedInstructions(
735 unsigned &Dups1,
unsigned &Dups2,
737 bool SkipUnconditionalBranches)
const {
738 while (TIB != TIE && FIB != FIE) {
742 if (TIB == TIE || FIB == FIE)
744 if (!TIB->isIdenticalTo(*FIB))
748 std::vector<MachineOperand> PredDefs;
752 if (!TIB->isBranch())
759 if (TIB == TIE || FIB == FIE)
771 if (SkipUnconditionalBranches) {
772 while (RTIE != RTIB && RTIE->isUnconditionalBranch())
774 while (RFIE != RFIB && RFIE->isUnconditionalBranch())
780 while (RTIE != RTIB && RFIE != RFIB) {
785 if (RTIE == RTIB || RFIE == RFIB)
787 if (!RTIE->isIdenticalTo(*RFIE))
791 if (!RTIE->isBranch())
810bool IfConverter::RescanInstructions(
813 BBInfo &TrueBBI, BBInfo &FalseBBI)
const {
814 bool BranchUnpredicable =
true;
815 TrueBBI.IsUnpredicable = FalseBBI.IsUnpredicable =
false;
816 ScanInstructions(TrueBBI, TIB, TIE, BranchUnpredicable);
817 if (TrueBBI.IsUnpredicable)
819 ScanInstructions(FalseBBI, FIB, FIE, BranchUnpredicable);
820 if (FalseBBI.IsUnpredicable)
822 if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)
835 while (E1 != B1 && E2 != B2) {
838 if (E1 == B1 && E2 == B2)
842 assert(!E2->isBranch() &&
"Branch mis-match, one block is empty.");
846 assert(!E1->isBranch() &&
"Branch mis-match, one block is empty.");
850 if (E1->isBranch() || E2->isBranch())
851 assert(E1->isIdenticalTo(*E2) &&
852 "Branch mis-match, branch instructions don't match.");
874bool IfConverter::ValidForkedDiamond(
875 BBInfo &TrueBBI, BBInfo &FalseBBI,
876 unsigned &Dups1,
unsigned &Dups2,
877 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
879 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
880 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
883 if (!TrueBBI.IsBrAnalyzable || !FalseBBI.IsBrAnalyzable)
886 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
891 if (TrueBBI.BrCond.size() == 0 ||
892 FalseBBI.BrCond.size() == 0)
913 if (!((TT == FT && TF == FF) || (TF == FT && TT == FF)))
916 bool FalseReversed =
false;
917 if (TF == FT && TT == FF) {
919 if (!FalseBBI.IsBrReversible)
921 FalseReversed =
true;
922 reverseBranchCondition(FalseBBI);
926 reverseBranchCondition(FalseBBI);
934 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
935 *TrueBBI.BB, *FalseBBI.BB,
939 TrueBBICalc.BB = TrueBBI.BB;
940 FalseBBICalc.BB = FalseBBI.BB;
941 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
942 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
943 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
949 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
950 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
956bool IfConverter::ValidDiamond(
957 BBInfo &TrueBBI, BBInfo &FalseBBI,
958 unsigned &Dups1,
unsigned &Dups2,
959 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
961 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
962 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
967 if (TrueBBI.BB == FalseBBI.BB)
973 if (!TT && blockAlwaysFallThrough(TrueBBI))
975 if (!FT && blockAlwaysFallThrough(FalseBBI))
979 if (!TT && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
981 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
985 if (TrueBBI.FalseBB || FalseBBI.FalseBB)
992 bool SkipUnconditionalBranches =
993 TrueBBI.IsBrAnalyzable && FalseBBI.IsBrAnalyzable;
998 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
999 *TrueBBI.BB, *FalseBBI.BB,
1000 SkipUnconditionalBranches))
1003 TrueBBICalc.BB = TrueBBI.BB;
1004 FalseBBICalc.BB = FalseBBI.BB;
1005 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
1006 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
1007 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
1012 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
1013 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
1019void IfConverter::AnalyzeBranches(BBInfo &BBI) {
1023 BBI.TrueBB = BBI.FalseBB =
nullptr;
1025 BBI.IsBrAnalyzable =
1027 if (!BBI.IsBrAnalyzable) {
1028 BBI.TrueBB =
nullptr;
1029 BBI.FalseBB =
nullptr;
1034 BBI.IsBrReversible = (RevCond.size() == 0) ||
1036 BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB ==
nullptr;
1038 if (BBI.BrCond.size()) {
1045 BBI.IsUnpredicable =
true;
1055void IfConverter::ScanInstructions(BBInfo &BBI,
1058 bool BranchUnpredicable)
const {
1059 if (BBI.IsDone || BBI.IsUnpredicable)
1062 bool AlreadyPredicated = !BBI.Predicate.empty();
1064 BBI.NonPredSize = 0;
1067 BBI.ClobbersPred =
false;
1069 if (
MI.isDebugInstr())
1102 if (
MI.isNotDuplicable() ||
MI.isConvergent())
1103 BBI.CannotBeCopied =
true;
1106 bool isCondBr = BBI.IsBrAnalyzable &&
MI.isConditionalBranch();
1108 if (BranchUnpredicable &&
MI.isBranch()) {
1109 BBI.IsUnpredicable =
true;
1117 if (!isPredicated) {
1119 unsigned ExtraPredCost =
TII->getPredicationCost(
MI);
1120 unsigned NumCycles = SchedModel.computeInstrLatency(&
MI,
false);
1122 BBI.ExtraCost += NumCycles-1;
1123 BBI.ExtraCost2 += ExtraPredCost;
1124 }
else if (!AlreadyPredicated) {
1128 BBI.IsUnpredicable =
true;
1132 if (BBI.ClobbersPred && !isPredicated) {
1137 BBI.IsUnpredicable =
true;
1143 std::vector<MachineOperand> PredDefs;
1145 BBI.ClobbersPred =
true;
1148 BBI.IsUnpredicable =
true;
1163bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
1165 bool isTriangle,
bool RevBranch,
1166 bool hasCommonTail) {
1171 if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))
1177 if (BBI.Predicate.size() && !BBI.IsBrAnalyzable)
1185 if (!hasCommonTail && BBI.BrCond.size()) {
1206void IfConverter::AnalyzeBlock(
1213 bool SuccsAnalyzed =
false;
1219 while (!BBStack.empty()) {
1220 BBState &State = BBStack.back();
1222 BBInfo &BBI = BBAnalysis[BB->
getNumber()];
1224 if (!State.SuccsAnalyzed) {
1225 if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
1231 BBI.IsBeingAnalyzed =
true;
1233 AnalyzeBranches(BBI);
1236 ScanInstructions(BBI, Begin,
End);
1240 if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
1241 BBI.IsBeingAnalyzed =
false;
1242 BBI.IsAnalyzed =
true;
1248 if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
1249 BBI.IsBeingAnalyzed =
false;
1250 BBI.IsAnalyzed =
true;
1257 BBI.IsBeingAnalyzed =
false;
1258 BBI.IsAnalyzed =
true;
1264 State.SuccsAnalyzed =
true;
1265 BBStack.push_back(*BBI.FalseBB);
1266 BBStack.push_back(*BBI.TrueBB);
1270 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1271 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1273 if (TrueBBI.IsDone && FalseBBI.IsDone) {
1274 BBI.IsBeingAnalyzed =
false;
1275 BBI.IsAnalyzed =
true;
1281 RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1286 bool TNeedSub = !TrueBBI.Predicate.empty();
1287 bool FNeedSub = !FalseBBI.Predicate.empty();
1288 bool Enqueued =
false;
1293 BBInfo TrueBBICalc, FalseBBICalc;
1294 auto feasibleDiamond = [&](
bool Forked) {
1295 bool MeetsSize = MeetIfcvtSizeLimit(TrueBBICalc, FalseBBICalc, *BB,
1296 Dups + Dups2, Prediction, Forked);
1297 bool TrueFeasible = FeasibilityAnalysis(TrueBBI, BBI.BrCond,
1300 bool FalseFeasible = FeasibilityAnalysis(FalseBBI, RevCond,
1303 return MeetsSize && TrueFeasible && FalseFeasible;
1306 if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1307 TrueBBICalc, FalseBBICalc)) {
1308 if (feasibleDiamond(
false)) {
1317 Tokens.push_back(std::make_unique<IfcvtToken>(
1318 BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1319 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1322 }
else if (ValidForkedDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1323 TrueBBICalc, FalseBBICalc)) {
1324 if (feasibleDiamond(
true)) {
1335 Tokens.push_back(std::make_unique<IfcvtToken>(
1336 BBI, ICForkedDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1337 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1343 if (ValidTriangle(TrueBBI, FalseBBI,
false, Dups, Prediction) &&
1344 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1345 TrueBBI.ExtraCost2, Prediction) &&
1346 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true)) {
1355 std::make_unique<IfcvtToken>(BBI, ICTriangle, TNeedSub, Dups));
1359 if (ValidTriangle(TrueBBI, FalseBBI,
true, Dups, Prediction) &&
1360 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1361 TrueBBI.ExtraCost2, Prediction) &&
1362 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true,
true)) {
1364 std::make_unique<IfcvtToken>(BBI, ICTriangleRev, TNeedSub, Dups));
1368 if (ValidSimple(TrueBBI, Dups, Prediction) &&
1369 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1370 TrueBBI.ExtraCost2, Prediction) &&
1371 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
1380 std::make_unique<IfcvtToken>(BBI, ICSimple, TNeedSub, Dups));
1386 if (ValidTriangle(FalseBBI, TrueBBI,
false, Dups,
1388 MeetIfcvtSizeLimit(*FalseBBI.BB,
1389 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1390 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1391 FeasibilityAnalysis(FalseBBI, RevCond,
true)) {
1392 Tokens.push_back(std::make_unique<IfcvtToken>(BBI, ICTriangleFalse,
1397 if (ValidTriangle(FalseBBI, TrueBBI,
true, Dups,
1399 MeetIfcvtSizeLimit(*FalseBBI.BB,
1400 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1401 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1402 FeasibilityAnalysis(FalseBBI, RevCond,
true,
true)) {
1404 std::make_unique<IfcvtToken>(BBI, ICTriangleFRev, FNeedSub, Dups));
1408 if (ValidSimple(FalseBBI, Dups, Prediction.
getCompl()) &&
1409 MeetIfcvtSizeLimit(*FalseBBI.BB,
1410 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1411 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1412 FeasibilityAnalysis(FalseBBI, RevCond)) {
1414 std::make_unique<IfcvtToken>(BBI, ICSimpleFalse, FNeedSub, Dups));
1419 BBI.IsEnqueued = Enqueued;
1420 BBI.IsBeingAnalyzed =
false;
1421 BBI.IsAnalyzed =
true;
1427void IfConverter::AnalyzeBlocks(
1428 MachineFunction &MF, std::vector<std::unique_ptr<IfcvtToken>> &Tokens) {
1430 AnalyzeBlock(
MBB, Tokens);
1446 if (
I == E || !
I->empty() || !PI->isSuccessor(&*
I))
1451 return PI->isSuccessor(&*
I);
1458 BBInfo &PBBI = BBAnalysis[Predecessor->getNumber()];
1459 if (PBBI.IsDone || PBBI.BB == &
MBB)
1461 PBBI.IsAnalyzed =
false;
1462 PBBI.IsEnqueued =
false;
1484 for (
unsigned Reg : Redefs)
1485 LiveBeforeMI.
insert(Reg);
1491 for (
auto Clobber : Clobbers) {
1494 unsigned Reg = Clobber.first;
1498 if (
Op.isRegMask()) {
1501 if (LiveBeforeMI.
count(Reg))
1513 [&](
MCPhysReg S) { return LiveBeforeMI.count(S); }))
1519bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
1520 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1521 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1522 BBInfo *CvtBBI = &TrueBBI;
1523 BBInfo *NextBBI = &FalseBBI;
1526 if (Kind == ICSimpleFalse)
1531 if (CvtBBI->IsDone ||
1532 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1534 BBI.IsAnalyzed =
false;
1535 CvtBBI->IsAnalyzed =
false;
1543 if (Kind == ICSimpleFalse)
1549 if (
MRI->tracksLiveness()) {
1563 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond);
1566 BBI.BB->removeSuccessor(&CvtMBB,
true);
1569 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1573 MergeBlocks(BBI, *CvtBBI);
1576 bool IterIfcvt =
true;
1579 BBI.HasFallThrough =
false;
1596 InvalidatePreds(*BBI.BB);
1597 CvtBBI->IsDone =
true;
1604bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1605 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1606 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1607 BBInfo *CvtBBI = &TrueBBI;
1608 BBInfo *NextBBI = &FalseBBI;
1612 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1617 if (CvtBBI->IsDone ||
1618 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1620 BBI.IsAnalyzed =
false;
1621 CvtBBI->IsAnalyzed =
false;
1629 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1633 if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
1634 if (reverseBranchCondition(*CvtBBI)) {
1640 BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
1641 if (PBBI.IsEnqueued) {
1642 PBBI.IsAnalyzed =
false;
1643 PBBI.IsEnqueued =
false;
1652 if (
MRI->tracksLiveness()) {
1657 bool HasEarlyExit = CvtBBI->FalseBB !=
nullptr;
1675 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond,
true);
1679 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1682 MergeBlocks(BBI, *CvtBBI,
false);
1686 BBI.BB->removeSuccessor(&CvtMBB,
true);
1691 CvtBBI->BrCond.end());
1702 auto NewNext = BBNext + BBCvt * CvtNext;
1703 auto NewTrueBBIter =
find(BBI.BB->successors(), NewTrueBB);
1704 if (NewTrueBBIter != BBI.BB->succ_end())
1705 BBI.BB->setSuccProbability(NewTrueBBIter, NewNext);
1707 auto NewFalse = BBCvt * CvtFalse;
1709 BBI.BB->addSuccessor(CvtBBI->FalseBB, NewFalse);
1714 bool FalseBBDead =
false;
1715 bool IterIfcvt =
true;
1717 if (!isFallThrough) {
1721 if (!HasEarlyExit &&
1722 NextMBB.
pred_size() == 1 && !NextBBI->HasFallThrough &&
1724 MergeBlocks(BBI, *NextBBI);
1728 BBI.HasFallThrough =
false;
1738 InvalidatePreds(*BBI.BB);
1739 CvtBBI->IsDone =
true;
1741 NextBBI->IsDone =
true;
1758bool IfConverter::IfConvertDiamondCommon(
1759 BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
1760 unsigned NumDups1,
unsigned NumDups2,
1761 bool TClobbersPred,
bool FClobbersPred,
1762 bool RemoveBranch,
bool MergeAddEdges) {
1764 if (TrueBBI.IsDone || FalseBBI.IsDone ||
1765 TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) {
1767 BBI.IsAnalyzed =
false;
1768 TrueBBI.IsAnalyzed =
false;
1769 FalseBBI.IsAnalyzed =
false;
1773 if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
1780 BBInfo *BBI1 = &TrueBBI;
1781 BBInfo *BBI2 = &FalseBBI;
1789 bool DoSwap =
false;
1790 if (TClobbersPred && !FClobbersPred)
1792 else if (!TClobbersPred && !FClobbersPred) {
1793 if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
1795 }
else if (TClobbersPred && FClobbersPred)
1815 if (
MRI->tracksLiveness()) {
1824 BBI1->NonPredSize -= NumDups1;
1825 BBI2->NonPredSize -= NumDups1;
1830 for (
unsigned i = 0; i < NumDups1; ++DI1) {
1831 if (DI1 == MBB1.
end())
1833 if (!DI1->isDebugInstr())
1836 while (NumDups1 != 0) {
1839 if (DI2->shouldUpdateCallSiteInfo())
1843 if (DI2 == MBB2.
end())
1845 if (!DI2->isDebugInstr())
1849 if (
MRI->tracksLiveness()) {
1856 BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.
begin(), DI1);
1867 if (!BBI1->IsBrAnalyzable)
1873 while (DI1 != MBB1.
begin()) {
1875 if (!Prev->isBranch() && !Prev->isDebugInstr())
1879 for (
unsigned i = 0; i != NumDups2; ) {
1888 if (DI1->shouldUpdateCallSiteInfo())
1892 if (!DI1->isDebugInstr())
1897 DI2 = BBI2->BB->end();
1905 while (DI2 != MBB2.
begin()) {
1907 if (!Prev->isBranch() && !Prev->isDebugInstr())
1912 while (NumDups2 != 0) {
1918 if (!DI2->isDebugInstr())
1932 if (
TII->isProfitableToUnpredicate(MBB1, MBB2)) {
1934 if (FI.isDebugInstr())
1945 }
else if (!RedefsByFalse.
count(Reg)) {
1954 if (!ExtUses.
count(Reg)) {
1963 PredicateBlock(*BBI1, MBB1.
end(), *Cond1, &RedefsByFalse);
1972 if (!MBB2.
empty() && (DI2 == MBB2.
end())) {
1977 if (BB2NonPredicated && (BB1Predicated || !BBI2->IsBrAnalyzable))
1982 PredicateBlock(*BBI2, DI2, *Cond2);
1985 MergeBlocks(BBI, *BBI1, MergeAddEdges);
1986 MergeBlocks(BBI, *BBI2, MergeAddEdges);
1992bool IfConverter::IfConvertForkedDiamond(
1993 BBInfo &BBI, IfcvtKind Kind,
1994 unsigned NumDups1,
unsigned NumDups2,
1995 bool TClobbersPred,
bool FClobbersPred) {
1996 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1997 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2002 if (TIE != TrueBBI.BB->end())
2003 dl = TIE->getDebugLoc();
2007 if (!IfConvertDiamondCommon(
2008 BBI, TrueBBI, FalseBBI,
2010 TClobbersPred, FClobbersPred,
2017 TrueBBI.BrCond, dl);
2020 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2021 InvalidatePreds(*BBI.BB);
2028bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
2029 unsigned NumDups1,
unsigned NumDups2,
2030 bool TClobbersPred,
bool FClobbersPred) {
2031 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2032 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2037 if (blockAlwaysFallThrough(TrueBBI))
2038 TailBB = FalseBBI.TrueBB;
2039 assert((TailBB || !TrueBBI.IsBrAnalyzable) &&
"Unexpected!");
2042 if (!IfConvertDiamondCommon(
2043 BBI, TrueBBI, FalseBBI,
2045 TClobbersPred, FClobbersPred,
2046 TrueBBI.IsBrAnalyzable,
2057 BBI.BB->removeSuccessor(TrueBBI.BB);
2058 BBI.BB->removeSuccessor(FalseBBI.BB,
true);
2060 BBInfo &TailBBI = BBAnalysis[TailBB->
getNumber()];
2061 bool CanMergeTail = !TailBBI.HasFallThrough &&
2062 !TailBBI.BB->hasAddressTaken();
2068 CanMergeTail =
false;
2071 unsigned NumPreds = TailBB->
pred_size();
2073 CanMergeTail =
false;
2074 else if (NumPreds == 1 && CanMergeTail) {
2076 if (*PI != TrueBBI.BB && *PI != FalseBBI.BB)
2077 CanMergeTail =
false;
2080 MergeBlocks(BBI, TailBBI);
2081 TailBBI.IsDone =
true;
2085 BBI.HasFallThrough =
false;
2090 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2091 InvalidatePreds(*BBI.BB);
2099 bool SawStore =
true;
2100 if (!
MI.isSafeToMove(SawStore))
2109 if (MO.isDef() && !LaterRedefs.
count(Reg))
2118void IfConverter::PredicateBlock(BBInfo &BBI,
2122 bool AnyUnpred =
false;
2123 bool MaySpec = LaterRedefs !=
nullptr;
2139 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2149 BBI.Predicate.append(
Cond.begin(),
Cond.end());
2151 BBI.IsAnalyzed =
false;
2152 BBI.NonPredSize = 0;
2161void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
2169 if (IgnoreBr &&
I.isBranch())
2174 if (
I.isCandidateForCallSiteEntry())
2177 ToBBI.BB->insert(ToBBI.BB->end(),
MI);
2178 ToBBI.NonPredSize++;
2179 unsigned ExtraPredCost =
TII->getPredicationCost(
I);
2180 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
2182 ToBBI.ExtraCost += NumCycles-1;
2183 ToBBI.ExtraCost2 += ExtraPredCost;
2188 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2200 std::vector<MachineBasicBlock *> Succs(FromMBB.succ_begin(),
2201 FromMBB.succ_end());
2207 if (Succ == FallThrough)
2209 ToBBI.BB->addSuccessor(Succ);
2213 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2214 ToBBI.Predicate.append(
Cond.begin(),
Cond.end());
2216 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2217 ToBBI.IsAnalyzed =
false;
2227void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges) {
2230 "Removing a BB whose address is taken!");
2236 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
2238 if (MO.isMBB() && !ToBBI.BB->isSuccessor(MO.getMBB()))
2245 ToBBI.BB->splice(ToTI, &FromMBB, FromMBB.begin(), FromTI);
2249 ToTI = ToBBI.BB->end();
2250 ToBBI.BB->splice(ToTI, &FromMBB, FromTI, FromMBB.end());
2256 if (ToBBI.IsBrAnalyzable)
2257 ToBBI.BB->normalizeSuccProbs();
2265 if (AddEdges && ToBBI.BB->isSuccessor(&FromMBB)) {
2269 ToBBI.BB->removeSuccessor(&FromMBB);
2274 if (Succ == FallThrough) {
2275 FromMBB.removeSuccessor(Succ);
2292 if (!To2FromProb.isZero())
2293 NewProb *= To2FromProb;
2296 FromMBB.removeSuccessor(Succ);
2321 if (ToBBI.BB->isSuccessor(Succ))
2322 ToBBI.BB->setSuccProbability(
2323 find(ToBBI.BB->successors(), Succ),
2326 ToBBI.BB->addSuccessor(Succ, NewProb);
2333 if (
Last != &FromMBB)
2334 FromMBB.moveAfter(
Last);
2338 if (ToBBI.IsBrAnalyzable && FromBBI.IsBrAnalyzable)
2339 ToBBI.BB->normalizeSuccProbs();
2341 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2342 FromBBI.Predicate.clear();
2344 ToBBI.NonPredSize += FromBBI.NonPredSize;
2345 ToBBI.ExtraCost += FromBBI.ExtraCost;
2346 ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
2347 FromBBI.NonPredSize = 0;
2348 FromBBI.ExtraCost = 0;
2349 FromBBI.ExtraCost2 = 0;
2351 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2352 ToBBI.HasFallThrough = FromBBI.HasFallThrough;
2353 ToBBI.IsAnalyzed =
false;
2354 FromBBI.IsAnalyzed =
false;
2359 return new IfConverter(std::move(Ftor));
unsigned const MachineRegisterInfo * MRI
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 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)
static bool MaySpeculate(const MachineInstr &MI, SmallSet< MCPhysReg, 4 > &LaterRedefs)
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
unsigned 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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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.
unsigned pred_size() const
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the first non-debug instruction in the basic block, or end().
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.
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()
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.
MachineFunctionProperties & set(Property P)
void copyCallSiteInfo(const MachineInstr *Old, const MachineInstr *New)
Copy the call site info from Old to \ New.
Function & getFunction()
Return the LLVM function that this machine code represents.
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 eraseCallSiteInfo(const MachineInstr *MI)
Following functions update call site info.
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.
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 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.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
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.
void init(const TargetSubtargetInfo *TSInfo)
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.
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
@ 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.
FunctionPass * createIfConverter(std::function< bool(const MachineFunction &)> Ftor)
detail::scope_exit< std::decay_t< Callable > > make_scope_exit(Callable &&F)
void initializeIfConverterPass(PassRegistry &)
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.
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.
char & IfConverterID
IfConverter - This pass performs machine code if conversion.
Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
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.