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");
133 bool IsBeingAnalyzed : 1;
136 bool IsBrAnalyzable : 1;
137 bool IsBrReversible : 1;
138 bool HasFallThrough : 1;
139 bool IsUnpredicable : 1;
140 bool CannotBeCopied : 1;
141 bool ClobbersPred : 1;
142 unsigned NonPredSize = 0;
143 unsigned ExtraCost = 0;
144 unsigned ExtraCost2 = 0;
151 BBInfo() : IsDone(
false), IsBeingAnalyzed(
false),
155 ClobbersPred(
false) {}
174 bool NeedSubsumption : 1;
175 bool TClobbersPred : 1;
176 bool FClobbersPred : 1;
178 IfcvtToken(BBInfo &b, IfcvtKind k,
bool s,
unsigned d,
unsigned d2 = 0,
179 bool tc =
false,
bool fc =
false)
180 : BBI(
b),
Kind(
k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
181 TClobbersPred(tc), FClobbersPred(fc) {}
186 std::vector<BBInfo> BBAnalysis;
197 bool PreRegAlloc =
true;
198 bool MadeChange =
false;
205 IfConverter(std::function<
bool(
const MachineFunction &)> Ftor =
nullptr)
221 MachineFunctionProperties::Property::NoVRegs);
225 bool reverseBranchCondition(BBInfo &BBI)
const;
226 bool ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
228 bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
229 bool FalseBranch,
unsigned &Dups,
231 bool CountDuplicatedInstructions(
234 unsigned &Dups1,
unsigned &Dups2,
236 bool SkipUnconditionalBranches)
const;
237 bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
238 unsigned &Dups1,
unsigned &Dups2,
239 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
240 bool ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
241 unsigned &Dups1,
unsigned &Dups2,
242 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
243 void AnalyzeBranches(BBInfo &BBI);
244 void ScanInstructions(BBInfo &BBI,
247 bool BranchUnpredicable =
false)
const;
248 bool RescanInstructions(
251 BBInfo &TrueBBI, BBInfo &FalseBBI)
const;
253 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
255 bool isTriangle =
false,
bool RevBranch =
false,
256 bool hasCommonTail =
false);
258 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
260 bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
261 bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
262 bool IfConvertDiamondCommon(BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
263 unsigned NumDups1,
unsigned NumDups2,
264 bool TClobbersPred,
bool FClobbersPred,
265 bool RemoveBranch,
bool MergeAddEdges);
266 bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
267 unsigned NumDups1,
unsigned NumDups2,
268 bool TClobbers,
bool FClobbers);
269 bool IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind Kind,
270 unsigned NumDups1,
unsigned NumDups2,
271 bool TClobbers,
bool FClobbers);
272 void PredicateBlock(BBInfo &BBI,
276 void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
278 bool IgnoreBr =
false);
279 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges =
true);
282 unsigned Cycle,
unsigned Extra,
288 bool MeetIfcvtSizeLimit(BBInfo &TBBInfo, BBInfo &FBBInfo,
298 unsigned Dups1 = 0, Dups2 = 0;
299 if (!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
300 *TBBInfo.BB, *FBBInfo.BB,
304 unsigned BranchBytes = 0;
305 unsigned CommonBytes = 0;
308 for (
auto &
I :
make_range(TBBInfo.BB->begin(), TIB)) {
310 CommonBytes +=
TII->getInstSizeInBytes(
I);
312 for (
auto &
I :
make_range(FBBInfo.BB->begin(), FIB)) {
314 CommonBytes +=
TII->getInstSizeInBytes(
I);
321 for (
auto &
I :
make_range(TIE, TBBInfo.BB->end())) {
322 if (
I.isBranch() && TBBInfo.IsBrAnalyzable && !Forked) {
324 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
327 CommonBytes +=
TII->getInstSizeInBytes(
I);
330 for (
auto &
I :
make_range(FIE, FBBInfo.BB->end())) {
331 if (
I.isBranch() && FBBInfo.IsBrAnalyzable && !Forked) {
333 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
336 CommonBytes +=
TII->getInstSizeInBytes(
I);
342 BranchBytes +=
TII->predictBranchSizeForIfCvt(
I);
351 unsigned NumPredicatedInstructions = 0;
353 if (!
I.isDebugInstr()) {
355 NumPredicatedInstructions++;
359 if (!
I.isDebugInstr()) {
361 NumPredicatedInstructions++;
367 if (NumPredicatedInstructions > 15)
372 unsigned ExtraPredicateBytes =
TII->extraSizeToPredicateInstructions(
373 MF, NumPredicatedInstructions);
375 LLVM_DEBUG(
dbgs() <<
"MeetIfcvtSizeLimit(BranchBytes=" << BranchBytes
376 <<
", CommonBytes=" << CommonBytes
377 <<
", NumPredicatedInstructions="
378 << NumPredicatedInstructions
379 <<
", ExtraPredicateBytes=" << ExtraPredicateBytes
381 return (BranchBytes + CommonBytes) > ExtraPredicateBytes;
383 unsigned TCycle = TBBInfo.NonPredSize + TBBInfo.ExtraCost - Dups;
384 unsigned FCycle = FBBInfo.NonPredSize + FBBInfo.ExtraCost - Dups;
385 bool Res = TCycle > 0 && FCycle > 0 &&
387 *TBBInfo.BB, TCycle, TBBInfo.ExtraCost2, *FBBInfo.BB,
388 FCycle, FBBInfo.ExtraCost2, Prediction);
390 <<
", FCycle=" << FCycle
391 <<
", TExtra=" << TBBInfo.ExtraCost2 <<
", FExtra="
392 << FBBInfo.ExtraCost2 <<
") = " << Res <<
"\n");
398 bool blockAlwaysFallThrough(BBInfo &BBI)
const {
399 return BBI.IsBrAnalyzable && BBI.TrueBB ==
nullptr;
403 static bool IfcvtTokenCmp(
const std::unique_ptr<IfcvtToken> &C1,
404 const std::unique_ptr<IfcvtToken> &C2) {
405 int Incr1 = (C1->Kind == ICDiamond)
406 ? -(
int)(C1->NumDups + C1->NumDups2) : (
int)C1->NumDups;
407 int Incr2 = (C2->Kind == ICDiamond)
408 ? -(
int)(C2->NumDups + C2->NumDups2) : (
int)C2->NumDups;
411 else if (Incr1 == Incr2) {
413 if (!C1->NeedSubsumption && C2->NeedSubsumption)
415 else if (C1->NeedSubsumption == C2->NeedSubsumption) {
417 if ((
unsigned)C1->Kind < (
unsigned)C2->Kind)
419 else if (C1->Kind == C2->Kind)
420 return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
429char IfConverter::ID = 0;
439 if (skipFunction(MF.getFunction()) || (PredicateFtor && !PredicateFtor(MF)))
443 TLI = ST.getTargetLowering();
444 TII = ST.getInstrInfo();
445 TRI = ST.getRegisterInfo();
447 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI());
448 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
450 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
451 MRI = &MF.getRegInfo();
452 SchedModel.
init(&ST);
454 if (!
TII)
return false;
456 PreRegAlloc =
MRI->isSSA();
458 bool BFChange =
false;
466 << MF.getName() <<
"\'");
475 BBAnalysis.resize(MF.getNumBlockIDs());
477 std::vector<std::unique_ptr<IfcvtToken>> Tokens;
479 unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
480 NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
485 AnalyzeBlocks(MF, Tokens);
486 while (!Tokens.empty()) {
487 std::unique_ptr<IfcvtToken> Token = std::move(Tokens.back());
489 BBInfo &BBI = Token->BBI;
490 IfcvtKind Kind = Token->Kind;
491 unsigned NumDups = Token->NumDups;
492 unsigned NumDups2 = Token->NumDups2;
497 BBI.IsEnqueued =
false;
501 BBI.IsEnqueued =
false;
507 case ICSimpleFalse: {
508 bool isFalse = Kind == ICSimpleFalse;
511 << (Kind == ICSimpleFalse ?
" false" :
"")
513 << ((Kind == ICSimpleFalse) ? BBI.FalseBB->getNumber()
514 : BBI.TrueBB->getNumber())
516 RetVal = IfConvertSimple(BBI, Kind);
517 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
519 if (isFalse) ++NumSimpleFalse;
526 case ICTriangleFalse:
527 case ICTriangleFRev: {
528 bool isFalse = Kind == ICTriangleFalse;
529 bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
539 <<
" (T:" << BBI.TrueBB->getNumber()
540 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
541 RetVal = IfConvertTriangle(BBI, Kind);
542 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
556 <<
" (T:" << BBI.TrueBB->getNumber()
557 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
558 RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,
559 Token->TClobbersPred,
560 Token->FClobbersPred);
561 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
562 if (RetVal) ++NumDiamonds;
564 case ICForkedDiamond:
568 <<
" (T:" << BBI.TrueBB->getNumber()
569 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
570 RetVal = IfConvertForkedDiamond(BBI, Kind, NumDups, NumDups2,
571 Token->TClobbersPred,
572 Token->FClobbersPred);
573 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
574 if (RetVal) ++NumForkedDiamonds;
578 if (RetVal &&
MRI->tracksLiveness())
583 NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
584 NumTriangleFalse + NumTriangleFRev + NumDiamonds;
591 MadeChange |= Change;
602 MadeChange |= BFChange;
610 if (SuccBB != TrueBB)
618bool IfConverter::reverseBranchCondition(BBInfo &BBI)
const {
642bool IfConverter::ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
645 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
648 if (TrueBBI.IsBrAnalyzable)
651 if (TrueBBI.BB->pred_size() > 1) {
652 if (TrueBBI.CannotBeCopied ||
656 Dups = TrueBBI.NonPredSize;
667bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
668 bool FalseBranch,
unsigned &Dups,
671 if (TrueBBI.BB == FalseBBI.BB)
674 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
677 if (TrueBBI.BB->pred_size() > 1) {
678 if (TrueBBI.CannotBeCopied)
681 unsigned Size = TrueBBI.NonPredSize;
682 if (TrueBBI.IsBrAnalyzable) {
683 if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
688 ? TrueBBI.TrueBB : TrueBBI.FalseBB;
700 if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
702 if (++
I == TrueBBI.BB->getParent()->end())
706 return TExit && TExit == FalseBBI.BB;
729bool IfConverter::CountDuplicatedInstructions(
734 unsigned &Dups1,
unsigned &Dups2,
736 bool SkipUnconditionalBranches)
const {
737 while (TIB != TIE && FIB != FIE) {
741 if (TIB == TIE || FIB == FIE)
743 if (!TIB->isIdenticalTo(*FIB))
747 std::vector<MachineOperand> PredDefs;
751 if (!TIB->isBranch())
758 if (TIB == TIE || FIB == FIE)
770 if (SkipUnconditionalBranches) {
771 while (RTIE != RTIB && RTIE->isUnconditionalBranch())
773 while (RFIE != RFIB && RFIE->isUnconditionalBranch())
779 while (RTIE != RTIB && RFIE != RFIB) {
784 if (RTIE == RTIB || RFIE == RFIB)
786 if (!RTIE->isIdenticalTo(*RFIE))
790 if (!RTIE->isBranch())
809bool IfConverter::RescanInstructions(
812 BBInfo &TrueBBI, BBInfo &FalseBBI)
const {
813 bool BranchUnpredicable =
true;
814 TrueBBI.IsUnpredicable = FalseBBI.IsUnpredicable =
false;
815 ScanInstructions(TrueBBI, TIB, TIE, BranchUnpredicable);
816 if (TrueBBI.IsUnpredicable)
818 ScanInstructions(FalseBBI, FIB, FIE, BranchUnpredicable);
819 if (FalseBBI.IsUnpredicable)
821 if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)
834 while (E1 != B1 && E2 != B2) {
837 if (E1 == B1 && E2 == B2)
841 assert(!E2->isBranch() &&
"Branch mis-match, one block is empty.");
845 assert(!E1->isBranch() &&
"Branch mis-match, one block is empty.");
849 if (E1->isBranch() || E2->isBranch())
850 assert(E1->isIdenticalTo(*E2) &&
851 "Branch mis-match, branch instructions don't match.");
873bool IfConverter::ValidForkedDiamond(
874 BBInfo &TrueBBI, BBInfo &FalseBBI,
875 unsigned &Dups1,
unsigned &Dups2,
876 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
878 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
879 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
882 if (!TrueBBI.IsBrAnalyzable || !FalseBBI.IsBrAnalyzable)
885 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
890 if (TrueBBI.BrCond.size() == 0 ||
891 FalseBBI.BrCond.size() == 0)
912 if (!((TT == FT && TF == FF) || (TF == FT && TT == FF)))
915 bool FalseReversed =
false;
916 if (TF == FT && TT == FF) {
918 if (!FalseBBI.IsBrReversible)
920 FalseReversed =
true;
921 reverseBranchCondition(FalseBBI);
925 reverseBranchCondition(FalseBBI);
933 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
934 *TrueBBI.BB, *FalseBBI.BB,
938 TrueBBICalc.BB = TrueBBI.BB;
939 FalseBBICalc.BB = FalseBBI.BB;
940 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
941 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
942 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
948 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
949 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
955bool IfConverter::ValidDiamond(
956 BBInfo &TrueBBI, BBInfo &FalseBBI,
957 unsigned &Dups1,
unsigned &Dups2,
958 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
960 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
961 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
966 if (TrueBBI.BB == FalseBBI.BB)
972 if (!TT && blockAlwaysFallThrough(TrueBBI))
974 if (!FT && blockAlwaysFallThrough(FalseBBI))
978 if (!TT && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
980 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
984 if (TrueBBI.FalseBB || FalseBBI.FalseBB)
991 bool SkipUnconditionalBranches =
992 TrueBBI.IsBrAnalyzable && FalseBBI.IsBrAnalyzable;
997 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
998 *TrueBBI.BB, *FalseBBI.BB,
999 SkipUnconditionalBranches))
1002 TrueBBICalc.BB = TrueBBI.BB;
1003 FalseBBICalc.BB = FalseBBI.BB;
1004 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
1005 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
1006 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
1011 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
1012 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
1018void IfConverter::AnalyzeBranches(BBInfo &BBI) {
1022 BBI.TrueBB = BBI.FalseBB =
nullptr;
1024 BBI.IsBrAnalyzable =
1026 if (!BBI.IsBrAnalyzable) {
1027 BBI.TrueBB =
nullptr;
1028 BBI.FalseBB =
nullptr;
1033 BBI.IsBrReversible = (RevCond.size() == 0) ||
1035 BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB ==
nullptr;
1037 if (BBI.BrCond.size()) {
1044 BBI.IsUnpredicable =
true;
1054void IfConverter::ScanInstructions(BBInfo &BBI,
1057 bool BranchUnpredicable)
const {
1058 if (BBI.IsDone || BBI.IsUnpredicable)
1061 bool AlreadyPredicated = !BBI.Predicate.empty();
1063 BBI.NonPredSize = 0;
1066 BBI.ClobbersPred =
false;
1068 if (
MI.isDebugInstr())
1101 if (
MI.isNotDuplicable() ||
MI.isConvergent())
1102 BBI.CannotBeCopied =
true;
1105 bool isCondBr = BBI.IsBrAnalyzable &&
MI.isConditionalBranch();
1107 if (BranchUnpredicable &&
MI.isBranch()) {
1108 BBI.IsUnpredicable =
true;
1116 if (!isPredicated) {
1118 unsigned ExtraPredCost =
TII->getPredicationCost(
MI);
1119 unsigned NumCycles = SchedModel.computeInstrLatency(&
MI,
false);
1121 BBI.ExtraCost += NumCycles-1;
1122 BBI.ExtraCost2 += ExtraPredCost;
1123 }
else if (!AlreadyPredicated) {
1127 BBI.IsUnpredicable =
true;
1131 if (BBI.ClobbersPred && !isPredicated) {
1136 BBI.IsUnpredicable =
true;
1142 std::vector<MachineOperand> PredDefs;
1144 BBI.ClobbersPred =
true;
1147 BBI.IsUnpredicable =
true;
1162bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
1164 bool isTriangle,
bool RevBranch,
1165 bool hasCommonTail) {
1170 if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))
1176 if (BBI.Predicate.size() && !BBI.IsBrAnalyzable)
1184 if (!hasCommonTail && BBI.BrCond.size()) {
1205void IfConverter::AnalyzeBlock(
1212 bool SuccsAnalyzed =
false;
1218 while (!BBStack.empty()) {
1219 BBState &State = BBStack.back();
1221 BBInfo &BBI = BBAnalysis[BB->
getNumber()];
1223 if (!State.SuccsAnalyzed) {
1224 if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
1230 BBI.IsBeingAnalyzed =
true;
1232 AnalyzeBranches(BBI);
1235 ScanInstructions(BBI, Begin,
End);
1239 if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
1240 BBI.IsBeingAnalyzed =
false;
1241 BBI.IsAnalyzed =
true;
1247 if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
1248 BBI.IsBeingAnalyzed =
false;
1249 BBI.IsAnalyzed =
true;
1256 BBI.IsBeingAnalyzed =
false;
1257 BBI.IsAnalyzed =
true;
1263 State.SuccsAnalyzed =
true;
1264 BBStack.push_back(*BBI.FalseBB);
1265 BBStack.push_back(*BBI.TrueBB);
1269 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1270 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1272 if (TrueBBI.IsDone && FalseBBI.IsDone) {
1273 BBI.IsBeingAnalyzed =
false;
1274 BBI.IsAnalyzed =
true;
1280 RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1285 bool TNeedSub = !TrueBBI.Predicate.empty();
1286 bool FNeedSub = !FalseBBI.Predicate.empty();
1287 bool Enqueued =
false;
1292 BBInfo TrueBBICalc, FalseBBICalc;
1293 auto feasibleDiamond = [&](
bool Forked) {
1294 bool MeetsSize = MeetIfcvtSizeLimit(TrueBBICalc, FalseBBICalc, *BB,
1295 Dups + Dups2, Prediction, Forked);
1296 bool TrueFeasible = FeasibilityAnalysis(TrueBBI, BBI.BrCond,
1299 bool FalseFeasible = FeasibilityAnalysis(FalseBBI, RevCond,
1302 return MeetsSize && TrueFeasible && FalseFeasible;
1305 if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1306 TrueBBICalc, FalseBBICalc)) {
1307 if (feasibleDiamond(
false)) {
1316 Tokens.push_back(std::make_unique<IfcvtToken>(
1317 BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1318 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1321 }
else if (ValidForkedDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1322 TrueBBICalc, FalseBBICalc)) {
1323 if (feasibleDiamond(
true)) {
1334 Tokens.push_back(std::make_unique<IfcvtToken>(
1335 BBI, ICForkedDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1336 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1342 if (ValidTriangle(TrueBBI, FalseBBI,
false, Dups, Prediction) &&
1343 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1344 TrueBBI.ExtraCost2, Prediction) &&
1345 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true)) {
1354 std::make_unique<IfcvtToken>(BBI, ICTriangle, TNeedSub, Dups));
1358 if (ValidTriangle(TrueBBI, FalseBBI,
true, Dups, Prediction) &&
1359 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1360 TrueBBI.ExtraCost2, Prediction) &&
1361 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true,
true)) {
1363 std::make_unique<IfcvtToken>(BBI, ICTriangleRev, TNeedSub, Dups));
1367 if (ValidSimple(TrueBBI, Dups, Prediction) &&
1368 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1369 TrueBBI.ExtraCost2, Prediction) &&
1370 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
1379 std::make_unique<IfcvtToken>(BBI, ICSimple, TNeedSub, Dups));
1385 if (ValidTriangle(FalseBBI, TrueBBI,
false, Dups,
1387 MeetIfcvtSizeLimit(*FalseBBI.BB,
1388 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1389 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1390 FeasibilityAnalysis(FalseBBI, RevCond,
true)) {
1391 Tokens.push_back(std::make_unique<IfcvtToken>(BBI, ICTriangleFalse,
1396 if (ValidTriangle(FalseBBI, TrueBBI,
true, Dups,
1398 MeetIfcvtSizeLimit(*FalseBBI.BB,
1399 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1400 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1401 FeasibilityAnalysis(FalseBBI, RevCond,
true,
true)) {
1403 std::make_unique<IfcvtToken>(BBI, ICTriangleFRev, FNeedSub, Dups));
1407 if (ValidSimple(FalseBBI, Dups, Prediction.
getCompl()) &&
1408 MeetIfcvtSizeLimit(*FalseBBI.BB,
1409 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1410 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1411 FeasibilityAnalysis(FalseBBI, RevCond)) {
1413 std::make_unique<IfcvtToken>(BBI, ICSimpleFalse, FNeedSub, Dups));
1418 BBI.IsEnqueued = Enqueued;
1419 BBI.IsBeingAnalyzed =
false;
1420 BBI.IsAnalyzed =
true;
1426void IfConverter::AnalyzeBlocks(
1427 MachineFunction &MF, std::vector<std::unique_ptr<IfcvtToken>> &Tokens) {
1429 AnalyzeBlock(
MBB, Tokens);
1445 if (
I == E || !
I->empty() || !PI->isSuccessor(&*
I))
1450 return PI->isSuccessor(&*
I);
1457 BBInfo &PBBI = BBAnalysis[Predecessor->getNumber()];
1458 if (PBBI.IsDone || PBBI.BB == &
MBB)
1460 PBBI.IsAnalyzed =
false;
1461 PBBI.IsEnqueued =
false;
1483 for (
unsigned Reg : Redefs)
1484 LiveBeforeMI.
insert(Reg);
1490 for (
auto Clobber : Clobbers) {
1493 unsigned Reg = Clobber.first;
1497 if (
Op.isRegMask()) {
1500 if (LiveBeforeMI.
count(Reg))
1512 [&](
MCPhysReg S) { return LiveBeforeMI.count(S); }))
1518bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
1519 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1520 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1521 BBInfo *CvtBBI = &TrueBBI;
1522 BBInfo *NextBBI = &FalseBBI;
1525 if (Kind == ICSimpleFalse)
1530 if (CvtBBI->IsDone ||
1531 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1533 BBI.IsAnalyzed =
false;
1534 CvtBBI->IsAnalyzed =
false;
1542 if (Kind == ICSimpleFalse)
1548 if (
MRI->tracksLiveness()) {
1562 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond);
1565 BBI.BB->removeSuccessor(&CvtMBB,
true);
1568 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1572 MergeBlocks(BBI, *CvtBBI);
1575 bool IterIfcvt =
true;
1578 BBI.HasFallThrough =
false;
1595 InvalidatePreds(*BBI.BB);
1596 CvtBBI->IsDone =
true;
1603bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1604 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1605 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1606 BBInfo *CvtBBI = &TrueBBI;
1607 BBInfo *NextBBI = &FalseBBI;
1611 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1616 if (CvtBBI->IsDone ||
1617 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1619 BBI.IsAnalyzed =
false;
1620 CvtBBI->IsAnalyzed =
false;
1628 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1632 if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
1633 if (reverseBranchCondition(*CvtBBI)) {
1639 BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
1640 if (PBBI.IsEnqueued) {
1641 PBBI.IsAnalyzed =
false;
1642 PBBI.IsEnqueued =
false;
1651 if (
MRI->tracksLiveness()) {
1656 bool HasEarlyExit = CvtBBI->FalseBB !=
nullptr;
1674 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond,
true);
1678 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1681 MergeBlocks(BBI, *CvtBBI,
false);
1685 BBI.BB->removeSuccessor(&CvtMBB,
true);
1690 CvtBBI->BrCond.end());
1701 auto NewNext = BBNext + BBCvt * CvtNext;
1702 auto NewTrueBBIter =
find(BBI.BB->successors(), NewTrueBB);
1703 if (NewTrueBBIter != BBI.BB->succ_end())
1704 BBI.BB->setSuccProbability(NewTrueBBIter, NewNext);
1706 auto NewFalse = BBCvt * CvtFalse;
1708 BBI.BB->addSuccessor(CvtBBI->FalseBB, NewFalse);
1713 bool FalseBBDead =
false;
1714 bool IterIfcvt =
true;
1716 if (!isFallThrough) {
1720 if (!HasEarlyExit &&
1721 NextMBB.
pred_size() == 1 && !NextBBI->HasFallThrough &&
1723 MergeBlocks(BBI, *NextBBI);
1727 BBI.HasFallThrough =
false;
1737 InvalidatePreds(*BBI.BB);
1738 CvtBBI->IsDone =
true;
1740 NextBBI->IsDone =
true;
1757bool IfConverter::IfConvertDiamondCommon(
1758 BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
1759 unsigned NumDups1,
unsigned NumDups2,
1760 bool TClobbersPred,
bool FClobbersPred,
1761 bool RemoveBranch,
bool MergeAddEdges) {
1763 if (TrueBBI.IsDone || FalseBBI.IsDone ||
1764 TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) {
1766 BBI.IsAnalyzed =
false;
1767 TrueBBI.IsAnalyzed =
false;
1768 FalseBBI.IsAnalyzed =
false;
1772 if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
1779 BBInfo *BBI1 = &TrueBBI;
1780 BBInfo *BBI2 = &FalseBBI;
1788 bool DoSwap =
false;
1789 if (TClobbersPred && !FClobbersPred)
1791 else if (!TClobbersPred && !FClobbersPred) {
1792 if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
1794 }
else if (TClobbersPred && FClobbersPred)
1814 if (
MRI->tracksLiveness()) {
1823 BBI1->NonPredSize -= NumDups1;
1824 BBI2->NonPredSize -= NumDups1;
1829 for (
unsigned i = 0; i < NumDups1; ++DI1) {
1830 if (DI1 == MBB1.
end())
1832 if (!DI1->isDebugInstr())
1835 while (NumDups1 != 0) {
1838 if (DI2->shouldUpdateCallSiteInfo())
1842 if (DI2 == MBB2.
end())
1844 if (!DI2->isDebugInstr())
1848 if (
MRI->tracksLiveness()) {
1855 BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.
begin(), DI1);
1866 if (!BBI1->IsBrAnalyzable)
1872 while (DI1 != MBB1.
begin()) {
1874 if (!Prev->isBranch() && !Prev->isDebugInstr())
1878 for (
unsigned i = 0; i != NumDups2; ) {
1887 if (DI1->shouldUpdateCallSiteInfo())
1891 if (!DI1->isDebugInstr())
1896 DI2 = BBI2->BB->end();
1904 while (DI2 != MBB2.
begin()) {
1906 if (!Prev->isBranch() && !Prev->isDebugInstr())
1911 while (NumDups2 != 0) {
1917 if (!DI2->isDebugInstr())
1931 if (
TII->isProfitableToUnpredicate(MBB1, MBB2)) {
1933 if (FI.isDebugInstr())
1944 }
else if (!RedefsByFalse.
count(Reg)) {
1953 if (!ExtUses.
count(Reg)) {
1962 PredicateBlock(*BBI1, MBB1.
end(), *Cond1, &RedefsByFalse);
1971 if (!MBB2.
empty() && (DI2 == MBB2.
end())) {
1976 if (BB2NonPredicated && (BB1Predicated || !BBI2->IsBrAnalyzable))
1981 PredicateBlock(*BBI2, DI2, *Cond2);
1984 MergeBlocks(BBI, *BBI1, MergeAddEdges);
1985 MergeBlocks(BBI, *BBI2, MergeAddEdges);
1991bool IfConverter::IfConvertForkedDiamond(
1992 BBInfo &BBI, IfcvtKind Kind,
1993 unsigned NumDups1,
unsigned NumDups2,
1994 bool TClobbersPred,
bool FClobbersPred) {
1995 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1996 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2001 if (TIE != TrueBBI.BB->end())
2002 dl = TIE->getDebugLoc();
2006 if (!IfConvertDiamondCommon(
2007 BBI, TrueBBI, FalseBBI,
2009 TClobbersPred, FClobbersPred,
2016 TrueBBI.BrCond, dl);
2019 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2020 InvalidatePreds(*BBI.BB);
2027bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
2028 unsigned NumDups1,
unsigned NumDups2,
2029 bool TClobbersPred,
bool FClobbersPred) {
2030 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2031 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2036 if (blockAlwaysFallThrough(TrueBBI))
2037 TailBB = FalseBBI.TrueBB;
2038 assert((TailBB || !TrueBBI.IsBrAnalyzable) &&
"Unexpected!");
2041 if (!IfConvertDiamondCommon(
2042 BBI, TrueBBI, FalseBBI,
2044 TClobbersPred, FClobbersPred,
2045 TrueBBI.IsBrAnalyzable,
2056 BBI.BB->removeSuccessor(TrueBBI.BB);
2057 BBI.BB->removeSuccessor(FalseBBI.BB,
true);
2059 BBInfo &TailBBI = BBAnalysis[TailBB->
getNumber()];
2060 bool CanMergeTail = !TailBBI.HasFallThrough &&
2061 !TailBBI.BB->hasAddressTaken();
2067 CanMergeTail =
false;
2070 unsigned NumPreds = TailBB->
pred_size();
2072 CanMergeTail =
false;
2073 else if (NumPreds == 1 && CanMergeTail) {
2075 if (*PI != TrueBBI.BB && *PI != FalseBBI.BB)
2076 CanMergeTail =
false;
2079 MergeBlocks(BBI, TailBBI);
2080 TailBBI.IsDone =
true;
2084 BBI.HasFallThrough =
false;
2089 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2090 InvalidatePreds(*BBI.BB);
2098 bool SawStore =
true;
2099 if (!
MI.isSafeToMove(SawStore))
2108 if (MO.isDef() && !LaterRedefs.
count(Reg))
2117void IfConverter::PredicateBlock(BBInfo &BBI,
2121 bool AnyUnpred =
false;
2122 bool MaySpec = LaterRedefs !=
nullptr;
2138 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2148 BBI.Predicate.append(
Cond.begin(),
Cond.end());
2150 BBI.IsAnalyzed =
false;
2151 BBI.NonPredSize = 0;
2160void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
2168 if (IgnoreBr &&
I.isBranch())
2173 if (
I.isCandidateForCallSiteEntry())
2176 ToBBI.BB->insert(ToBBI.BB->end(),
MI);
2177 ToBBI.NonPredSize++;
2178 unsigned ExtraPredCost =
TII->getPredicationCost(
I);
2179 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
2181 ToBBI.ExtraCost += NumCycles-1;
2182 ToBBI.ExtraCost2 += ExtraPredCost;
2187 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2199 std::vector<MachineBasicBlock *> Succs(FromMBB.succ_begin(),
2200 FromMBB.succ_end());
2206 if (Succ == FallThrough)
2208 ToBBI.BB->addSuccessor(Succ);
2212 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2213 ToBBI.Predicate.append(
Cond.begin(),
Cond.end());
2215 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2216 ToBBI.IsAnalyzed =
false;
2226void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges) {
2229 "Removing a BB whose address is taken!");
2235 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
2237 if (MO.isMBB() && !ToBBI.BB->isSuccessor(MO.getMBB()))
2244 ToBBI.BB->splice(ToTI, &FromMBB, FromMBB.begin(), FromTI);
2248 ToTI = ToBBI.BB->end();
2249 ToBBI.BB->splice(ToTI, &FromMBB, FromTI, FromMBB.end());
2255 if (ToBBI.IsBrAnalyzable)
2256 ToBBI.BB->normalizeSuccProbs();
2264 if (AddEdges && ToBBI.BB->isSuccessor(&FromMBB)) {
2268 ToBBI.BB->removeSuccessor(&FromMBB);
2273 if (Succ == FallThrough) {
2274 FromMBB.removeSuccessor(Succ);
2291 if (!To2FromProb.isZero())
2292 NewProb *= To2FromProb;
2295 FromMBB.removeSuccessor(Succ);
2320 if (ToBBI.BB->isSuccessor(Succ))
2321 ToBBI.BB->setSuccProbability(
2322 find(ToBBI.BB->successors(), Succ),
2325 ToBBI.BB->addSuccessor(Succ, NewProb);
2332 if (
Last != &FromMBB)
2333 FromMBB.moveAfter(
Last);
2337 if (ToBBI.IsBrAnalyzable && FromBBI.IsBrAnalyzable)
2338 ToBBI.BB->normalizeSuccProbs();
2340 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2341 FromBBI.Predicate.clear();
2343 ToBBI.NonPredSize += FromBBI.NonPredSize;
2344 ToBBI.ExtraCost += FromBBI.ExtraCost;
2345 ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
2346 FromBBI.NonPredSize = 0;
2347 FromBBI.ExtraCost = 0;
2348 FromBBI.ExtraCost2 = 0;
2350 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2351 ToBBI.HasFallThrough = FromBBI.HasFallThrough;
2352 ToBBI.IsAnalyzed =
false;
2353 FromBBI.IsAnalyzed =
false;
2358 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.