42 #define DEBUG_TYPE "ifcvt"
67 STATISTIC(NumSimple,
"Number of simple if-conversions performed");
68 STATISTIC(NumSimpleFalse,
"Number of simple (F) if-conversions performed");
69 STATISTIC(NumTriangle,
"Number of triangle if-conversions performed");
70 STATISTIC(NumTriangleRev,
"Number of triangle (R) if-conversions performed");
71 STATISTIC(NumTriangleFalse,
"Number of triangle (F) if-conversions performed");
72 STATISTIC(NumTriangleFRev,
"Number of triangle (F/R) if-conversions performed");
73 STATISTIC(NumDiamonds,
"Number of diamond if-conversions performed");
74 STATISTIC(NumForkedDiamonds,
"Number of forked-diamond if-conversions performed");
75 STATISTIC(NumIfConvBBs,
"Number of if-converted blocks");
76 STATISTIC(NumDupBBs,
"Number of duplicated blocks");
77 STATISTIC(NumUnpred,
"Number of true blocks of diamonds unpredicated");
119 bool IsBeingAnalyzed : 1;
122 bool IsBrAnalyzable : 1;
123 bool IsBrReversible : 1;
124 bool HasFallThrough : 1;
125 bool IsUnpredicable : 1;
126 bool CannotBeCopied : 1;
127 bool ClobbersPred : 1;
128 unsigned NonPredSize;
136 BBInfo() : IsDone(
false), IsBeingAnalyzed(
false),
140 ClobbersPred(
false), NonPredSize(0), ExtraCost(0),
141 ExtraCost2(0), BB(nullptr), TrueBB(nullptr),
161 bool NeedSubsumption : 1;
162 bool TClobbersPred : 1;
163 bool FClobbersPred : 1;
164 IfcvtToken(BBInfo &b, IfcvtKind k,
bool s,
unsigned d,
unsigned d2 = 0,
165 bool tc =
false,
bool fc =
false)
166 : BBI(b),
Kind(k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
167 TClobbersPred(tc), FClobbersPred(fc) {}
172 std::vector<BBInfo> BBAnalysis;
187 std::function<bool(const MachineFunction &)> PredicateFtor;
210 bool reverseBranchCondition(BBInfo &BBI)
const;
211 bool ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
213 bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
214 bool FalseBranch,
unsigned &Dups,
216 bool CountDuplicatedInstructions(
219 unsigned &Dups1,
unsigned &Dups2,
221 bool SkipUnconditionalBranches)
const;
222 bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
223 unsigned &Dups1,
unsigned &Dups2,
224 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
225 bool ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
226 unsigned &Dups1,
unsigned &Dups2,
227 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
228 void AnalyzeBranches(BBInfo &BBI);
229 void ScanInstructions(BBInfo &BBI,
232 bool BranchUnpredicable =
false)
const;
233 bool RescanInstructions(
236 BBInfo &TrueBBI, BBInfo &FalseBBI)
const;
238 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
240 bool isTriangle =
false,
bool RevBranch =
false,
241 bool hasCommonTail =
false);
243 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
245 void RemoveExtraEdges(BBInfo &BBI);
246 bool IfConvertSimple(BBInfo &BBI, IfcvtKind
Kind);
247 bool IfConvertTriangle(BBInfo &BBI, IfcvtKind
Kind);
248 bool IfConvertDiamondCommon(BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
249 unsigned NumDups1,
unsigned NumDups2,
250 bool TClobbersPred,
bool FClobbersPred,
251 bool RemoveBranch,
bool MergeAddEdges);
252 bool IfConvertDiamond(BBInfo &BBI, IfcvtKind
Kind,
253 unsigned NumDups1,
unsigned NumDups2,
254 bool TClobbers,
bool FClobbers);
255 bool IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind
Kind,
256 unsigned NumDups1,
unsigned NumDups2,
257 bool TClobbers,
bool FClobbers);
258 void PredicateBlock(BBInfo &BBI,
262 void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
264 bool IgnoreBr =
false);
265 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges =
true);
268 unsigned Cycle,
unsigned Extra,
275 unsigned TCycle,
unsigned TExtra,
277 unsigned FCycle,
unsigned FExtra,
279 return TCycle > 0 && FCycle > 0 &&
285 bool blockAlwaysFallThrough(BBInfo &BBI)
const {
286 return BBI.IsBrAnalyzable && BBI.TrueBB ==
nullptr;
290 static bool IfcvtTokenCmp(
const std::unique_ptr<IfcvtToken> &C1,
291 const std::unique_ptr<IfcvtToken> &C2) {
292 int Incr1 = (C1->Kind == ICDiamond)
293 ? -(
int)(C1->NumDups + C1->NumDups2) : (
int)C1->NumDups;
294 int Incr2 = (C2->Kind == ICDiamond)
295 ? -(
int)(C2->NumDups + C2->NumDups2) : (
int)C2->NumDups;
298 else if (Incr1 == Incr2) {
300 if (!C1->NeedSubsumption && C2->NeedSubsumption)
302 else if (C1->NeedSubsumption == C2->NeedSubsumption) {
304 if ((
unsigned)C1->Kind < (
unsigned)C2->Kind)
306 else if (C1->Kind == C2->Kind)
307 return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
324 if (skipFunction(*MF.getFunction()) || (PredicateFtor && !PredicateFtor(MF)))
332 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
333 MRI = &MF.getRegInfo();
336 if (!
TII)
return false;
338 PreRegAlloc = MRI->isSSA();
340 bool BFChange =
false;
345 getAnalysisIfAvailable<MachineModuleInfo>());
348 DEBUG(
dbgs() <<
"\nIfcvt: function (" << ++FnNum <<
") \'"
349 << MF.getName() <<
"\'");
358 BBAnalysis.resize(MF.getNumBlockIDs());
360 std::vector<std::unique_ptr<IfcvtToken>> Tokens;
362 unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
363 NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
368 AnalyzeBlocks(MF, Tokens);
369 while (!Tokens.empty()) {
370 std::unique_ptr<IfcvtToken>
Token = std::move(Tokens.back());
372 BBInfo &BBI = Token->BBI;
373 IfcvtKind
Kind = Token->Kind;
374 unsigned NumDups = Token->NumDups;
375 unsigned NumDups2 = Token->NumDups2;
380 BBI.IsEnqueued =
false;
384 BBI.IsEnqueued =
false;
390 case ICSimpleFalse: {
391 bool isFalse = Kind == ICSimpleFalse;
393 DEBUG(
dbgs() <<
"Ifcvt (Simple" << (Kind == ICSimpleFalse ?
395 <<
"): BB#" << BBI.BB->getNumber() <<
" ("
396 << ((Kind == ICSimpleFalse)
397 ? BBI.FalseBB->getNumber()
398 : BBI.TrueBB->getNumber()) <<
") ");
399 RetVal = IfConvertSimple(BBI, Kind);
400 DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
402 if (isFalse) ++NumSimpleFalse;
409 case ICTriangleFalse:
410 case ICTriangleFRev: {
411 bool isFalse = Kind == ICTriangleFalse;
412 bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
422 DEBUG(
dbgs() <<
"): BB#" << BBI.BB->getNumber() <<
" (T:"
423 << BBI.TrueBB->getNumber() <<
",F:"
424 << BBI.FalseBB->getNumber() <<
") ");
425 RetVal = IfConvertTriangle(BBI, Kind);
426 DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
429 if (isRev) ++NumTriangleFRev;
430 else ++NumTriangleFalse;
432 if (isRev) ++NumTriangleRev;
440 DEBUG(
dbgs() <<
"Ifcvt (Diamond): BB#" << BBI.BB->getNumber() <<
" (T:"
441 << BBI.TrueBB->getNumber() <<
",F:"
442 << BBI.FalseBB->getNumber() <<
") ");
443 RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,
444 Token->TClobbersPred,
445 Token->FClobbersPred);
446 DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
447 if (RetVal) ++NumDiamonds;
450 case ICForkedDiamond: {
452 DEBUG(
dbgs() <<
"Ifcvt (Forked Diamond): BB#"
453 << BBI.BB->getNumber() <<
" (T:"
454 << BBI.TrueBB->getNumber() <<
",F:"
455 << BBI.FalseBB->getNumber() <<
") ");
456 RetVal = IfConvertForkedDiamond(BBI, Kind, NumDups, NumDups2,
457 Token->TClobbersPred,
458 Token->FClobbersPred);
459 DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
460 if (RetVal) ++NumForkedDiamonds;
467 NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
468 NumTriangleFalse + NumTriangleFRev + NumDiamonds;
475 MadeChange |= Change;
484 getAnalysisIfAvailable<MachineModuleInfo>());
487 MadeChange |= BFChange;
495 if (SuccBB != TrueBB)
503 bool IfConverter::reverseBranchCondition(BBInfo &BBI)
const {
527 bool IfConverter::ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
530 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
533 if (TrueBBI.IsBrAnalyzable)
536 if (TrueBBI.BB->pred_size() > 1) {
537 if (TrueBBI.CannotBeCopied ||
541 Dups = TrueBBI.NonPredSize;
552 bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
553 bool FalseBranch,
unsigned &Dups,
556 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
559 if (TrueBBI.BB->pred_size() > 1) {
560 if (TrueBBI.CannotBeCopied)
563 unsigned Size = TrueBBI.NonPredSize;
564 if (TrueBBI.IsBrAnalyzable) {
565 if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
570 ? TrueBBI.TrueBB : TrueBBI.FalseBB;
582 if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
584 if (++I == TrueBBI.BB->getParent()->end())
588 return TExit && TExit == FalseBBI.BB;
624 bool IfConverter::CountDuplicatedInstructions(
629 unsigned &Dups1,
unsigned &Dups2,
631 bool SkipUnconditionalBranches)
const {
633 while (TIB != TIE && FIB != FIE) {
641 if (!TIB->isIdenticalTo(*FIB))
645 std::vector<MachineOperand> PredDefs;
649 if (!TIB->isBranch())
656 if (TIB == TIE || FIB == FIE)
667 bool TEmpty =
false, FEmpty =
false;
680 if (SkipUnconditionalBranches) {
681 while (!TEmpty && TIE->isUnconditionalBranch())
683 while (!FEmpty && FIE->isUnconditionalBranch())
690 if (TEmpty || FEmpty)
694 while (!TEmpty && !FEmpty) {
698 TEmpty = TIE == TIB && TIE->isDebugValue();
699 FEmpty = FIE == FIB && FIE->isDebugValue();
700 if (TEmpty || FEmpty)
702 if (!TIE->isIdenticalTo(*FIE))
706 if (!TIE->isBranch())
723 bool IfConverter::RescanInstructions(
726 BBInfo &TrueBBI, BBInfo &FalseBBI)
const {
727 bool BranchUnpredicable =
true;
728 TrueBBI.IsUnpredicable = FalseBBI.IsUnpredicable =
false;
729 ScanInstructions(TrueBBI, TIB, TIE, BranchUnpredicable);
730 if (TrueBBI.IsUnpredicable)
732 ScanInstructions(FalseBBI, FIB, FIE, BranchUnpredicable);
733 if (FalseBBI.IsUnpredicable)
735 if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)
748 bool Empty1 =
false, Empty2 =
false;
749 while (!Empty1 && !Empty2) {
752 Empty1 = E1 == B1 && E1->isDebugValue();
753 Empty2 = E2 == B2 && E2->isDebugValue();
755 if (Empty1 && Empty2)
759 assert(!E2->isBranch() &&
"Branch mis-match, one block is empty.");
763 assert(!E1->isBranch() &&
"Branch mis-match, one block is empty.");
767 if (E1->isBranch() || E2->isBranch())
768 assert(E1->isIdenticalTo(*E2) &&
769 "Branch mis-match, branch instructions don't match.");
791 bool IfConverter::ValidForkedDiamond(
792 BBInfo &TrueBBI, BBInfo &FalseBBI,
793 unsigned &Dups1,
unsigned &Dups2,
794 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
796 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
797 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
800 if (!TrueBBI.IsBrAnalyzable || !FalseBBI.IsBrAnalyzable)
803 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
808 if (TrueBBI.BrCond.size() == 0 ||
809 FalseBBI.BrCond.size() == 0)
830 if (!((TT == FT && TF == FF) || (TF == FT && TT == FF)))
833 bool FalseReversed =
false;
834 if (TF == FT && TT == FF) {
836 if (!FalseBBI.IsBrReversible)
838 FalseReversed =
true;
839 reverseBranchCondition(FalseBBI);
843 reverseBranchCondition(FalseBBI);
851 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
852 *TrueBBI.BB, *FalseBBI.BB,
856 TrueBBICalc.BB = TrueBBI.BB;
857 FalseBBICalc.BB = FalseBBI.BB;
858 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
864 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
865 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
871 bool IfConverter::ValidDiamond(
872 BBInfo &TrueBBI, BBInfo &FalseBBI,
873 unsigned &Dups1,
unsigned &Dups2,
874 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
876 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
877 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
883 if (!TT && blockAlwaysFallThrough(TrueBBI))
885 if (!FT && blockAlwaysFallThrough(FalseBBI))
889 if (!TT && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
891 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
895 if (TrueBBI.FalseBB || FalseBBI.FalseBB)
902 bool SkipUnconditionalBranches =
903 TrueBBI.IsBrAnalyzable && FalseBBI.IsBrAnalyzable;
908 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
909 *TrueBBI.BB, *FalseBBI.BB,
910 SkipUnconditionalBranches))
913 TrueBBICalc.BB = TrueBBI.BB;
914 FalseBBICalc.BB = FalseBBI.BB;
915 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
920 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
921 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
927 void IfConverter::AnalyzeBranches(BBInfo &BBI) {
931 BBI.TrueBB = BBI.FalseBB =
nullptr;
936 BBI.IsBrReversible = (RevCond.size() == 0) ||
938 BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB ==
nullptr;
940 if (BBI.BrCond.size()) {
947 BBI.IsUnpredicable =
true;
957 void IfConverter::ScanInstructions(BBInfo &BBI,
960 bool BranchUnpredicable)
const {
961 if (BBI.IsDone || BBI.IsUnpredicable)
964 bool AlreadyPredicated = !BBI.Predicate.empty();
969 BBI.ClobbersPred =
false;
971 if (
MI.isDebugValue())
1004 if (
MI.isNotDuplicable() ||
MI.isConvergent())
1005 BBI.CannotBeCopied =
true;
1008 bool isCondBr = BBI.IsBrAnalyzable &&
MI.isConditionalBranch();
1010 if (BranchUnpredicable &&
MI.isBranch()) {
1011 BBI.IsUnpredicable =
true;
1021 unsigned ExtraPredCost =
TII->getPredicationCost(
MI);
1022 unsigned NumCycles = SchedModel.computeInstrLatency(&
MI,
false);
1024 BBI.ExtraCost += NumCycles-1;
1025 BBI.ExtraCost2 += ExtraPredCost;
1026 }
else if (!AlreadyPredicated) {
1030 BBI.IsUnpredicable =
true;
1039 BBI.IsUnpredicable =
true;
1045 std::vector<MachineOperand> PredDefs;
1047 BBI.ClobbersPred =
true;
1050 BBI.IsUnpredicable =
true;
1065 bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
1067 bool isTriangle,
bool RevBranch,
1068 bool hasCommonTail) {
1073 if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))
1079 if (BBI.Predicate.size() && !BBI.IsBrAnalyzable)
1087 if (!hasCommonTail && BBI.BrCond.size()) {
1108 void IfConverter::AnalyzeBlock(
1121 while (!BBStack.empty()) {
1122 BBState &State = BBStack.back();
1124 BBInfo &BBI = BBAnalysis[BB->
getNumber()];
1126 if (!State.SuccsAnalyzed) {
1127 if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
1133 BBI.IsBeingAnalyzed =
true;
1135 AnalyzeBranches(BBI);
1138 ScanInstructions(BBI, Begin, End);
1142 if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
1143 BBI.IsBeingAnalyzed =
false;
1144 BBI.IsAnalyzed =
true;
1150 if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
1151 BBI.IsBeingAnalyzed =
false;
1152 BBI.IsAnalyzed =
true;
1159 BBI.IsBeingAnalyzed =
false;
1160 BBI.IsAnalyzed =
true;
1166 State.SuccsAnalyzed =
true;
1167 BBStack.push_back(*BBI.FalseBB);
1168 BBStack.push_back(*BBI.TrueBB);
1172 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1173 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1175 if (TrueBBI.IsDone && FalseBBI.IsDone) {
1176 BBI.IsBeingAnalyzed =
false;
1177 BBI.IsAnalyzed =
true;
1183 RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1188 bool TNeedSub = !TrueBBI.Predicate.empty();
1189 bool FNeedSub = !FalseBBI.Predicate.empty();
1190 bool Enqueued =
false;
1195 BBInfo TrueBBICalc, FalseBBICalc;
1196 auto feasibleDiamond = [&]() {
1197 bool MeetsSize = MeetIfcvtSizeLimit(
1198 *TrueBBI.BB, (TrueBBICalc.NonPredSize - (Dups + Dups2) +
1199 TrueBBICalc.ExtraCost), TrueBBICalc.ExtraCost2,
1200 *FalseBBI.BB, (FalseBBICalc.NonPredSize - (Dups + Dups2) +
1201 FalseBBICalc.ExtraCost), FalseBBICalc.ExtraCost2,
1203 bool TrueFeasible = FeasibilityAnalysis(TrueBBI, BBI.BrCond,
1206 bool FalseFeasible = FeasibilityAnalysis(FalseBBI, RevCond,
1209 return MeetsSize && TrueFeasible && FalseFeasible;
1212 if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1213 TrueBBICalc, FalseBBICalc)) {
1214 if (feasibleDiamond()) {
1223 Tokens.push_back(llvm::make_unique<IfcvtToken>(
1224 BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1225 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1228 }
else if (ValidForkedDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1229 TrueBBICalc, FalseBBICalc)) {
1230 if (feasibleDiamond()) {
1241 Tokens.push_back(llvm::make_unique<IfcvtToken>(
1242 BBI, ICForkedDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1243 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1249 if (ValidTriangle(TrueBBI, FalseBBI,
false, Dups, Prediction) &&
1250 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1251 TrueBBI.ExtraCost2, Prediction) &&
1252 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true)) {
1261 llvm::make_unique<IfcvtToken>(BBI, ICTriangle, TNeedSub, Dups));
1265 if (ValidTriangle(TrueBBI, FalseBBI,
true, Dups, Prediction) &&
1266 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1267 TrueBBI.ExtraCost2, Prediction) &&
1268 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true,
true)) {
1270 llvm::make_unique<IfcvtToken>(BBI, ICTriangleRev, TNeedSub, Dups));
1274 if (ValidSimple(TrueBBI, Dups, Prediction) &&
1275 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1276 TrueBBI.ExtraCost2, Prediction) &&
1277 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
1286 llvm::make_unique<IfcvtToken>(BBI, ICSimple, TNeedSub, Dups));
1292 if (ValidTriangle(FalseBBI, TrueBBI,
false, Dups,
1294 MeetIfcvtSizeLimit(*FalseBBI.BB,
1295 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1296 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1297 FeasibilityAnalysis(FalseBBI, RevCond,
true)) {
1298 Tokens.push_back(llvm::make_unique<IfcvtToken>(BBI, ICTriangleFalse,
1303 if (ValidTriangle(FalseBBI, TrueBBI,
true, Dups,
1305 MeetIfcvtSizeLimit(*FalseBBI.BB,
1306 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1307 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1308 FeasibilityAnalysis(FalseBBI, RevCond,
true,
true)) {
1310 llvm::make_unique<IfcvtToken>(BBI, ICTriangleFRev, FNeedSub, Dups));
1314 if (ValidSimple(FalseBBI, Dups, Prediction.
getCompl()) &&
1315 MeetIfcvtSizeLimit(*FalseBBI.BB,
1316 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1317 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1318 FeasibilityAnalysis(FalseBBI, RevCond)) {
1320 llvm::make_unique<IfcvtToken>(BBI, ICSimpleFalse, FNeedSub, Dups));
1325 BBI.IsEnqueued = Enqueued;
1326 BBI.IsBeingAnalyzed =
false;
1327 BBI.IsAnalyzed =
true;
1333 void IfConverter::AnalyzeBlocks(
1334 MachineFunction &MF, std::vector<std::unique_ptr<IfcvtToken>> &Tokens) {
1336 AnalyzeBlock(MBB, Tokens);
1339 std::stable_sort(Tokens.begin(), Tokens.end(), IfcvtTokenCmp);
1352 if (I == E || !I->empty() || !PI->isSuccessor(&*I))
1363 BBInfo &PBBI = BBAnalysis[Predecessor->getNumber()];
1364 if (PBBI.IsDone || PBBI.BB == &MBB)
1366 PBBI.IsAnalyzed =
false;
1367 PBBI.IsEnqueued =
false;
1380 void IfConverter::RemoveExtraEdges(BBInfo &BBI) {
1384 BBI.BB->CorrectExtraCFGEdges(TBB, FBB, !Cond.
empty());
1398 for (
unsigned Reg : Redefs)
1402 Redefs.stepForward(MI, Clobbers);
1405 for (
auto Clobber : Clobbers) {
1408 unsigned Reg = Clobber.first;
1415 if (LiveBeforeMI.
count(Reg))
1426 assert(Op.
isReg() &&
"Register operand required");
1430 if (Redefs.contains(Op.
getReg()))
1433 if (LiveBeforeMI.
count(Reg))
1436 bool HasLiveSubReg =
false;
1438 if (!LiveBeforeMI.
count(*S))
1440 HasLiveSubReg =
true;
1452 if (!O->isReg() || !O->isKill())
1454 if (DontKill.
contains(O->getReg()))
1455 O->setIsKill(
false);
1470 bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind
Kind) {
1471 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1472 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1473 BBInfo *CvtBBI = &TrueBBI;
1474 BBInfo *NextBBI = &FalseBBI;
1477 if (Kind == ICSimpleFalse)
1482 if (CvtBBI->IsDone ||
1483 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1485 BBI.IsAnalyzed =
false;
1486 CvtBBI->IsAnalyzed =
false;
1494 if (Kind == ICSimpleFalse)
1499 DontKill.init(*TRI);
1501 if (
MRI->tracksLiveness()) {
1504 Redefs.addLiveIns(CvtMBB);
1505 Redefs.addLiveIns(NextMBB);
1508 DontKill.addLiveIns(NextMBB);
1515 CopyAndPredicateBlock(BBI, *CvtBBI, Cond);
1519 BBI.BB->removeSuccessor(&CvtMBB,
true);
1522 PredicateBlock(*CvtBBI, CvtMBB.
end(), Cond);
1526 MergeBlocks(BBI, *CvtBBI);
1529 bool IterIfcvt =
true;
1532 BBI.HasFallThrough =
false;
1546 RemoveExtraEdges(BBI);
1551 InvalidatePreds(*BBI.BB);
1552 CvtBBI->IsDone =
true;
1559 bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1560 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1561 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1562 BBInfo *CvtBBI = &TrueBBI;
1563 BBInfo *NextBBI = &FalseBBI;
1567 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1572 if (CvtBBI->IsDone ||
1573 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1575 BBI.IsAnalyzed =
false;
1576 CvtBBI->IsAnalyzed =
false;
1584 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1588 if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
1589 if (reverseBranchCondition(*CvtBBI)) {
1595 BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
1596 if (PBBI.IsEnqueued) {
1597 PBBI.IsAnalyzed =
false;
1598 PBBI.IsEnqueued =
false;
1607 if (
MRI->tracksLiveness()) {
1608 Redefs.addLiveIns(CvtMBB);
1609 Redefs.addLiveIns(NextMBB);
1614 bool HasEarlyExit = CvtBBI->FalseBB !=
nullptr;
1619 CvtNext = MBPI->getEdgeProbability(&CvtMBB, &NextMBB);
1620 CvtFalse = MBPI->getEdgeProbability(&CvtMBB, CvtBBI->FalseBB);
1621 BBNext = MBPI->getEdgeProbability(BBI.BB, &NextMBB);
1622 BBCvt = MBPI->getEdgeProbability(BBI.BB, &CvtMBB);
1629 CopyAndPredicateBlock(BBI, *CvtBBI, Cond,
true);
1633 BBI.BB->removeSuccessor(&CvtMBB,
true);
1637 PredicateBlock(*CvtBBI, CvtMBB.
end(), Cond);
1641 MergeBlocks(BBI, *CvtBBI,
false);
1647 CvtBBI->BrCond.end());
1658 auto NewNext = BBNext + BBCvt * CvtNext;
1659 auto NewTrueBBIter =
find(BBI.BB->successors(), NewTrueBB);
1660 if (NewTrueBBIter != BBI.BB->succ_end())
1661 BBI.BB->setSuccProbability(NewTrueBBIter, NewNext);
1663 auto NewFalse = BBCvt * CvtFalse;
1665 BBI.BB->addSuccessor(CvtBBI->FalseBB, NewFalse);
1670 bool FalseBBDead =
false;
1671 bool IterIfcvt =
true;
1673 if (!isFallThrough) {
1677 if (!HasEarlyExit &&
1678 NextMBB.
pred_size() == 1 && !NextBBI->HasFallThrough &&
1680 MergeBlocks(BBI, *NextBBI);
1684 BBI.HasFallThrough =
false;
1691 RemoveExtraEdges(BBI);
1696 InvalidatePreds(*BBI.BB);
1697 CvtBBI->IsDone =
true;
1699 NextBBI->IsDone =
true;
1716 bool IfConverter::IfConvertDiamondCommon(
1717 BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
1718 unsigned NumDups1,
unsigned NumDups2,
1719 bool TClobbersPred,
bool FClobbersPred,
1720 bool RemoveBranch,
bool MergeAddEdges) {
1722 if (TrueBBI.IsDone || FalseBBI.IsDone ||
1723 TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) {
1725 BBI.IsAnalyzed =
false;
1726 TrueBBI.IsAnalyzed =
false;
1727 FalseBBI.IsAnalyzed =
false;
1731 if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
1738 BBInfo *BBI1 = &TrueBBI;
1739 BBInfo *BBI2 = &FalseBBI;
1747 bool DoSwap =
false;
1748 if (TClobbersPred && !FClobbersPred)
1750 else if (!TClobbersPred && !FClobbersPred) {
1751 if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
1753 }
else if (TClobbersPred && FClobbersPred)
1773 if (
MRI->tracksLiveness()) {
1774 Redefs.addLiveIns(MBB1);
1775 Redefs.addLiveIns(MBB2);
1782 BBI1->NonPredSize -= NumDups1;
1783 BBI2->NonPredSize -= NumDups1;
1787 for (
unsigned i = 0;
i < NumDups1; ++DI1) {
1788 if (!DI1->isDebugValue())
1791 while (NumDups1 != 0) {
1793 if (!DI2->isDebugValue())
1800 DontKill.init(*TRI);
1801 if (
MRI->tracksLiveness()) {
1803 DontKill.stepBackward(
MI);
1807 Redefs.stepForward(
MI, Dummy);
1810 BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.
begin(), DI1);
1817 if (!BBI1->IsBrAnalyzable)
1823 for (
unsigned i = 0;
i != NumDups2; ) {
1829 if (!DI1->isDebugValue())
1838 DI2 = BBI2->BB->end();
1847 }
while (DI2->isBranch() || DI2->isDebugValue());
1850 while (NumDups2 != 0) {
1856 if (!DI2->isDebugValue())
1870 if (
TII->isProfitableToUnpredicate(MBB1, MBB2)) {
1872 if (FI.isDebugValue())
1878 unsigned Reg = MO.getReg();
1883 }
else if (!RedefsByFalse.
count(Reg)) {
1888 ExtUses.
insert(*SubRegs);
1892 for (
unsigned Reg : Defs) {
1893 if (!ExtUses.
count(Reg)) {
1896 RedefsByFalse.
insert(*SubRegs);
1903 PredicateBlock(*BBI1, MBB1.
end(), *Cond1, &RedefsByFalse);
1909 if (!MBB2.
empty() && (DI2 == MBB2.
end())) {
1918 PredicateBlock(*BBI2, DI2, *Cond2);
1921 MergeBlocks(BBI, *BBI1, MergeAddEdges);
1922 MergeBlocks(BBI, *BBI2, MergeAddEdges);
1928 bool IfConverter::IfConvertForkedDiamond(
1929 BBInfo &BBI, IfcvtKind Kind,
1930 unsigned NumDups1,
unsigned NumDups2,
1931 bool TClobbersPred,
bool FClobbersPred) {
1932 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1933 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1938 if (TIE != TrueBBI.BB->end())
1939 dl = TIE->getDebugLoc();
1943 if (!IfConvertDiamondCommon(
1944 BBI, TrueBBI, FalseBBI,
1946 TClobbersPred, FClobbersPred,
1953 TrueBBI.BrCond, dl);
1955 RemoveExtraEdges(BBI);
1958 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
1959 InvalidatePreds(*BBI.BB);
1966 bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
1967 unsigned NumDups1,
unsigned NumDups2,
1968 bool TClobbersPred,
bool FClobbersPred) {
1969 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1970 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1975 if (blockAlwaysFallThrough(TrueBBI))
1976 TailBB = FalseBBI.TrueBB;
1977 assert((TailBB || !TrueBBI.IsBrAnalyzable) &&
"Unexpected!");
1980 if (!IfConvertDiamondCommon(
1981 BBI, TrueBBI, FalseBBI,
1983 TClobbersPred, FClobbersPred,
1984 TrueBBI.IsBrAnalyzable,
1993 BBInfo &TailBBI = BBAnalysis[TailBB->
getNumber()];
1994 bool CanMergeTail = !TailBBI.HasFallThrough &&
1995 !TailBBI.BB->hasAddressTaken();
2001 CanMergeTail =
false;
2004 unsigned NumPreds = TailBB->
pred_size();
2006 CanMergeTail =
false;
2007 else if (NumPreds == 1 && CanMergeTail) {
2009 if (*PI != TrueBBI.BB && *PI != FalseBBI.BB)
2010 CanMergeTail =
false;
2013 MergeBlocks(BBI, TailBBI);
2014 TailBBI.IsDone =
true;
2018 BBI.HasFallThrough =
false;
2025 BBI.BB->removeSuccessor(TrueBBI.BB);
2026 BBI.BB->removeSuccessor(FalseBBI.BB,
true);
2027 RemoveExtraEdges(BBI);
2030 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2031 InvalidatePreds(*BBI.BB);
2046 unsigned Reg = MO.getReg();
2049 if (MO.isDef() && !LaterRedefs.
count(Reg))
2058 void IfConverter::PredicateBlock(BBInfo &BBI,
2062 bool AnyUnpred =
false;
2063 bool MaySpec = LaterRedefs !=
nullptr;
2079 dbgs() <<
"Unable to predicate " << I <<
"!\n";
2089 BBI.Predicate.append(Cond.
begin(), Cond.
end());
2091 BBI.IsAnalyzed =
false;
2092 BBI.NonPredSize = 0;
2101 void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
2109 if (IgnoreBr && I.isBranch())
2113 ToBBI.BB->insert(ToBBI.BB->end(),
MI);
2114 ToBBI.NonPredSize++;
2115 unsigned ExtraPredCost =
TII->getPredicationCost(I);
2116 unsigned NumCycles = SchedModel.computeInstrLatency(&I,
false);
2118 ToBBI.ExtraCost += NumCycles-1;
2119 ToBBI.ExtraCost2 += ExtraPredCost;
2124 dbgs() <<
"Unable to predicate " << I <<
"!\n";
2135 if (!DontKill.empty())
2140 std::vector<MachineBasicBlock *> Succs(FromMBB.succ_begin(),
2141 FromMBB.succ_end());
2147 if (Succ == FallThrough)
2149 ToBBI.BB->addSuccessor(Succ);
2153 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2154 ToBBI.Predicate.append(Cond.
begin(), Cond.
end());
2156 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2157 ToBBI.IsAnalyzed =
false;
2166 void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges) {
2169 "Removing a BB whose address is taken!");
2175 ToBBI.BB->splice(ToTI, &FromMBB, FromMBB.
begin(), FromTI);
2179 ToTI = ToBBI.BB->end();
2180 ToBBI.BB->splice(ToTI, &FromMBB, FromTI, FromMBB.
end());
2186 ToBBI.BB->normalizeSuccProbs();
2195 if (AddEdges && ToBBI.BB->isSuccessor(&FromMBB)) {
2196 To2FromProb = MBPI->getEdgeProbability(ToBBI.BB, &FromMBB);
2200 ToBBI.BB->setSuccProbability(
find(ToBBI.BB->successors(), &FromMBB),
2206 if (Succ == FallThrough)
2215 NewProb = MBPI->getEdgeProbability(&FromMBB, Succ);
2222 if (!To2FromProb.isZero())
2223 NewProb *= To2FromProb;
2251 if (ToBBI.BB->isSuccessor(Succ))
2252 ToBBI.BB->setSuccProbability(
2253 find(ToBBI.BB->successors(), Succ),
2254 MBPI->getEdgeProbability(ToBBI.BB, Succ) + NewProb);
2256 ToBBI.BB->addSuccessor(Succ, NewProb);
2266 ToBBI.BB->normalizeSuccProbs();
2268 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2269 FromBBI.Predicate.clear();
2271 ToBBI.NonPredSize += FromBBI.NonPredSize;
2272 ToBBI.ExtraCost += FromBBI.ExtraCost;
2273 ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
2274 FromBBI.NonPredSize = 0;
2275 FromBBI.ExtraCost = 0;
2276 FromBBI.ExtraCost2 = 0;
2278 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2279 ToBBI.HasFallThrough = FromBBI.HasFallThrough;
2280 ToBBI.IsAnalyzed =
false;
2281 FromBBI.IsAnalyzed =
false;
2286 return new IfConverter(std::move(Ftor));
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
bool DefinesPredicate(MachineInstr &MI, std::vector< MachineOperand > &Pred) const override
If the specified instruction defines any predicate or condition code register(s) used for predication...
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
MachineInstr * getParent()
getParent - Return the instruction that this operand belongs to.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
STATISTIC(NumFunctions,"Total number of functions")
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
static void UpdatePredRedefs(MachineInstr &MI, LivePhysRegs &Redefs)
Behaves like LiveRegUnits::StepForward() but also adds implicit uses to all values defined in MI whic...
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
std::pair< iterator, bool > insert(const ValueT &Val)
insert - Attempts to insert a new element.
static cl::opt< bool > DisableDiamond("disable-ifcvt-diamond", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableForkedDiamond("disable-ifcvt-forked-diamond", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableTriangleFR("disable-ifcvt-triangle-false-rev", cl::init(false), cl::Hidden)
size_type count(const KeyT &Key) const
count - Returns 1 if this set contains an element identified by Key, 0 otherwise. ...
iterator getFirstNonDebugInstr()
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 SubsumesPredicate(ArrayRef< MachineOperand > Pred1, ArrayRef< MachineOperand > Pred2) const override
Returns true if the first specified predicate subsumes the second, e.g.
MIBundleOperands - Iterate over all operands in a bundle of machine instructions. ...
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
MachineBlockFrequencyInfo pass uses BlockFrequencyInfoImpl implementation to estimate machine basic b...
LLVM_NODISCARD detail::scope_exit< typename std::decay< Callable >::type > make_scope_exit(Callable &&F)
FunctionPass * createIfConverter(std::function< bool(const MachineFunction &)> Ftor)
void setIsDead(bool Val=true)
static cl::opt< bool > DisableSimple("disable-ifcvt-simple", cl::init(false), cl::Hidden)
static BranchProbability getOne()
iterator_range< mop_iterator > operands()
iterator_range< succ_iterator > successors()
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...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, const TargetRegisterInfo *tri, MachineModuleInfo *mmi, MachineLoopInfo *mli=nullptr, bool AfterPlacement=false)
OptimizeFunction - Perhaps branch folding, tail merging and other CFG optimizations on the given func...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Provide an instruction scheduling machine model to CodeGen passes.
const HexagonInstrInfo * TII
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Reg
All possible values of the reg field in the ModR/M byte.
void initializeIfConverterPass(PassRegistry &)
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
LLVM_NODISCARD bool empty() const
bool PredicateInstruction(MachineInstr &MI, ArrayRef< MachineOperand > Cond) const override
Convert the instruction into a predicated instruction.
virtual unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const
Insert branch code into the end of the specified MachineBasicBlock.
unsigned getNumRegs() const
Return the number of registers this target has (useful for sizing arrays holding per register informa...
const HexagonRegisterInfo & getRegisterInfo() const
HexagonInstrInfo specifics.
Function Alias Analysis false
std::vector< MachineBasicBlock * >::iterator pred_iterator
static MachineBasicBlock * getNextBlock(MachineBasicBlock &MBB)
Returns the next block in the function blocks ordering.
reverse_iterator rbegin()
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
MCRegisterInfo base class - We assume that the target defines a static array of MCRegisterDesc object...
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
bool isDebugValue() const
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...
static cl::opt< bool > DisableTriangleR("disable-ifcvt-triangle-rev", cl::init(false), cl::Hidden)
initializer< Ty > init(const Ty &Val)
static MachineBasicBlock * findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB)
BB has a fallthrough. Find its 'false' successor given its 'true' successor.
* if(!EatIfPresent(lltok::kw_thread_local)) return false
ParseOptionalThreadLocal := /*empty.
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator begin()
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
static cl::opt< bool > DisableTriangleF("disable-ifcvt-triangle-false", cl::init(false), cl::Hidden)
Represent the analysis usage information of a pass.
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...
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
bool contains(unsigned Reg) const
Returns true if register Reg is contained in the set.
static const unsigned End
FunctionPass class - This class is used to implement most global optimizations.
self_iterator getIterator()
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
void setUniverse(unsigned U)
setUniverse - Set the universe size which determines the largest key the set can hold.
iterator_range< pred_iterator > predecessors()
succ_iterator succ_begin()
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
MCSubRegIterator enumerates all sub-registers of Reg.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isPredicated(const MachineInstr &MI) const override
Returns true if the instruction is already predicated.
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
bool isRegMask() const
isRegMask - Tests if this is a MO_RegisterMask operand.
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Iterator for intrusive lists based on ilist_node.
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
auto find(R &&Range, const T &Val) -> decltype(std::begin(Range))
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly...
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
CloneMachineInstr - Create a new MachineInstr which is a copy of the 'Orig' instruction, identical in all ways except the instruction has no parent, prev, or next.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
static cl::opt< bool > DisableTriangle("disable-ifcvt-triangle", cl::init(false), cl::Hidden)
virtual const TargetLowering * getTargetLowering() const
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
bool isSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB is a successor of this block.
bool isPredicable(MachineInstr &MI) const override
Return true if the specified instruction can be predicated.
static bool MaySpeculate(const MachineInstr &MI, SmallSet< unsigned, 4 > &LaterRedefs)
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...
static void RemoveKills(MachineInstr &MI, const LivePhysRegs &DontKill)
Remove kill flags from operands with a registers in the DontKill set.
static cl::opt< int > IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden)
IterT skipDebugInstructionsBackward(IterT It, IterT Begin)
Decrement It until it points to a non-debug instruction or to Begin and return the resulting iterator...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
unsigned removeBranch(MachineBasicBlock &MBB, int *BytesRemoved=nullptr) const override
Remove the branching code at the end of the specific MBB.
Maximum length of the test input If
bool isPredicated(MCInstrInfo const &MCII, MCInst const &MCI)
IterT skipDebugInstructionsForward(IterT It, IterT End)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator...
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
MachineFunctionProperties & set(Property P)
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
bool hasAddressTaken() const
Test whether this block is potentially the target of an indirect branch.
LLVM_ATTRIBUTE_ALWAYS_INLINE iterator end()
static cl::opt< int > IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden)
A set of live physical registers with functions to track liveness when walking backward/forward throu...
static cl::opt< bool > IfCvtBranchFold("ifcvt-branch-fold", cl::init(true), cl::Hidden)
char & IfConverterID
IfConverter - This pass performs machine code if conversion.
static cl::opt< bool > DisableSimpleF("disable-ifcvt-simple-false", cl::init(false), cl::Hidden)
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
unsigned getReg() const
getReg - Returns the register number.
bool isValid() const
isValid - Returns true until all the operands have been visited.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
virtual const TargetInstrInfo * getInstrInfo() const
static void InsertUncondBranch(MachineBasicBlock &MBB, MachineBasicBlock &ToMBB, const TargetInstrInfo *TII)
Inserts an unconditional branch from MBB to ToMBB.
This class keeps track of branch frequencies of newly created blocks and tail-merged blocks...
print Print MemDeps of function
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
static BranchProbability getZero()
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
unsigned pred_size() const
Properties which a MachineFunction may have at a given point in time.
This file describes how to lower LLVM code to machine code.
static void verifySameBranchInstructions(MachineBasicBlock *MBB1, MachineBasicBlock *MBB2)
static cl::opt< int > IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden)
BranchProbability getCompl() const
static void shrinkInclusiveRange(MachineBasicBlock::iterator &Begin, MachineBasicBlock::iterator &It, bool &Empty)
Shrink the provided inclusive range by one instruction.