14 #define DEBUG_TYPE "ifcvt"
61 STATISTIC(NumSimple,
"Number of simple if-conversions performed");
62 STATISTIC(NumSimpleFalse,
"Number of simple (F) if-conversions performed");
63 STATISTIC(NumTriangle,
"Number of triangle if-conversions performed");
64 STATISTIC(NumTriangleRev,
"Number of triangle (R) if-conversions performed");
65 STATISTIC(NumTriangleFalse,
"Number of triangle (F) if-conversions performed");
66 STATISTIC(NumTriangleFRev,
"Number of triangle (F/R) if-conversions performed");
67 STATISTIC(NumDiamonds,
"Number of diamond if-conversions performed");
68 STATISTIC(NumIfConvBBs,
"Number of if-converted blocks");
69 STATISTIC(NumDupBBs,
"Number of duplicated blocks");
70 STATISTIC(NumUnpred,
"Number of true blocks of diamonds unpredicated");
110 bool IsBeingAnalyzed : 1;
113 bool IsBrAnalyzable : 1;
114 bool HasFallThrough : 1;
115 bool IsUnpredicable : 1;
116 bool CannotBeCopied : 1;
117 bool ClobbersPred : 1;
118 unsigned NonPredSize;
126 BBInfo() : IsDone(
false), IsBeingAnalyzed(
false),
129 CannotBeCopied(
false), ClobbersPred(
false), NonPredSize(0),
130 ExtraCost(0), ExtraCost2(0), BB(0), TrueBB(0), FalseBB(0) {}
147 bool NeedSubsumption;
150 IfcvtToken(BBInfo &b, IfcvtKind k,
bool s,
unsigned d,
unsigned d2 = 0)
151 : BBI(b),
Kind(k), NeedSubsumption(s), NumDups(d), NumDups2(d2) {}
156 std::vector<BBInfo> BBAnalysis;
185 bool ReverseBranchCondition(BBInfo &BBI);
186 bool ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
188 bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
189 bool FalseBranch,
unsigned &Dups,
191 bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
192 unsigned &Dups1,
unsigned &Dups2)
const;
193 void ScanInstructions(BBInfo &BBI);
195 std::vector<IfcvtToken*> &Tokens);
197 bool isTriangle =
false,
bool RevBranch =
false);
198 void AnalyzeBlocks(
MachineFunction &MF, std::vector<IfcvtToken*> &Tokens);
200 void RemoveExtraEdges(BBInfo &BBI);
201 bool IfConvertSimple(BBInfo &BBI, IfcvtKind
Kind);
202 bool IfConvertTriangle(BBInfo &BBI, IfcvtKind
Kind);
203 bool IfConvertDiamond(BBInfo &BBI, IfcvtKind
Kind,
204 unsigned NumDups1,
unsigned NumDups2);
205 void PredicateBlock(BBInfo &BBI,
209 void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
211 bool IgnoreBr =
false);
212 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges =
true);
215 unsigned Cycle,
unsigned Extra,
222 unsigned TCycle,
unsigned TExtra,
224 unsigned FCycle,
unsigned FExtra,
226 return TCycle > 0 && FCycle > 0 &&
232 bool blockAlwaysFallThrough(BBInfo &BBI)
const {
233 return BBI.IsBrAnalyzable && BBI.TrueBB == NULL;
237 static bool IfcvtTokenCmp(IfcvtToken *C1, IfcvtToken *C2) {
238 int Incr1 = (C1->Kind == ICDiamond)
239 ? -(
int)(C1->NumDups + C1->NumDups2) : (
int)C1->NumDups;
240 int Incr2 = (C2->Kind == ICDiamond)
241 ? -(
int)(C2->NumDups + C2->NumDups2) : (
int)C2->NumDups;
244 else if (Incr1 == Incr2) {
246 if (C1->NeedSubsumption ==
false && C2->NeedSubsumption ==
true)
248 else if (C1->NeedSubsumption == C2->NeedSubsumption) {
250 if ((
unsigned)C1->Kind < (
unsigned)C2->Kind)
252 else if (C1->Kind == C2->Kind)
253 return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
270 TLI = MF.getTarget().getTargetLowering();
271 TII = MF.getTarget().getInstrInfo();
273 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
274 MRI = &MF.getRegInfo();
280 if (!
TII)
return false;
282 PreRegAlloc = MRI->isSSA();
284 bool BFChange =
false;
290 getAnalysisIfAvailable<MachineModuleInfo>());
293 DEBUG(
dbgs() <<
"\nIfcvt: function (" << ++FnNum <<
") \'"
294 << MF.getName() <<
"\'");
303 BBAnalysis.resize(MF.getNumBlockIDs());
305 std::vector<IfcvtToken*> Tokens;
307 unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
308 NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
313 AnalyzeBlocks(MF, Tokens);
314 while (!Tokens.empty()) {
315 IfcvtToken *Token = Tokens.back();
317 BBInfo &BBI = Token->BBI;
318 IfcvtKind
Kind = Token->Kind;
319 unsigned NumDups = Token->NumDups;
320 unsigned NumDups2 = Token->NumDups2;
327 BBI.IsEnqueued =
false;
331 BBI.IsEnqueued =
false;
337 case ICSimpleFalse: {
338 bool isFalse = Kind == ICSimpleFalse;
340 DEBUG(
dbgs() <<
"Ifcvt (Simple" << (Kind == ICSimpleFalse ?
342 <<
"): BB#" << BBI.BB->getNumber() <<
" ("
343 << ((Kind == ICSimpleFalse)
344 ? BBI.FalseBB->getNumber()
345 : BBI.TrueBB->getNumber()) <<
") ");
346 RetVal = IfConvertSimple(BBI, Kind);
347 DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
349 if (isFalse) ++NumSimpleFalse;
356 case ICTriangleFalse:
357 case ICTriangleFRev: {
358 bool isFalse = Kind == ICTriangleFalse;
359 bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
369 DEBUG(
dbgs() <<
"): BB#" << BBI.BB->getNumber() <<
" (T:"
370 << BBI.TrueBB->getNumber() <<
",F:"
371 << BBI.FalseBB->getNumber() <<
") ");
372 RetVal = IfConvertTriangle(BBI, Kind);
373 DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
376 if (isRev) ++NumTriangleFRev;
377 else ++NumTriangleFalse;
379 if (isRev) ++NumTriangleRev;
387 DEBUG(
dbgs() <<
"Ifcvt (Diamond): BB#" << BBI.BB->getNumber() <<
" (T:"
388 << BBI.TrueBB->getNumber() <<
",F:"
389 << BBI.FalseBB->getNumber() <<
") ");
390 RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2);
391 DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
392 if (RetVal) ++NumDiamonds;
399 NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
400 NumTriangleFalse + NumTriangleFRev + NumDiamonds;
407 MadeChange |= Change;
411 while (!Tokens.empty()) {
412 IfcvtToken *Token = Tokens.back();
424 getAnalysisIfAvailable<MachineModuleInfo>());
427 MadeChange |= BFChange;
436 E = BB->
succ_end(); SI != E; ++SI) {
438 if (SuccBB != TrueBB)
446 bool IfConverter::ReverseBranchCondition(BBInfo &BBI) {
471 bool IfConverter::ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
474 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
477 if (TrueBBI.IsBrAnalyzable)
480 if (TrueBBI.BB->pred_size() > 1) {
481 if (TrueBBI.CannotBeCopied ||
485 Dups = TrueBBI.NonPredSize;
497 bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
498 bool FalseBranch,
unsigned &Dups,
501 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
504 if (TrueBBI.BB->pred_size() > 1) {
505 if (TrueBBI.CannotBeCopied)
508 unsigned Size = TrueBBI.NonPredSize;
509 if (TrueBBI.IsBrAnalyzable) {
510 if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
515 ? TrueBBI.TrueBB : TrueBBI.FalseBB;
527 if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
529 if (++I == TrueBBI.BB->getParent()->end())
533 return TExit && TExit == FalseBBI.BB;
538 bool IfConverter::ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
539 unsigned &Dups1,
unsigned &Dups2)
const {
541 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
542 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
548 if (!TT && blockAlwaysFallThrough(TrueBBI))
550 if (!FT && blockAlwaysFallThrough(FalseBBI))
554 if (TT == NULL && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
556 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
560 if (TrueBBI.FalseBB || FalseBBI.FalseBB ||
561 (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred))
569 while (TIB != TIE && FIB != FIE) {
571 if (TIB->isDebugValue()) {
572 while (TIB != TIE && TIB->isDebugValue())
577 if (FIB->isDebugValue()) {
578 while (FIB != FIE && FIB->isDebugValue())
583 if (!TIB->isIdenticalTo(FIB))
594 if (!TIE->isBranch())
599 if (!FIE->isBranch())
605 if (TIB == TIE || FIB == FIE)
609 while (TIE != TIB && FIE != FIB) {
611 if (TIE->isDebugValue()) {
612 while (TIE != TIB && TIE->isDebugValue())
617 if (FIE->isDebugValue()) {
618 while (FIE != FIB && FIE->isDebugValue())
623 if (!TIE->isIdenticalTo(FIE))
638 void IfConverter::ScanInstructions(BBInfo &BBI) {
642 bool AlreadyPredicated = !BBI.Predicate.empty();
644 BBI.TrueBB = BBI.FalseBB = NULL;
648 BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB == NULL;
650 if (BBI.BrCond.size()) {
657 BBI.IsUnpredicable =
true;
666 BBI.ClobbersPred =
false;
669 if (I->isDebugValue())
672 if (I->isNotDuplicable())
673 BBI.CannotBeCopied =
true;
676 bool isCondBr = BBI.IsBrAnalyzable && I->isConditionalBranch();
684 unsigned ExtraPredCost =
TII->getPredicationCost(&*I);
685 unsigned NumCycles = SchedModel.computeInstrLatency(&*I,
false);
687 BBI.ExtraCost += NumCycles-1;
688 BBI.ExtraCost2 += ExtraPredCost;
689 }
else if (!AlreadyPredicated) {
693 BBI.IsUnpredicable =
true;
697 if (BBI.ClobbersPred && !isPredicated) {
702 BBI.IsUnpredicable =
true;
708 std::vector<MachineOperand> PredDefs;
710 BBI.ClobbersPred =
true;
713 BBI.IsUnpredicable =
true;
721 bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
723 bool isTriangle,
bool RevBranch) {
725 if (BBI.IsDone || BBI.IsUnpredicable)
733 if (BBI.BrCond.size()) {
756 std::vector<IfcvtToken*> &Tokens) {
757 BBInfo &BBI = BBAnalysis[BB->
getNumber()];
759 if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed)
763 BBI.IsBeingAnalyzed =
true;
765 ScanInstructions(BBI);
769 if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
770 BBI.IsBeingAnalyzed =
false;
771 BBI.IsAnalyzed =
true;
776 if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
777 BBI.IsBeingAnalyzed =
false;
778 BBI.IsAnalyzed =
true;
784 BBI.IsBeingAnalyzed =
false;
785 BBI.IsAnalyzed =
true;
789 BBInfo &TrueBBI = AnalyzeBlock(BBI.TrueBB, Tokens);
790 BBInfo &FalseBBI = AnalyzeBlock(BBI.FalseBB, Tokens);
792 if (TrueBBI.IsDone && FalseBBI.IsDone) {
793 BBI.IsBeingAnalyzed =
false;
794 BBI.IsAnalyzed =
true;
803 bool TNeedSub = !TrueBBI.Predicate.empty();
804 bool FNeedSub = !FalseBBI.Predicate.empty();
805 bool Enqueued =
false;
809 if (CanRevCond && ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2) &&
810 MeetIfcvtSizeLimit(*TrueBBI.BB, (TrueBBI.NonPredSize - (Dups + Dups2) +
811 TrueBBI.ExtraCost), TrueBBI.ExtraCost2,
812 *FalseBBI.BB, (FalseBBI.NonPredSize - (Dups + Dups2) +
813 FalseBBI.ExtraCost),FalseBBI.ExtraCost2,
815 FeasibilityAnalysis(TrueBBI, BBI.BrCond) &&
816 FeasibilityAnalysis(FalseBBI, RevCond)) {
825 Tokens.push_back(
new IfcvtToken(BBI, ICDiamond, TNeedSub|FNeedSub, Dups,
830 if (ValidTriangle(TrueBBI, FalseBBI,
false, Dups, Prediction) &&
831 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
832 TrueBBI.ExtraCost2, Prediction) &&
833 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true)) {
841 Tokens.push_back(
new IfcvtToken(BBI, ICTriangle, TNeedSub, Dups));
845 if (ValidTriangle(TrueBBI, FalseBBI,
true, Dups, Prediction) &&
846 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
847 TrueBBI.ExtraCost2, Prediction) &&
848 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true,
true)) {
849 Tokens.push_back(
new IfcvtToken(BBI, ICTriangleRev, TNeedSub, Dups));
853 if (ValidSimple(TrueBBI, Dups, Prediction) &&
854 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
855 TrueBBI.ExtraCost2, Prediction) &&
856 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
864 Tokens.push_back(
new IfcvtToken(BBI, ICSimple, TNeedSub, Dups));
870 if (ValidTriangle(FalseBBI, TrueBBI,
false, Dups,
872 MeetIfcvtSizeLimit(*FalseBBI.BB,
873 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
874 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
875 FeasibilityAnalysis(FalseBBI, RevCond,
true)) {
876 Tokens.push_back(
new IfcvtToken(BBI, ICTriangleFalse, FNeedSub, Dups));
880 if (ValidTriangle(FalseBBI, TrueBBI,
true, Dups,
882 MeetIfcvtSizeLimit(*FalseBBI.BB,
883 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
884 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
885 FeasibilityAnalysis(FalseBBI, RevCond,
true,
true)) {
886 Tokens.push_back(
new IfcvtToken(BBI, ICTriangleFRev, FNeedSub, Dups));
890 if (ValidSimple(FalseBBI, Dups, Prediction.
getCompl()) &&
891 MeetIfcvtSizeLimit(*FalseBBI.BB,
892 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
893 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
894 FeasibilityAnalysis(FalseBBI, RevCond)) {
895 Tokens.push_back(
new IfcvtToken(BBI, ICSimpleFalse, FNeedSub, Dups));
900 BBI.IsEnqueued = Enqueued;
901 BBI.IsBeingAnalyzed =
false;
902 BBI.IsAnalyzed =
true;
909 std::vector<IfcvtToken*> &Tokens) {
912 AnalyzeBlock(BB, Tokens);
916 std::stable_sort(Tokens.begin(), Tokens.end(), IfcvtTokenCmp);
930 if (I == E || !I->empty() || !PI->isSuccessor(I))
942 E = BB->
pred_end(); PI != E; ++PI) {
943 BBInfo &PBBI = BBAnalysis[(*PI)->getNumber()];
944 if (PBBI.IsDone || PBBI.BB == BB)
946 PBBI.IsAnalyzed =
false;
947 PBBI.IsEnqueued =
false;
962 void IfConverter::RemoveExtraEdges(BBInfo &BBI) {
966 BBI.BB->CorrectExtraCFGEdges(TBB, FBB, !Cond.
empty());
974 if (!Ops->isReg() || !Ops->isKill())
976 unsigned Reg = Ops->getReg();
982 if (!Ops->isReg() || !Ops->isDef())
984 unsigned Reg = Ops->getReg();
985 if (Reg == 0 || Redefs.
contains(Reg, *TRI))
1002 if (!O->isReg() || !O->isKill())
1004 if (DontKill.
contains(O->getReg(), MCRI))
1005 O->setIsKill(
false);
1017 for ( ; I != E; ++
I)
1023 bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind
Kind) {
1024 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1025 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1026 BBInfo *CvtBBI = &TrueBBI;
1027 BBInfo *NextBBI = &FalseBBI;
1030 if (Kind == ICSimpleFalse)
1033 if (CvtBBI->IsDone ||
1034 (CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1)) {
1036 BBI.IsAnalyzed =
false;
1037 CvtBBI->IsAnalyzed =
false;
1041 if (CvtBBI->BB->hasAddressTaken())
1045 if (Kind == ICSimpleFalse)
1052 Redefs.addLiveIns(CvtBBI->BB, *TRI);
1053 Redefs.addLiveIns(NextBBI->BB, *TRI);
1058 DontKill.addLiveIns(NextBBI->BB, *TRI);
1060 if (CvtBBI->BB->pred_size() > 1) {
1064 CopyAndPredicateBlock(BBI, *CvtBBI, Cond);
1068 BBI.BB->removeSuccessor(CvtBBI->BB);
1070 RemoveKills(CvtBBI->BB->begin(), CvtBBI->BB->end(), DontKill, *TRI);
1071 PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond);
1075 MergeBlocks(BBI, *CvtBBI);
1078 bool IterIfcvt =
true;
1081 BBI.HasFallThrough =
false;
1095 RemoveExtraEdges(BBI);
1100 InvalidatePreds(BBI.BB);
1101 CvtBBI->IsDone =
true;
1109 bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1110 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1111 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1112 BBInfo *CvtBBI = &TrueBBI;
1113 BBInfo *NextBBI = &FalseBBI;
1117 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1120 if (CvtBBI->IsDone ||
1121 (CvtBBI->CannotBeCopied && CvtBBI->BB->pred_size() > 1)) {
1123 BBI.IsAnalyzed =
false;
1124 CvtBBI->IsAnalyzed =
false;
1128 if (CvtBBI->BB->hasAddressTaken())
1132 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1136 if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
1137 if (ReverseBranchCondition(*CvtBBI)) {
1141 E = CvtBBI->BB->pred_end(); PI != E; ++PI) {
1145 BBInfo &PBBI = BBAnalysis[PBB->
getNumber()];
1146 if (PBBI.IsEnqueued) {
1147 PBBI.IsAnalyzed =
false;
1148 PBBI.IsEnqueued =
false;
1157 Redefs.addLiveIns(CvtBBI->BB, *TRI);
1158 Redefs.addLiveIns(NextBBI->BB, *TRI);
1162 bool HasEarlyExit = CvtBBI->FalseBB != NULL;
1163 if (CvtBBI->BB->pred_size() > 1) {
1167 CopyAndPredicateBlock(BBI, *CvtBBI, Cond,
true);
1171 BBI.BB->removeSuccessor(CvtBBI->BB);
1175 PredicateBlock(*CvtBBI, CvtBBI->BB->end(), Cond);
1179 MergeBlocks(BBI, *CvtBBI,
false);
1185 CvtBBI->BrCond.end());
1189 BBI.BB->addSuccessor(CvtBBI->FalseBB);
1194 bool FalseBBDead =
false;
1195 bool IterIfcvt =
true;
1197 if (!isFallThrough) {
1201 if (!HasEarlyExit &&
1202 NextBBI->BB->pred_size() == 1 && !NextBBI->HasFallThrough &&
1203 !NextBBI->BB->hasAddressTaken()) {
1204 MergeBlocks(BBI, *NextBBI);
1208 BBI.HasFallThrough =
false;
1215 RemoveExtraEdges(BBI);
1220 InvalidatePreds(BBI.BB);
1221 CvtBBI->IsDone =
true;
1223 NextBBI->IsDone =
true;
1231 bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
1232 unsigned NumDups1,
unsigned NumDups2) {
1233 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1234 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1238 if (blockAlwaysFallThrough(TrueBBI))
1239 TailBB = FalseBBI.TrueBB;
1240 assert((TailBB || !TrueBBI.IsBrAnalyzable) &&
"Unexpected!");
1243 if (TrueBBI.IsDone || FalseBBI.IsDone ||
1244 TrueBBI.BB->pred_size() > 1 ||
1245 FalseBBI.BB->pred_size() > 1) {
1247 BBI.IsAnalyzed =
false;
1248 TrueBBI.IsAnalyzed =
false;
1249 FalseBBI.IsAnalyzed =
false;
1253 if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
1260 BBInfo *BBI1 = &TrueBBI;
1261 BBInfo *BBI2 = &FalseBBI;
1269 bool DoSwap =
false;
1270 if (TrueBBI.ClobbersPred && !FalseBBI.ClobbersPred)
1272 else if (TrueBBI.ClobbersPred == FalseBBI.ClobbersPred) {
1273 if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
1287 Redefs.addLiveIns(BBI1->BB, *TRI);
1295 while (DI1 != DIE1 && DI1->isDebugValue())
1297 while (DI2 != DIE2 && DI2->isDebugValue())
1299 BBI1->NonPredSize -= NumDups1;
1300 BBI2->NonPredSize -= NumDups1;
1304 for (
unsigned i = 0; i < NumDups1; ++DI1) {
1305 if (!DI1->isDebugValue())
1308 while (NumDups1 != 0) {
1310 if (!DI2->isDebugValue())
1320 DontKill.stepBackward(*I, *TRI);
1325 Redefs.stepForward(*I, *TRI);
1327 BBI.BB->splice(BBI.BB->end(), BBI1->BB, BBI1->BB->begin(), DI1);
1328 BBI2->BB->erase(BBI2->BB->begin(), DI2);
1332 DI1 = BBI1->BB->end();
1333 for (
unsigned i = 0; i != NumDups2; ) {
1336 assert (DI1 != BBI1->BB->begin());
1339 if (!DI1->isDebugValue())
1342 BBI1->BB->erase(DI1, BBI1->BB->end());
1346 RemoveKills(BBI1->BB->begin(), BBI1->BB->end(), DontKill, *TRI);
1350 DI2 = BBI2->BB->end();
1351 while (NumDups2 != 0) {
1354 assert (DI2 != BBI2->BB->begin());
1357 if (!DI2->isDebugValue())
1371 if (
TII->isProfitableToUnpredicate(*BBI1->BB, *BBI2->BB)) {
1373 if (FI->isDebugValue())
1376 for (
unsigned i = 0, e = FI->getNumOperands(); i != e; ++i) {
1385 }
else if (!RedefsByFalse.
count(Reg)) {
1390 ExtUses.
insert(*SubRegs);
1394 for (
unsigned i = 0, e = Defs.
size(); i != e; ++i) {
1395 unsigned Reg = Defs[i];
1396 if (!ExtUses.
count(Reg)) {
1399 RedefsByFalse.
insert(*SubRegs);
1406 PredicateBlock(*BBI1, BBI1->BB->end(), *Cond1, &RedefsByFalse);
1409 PredicateBlock(*BBI2, DI2, *Cond2);
1412 MergeBlocks(BBI, *BBI1, TailBB == 0);
1413 MergeBlocks(BBI, *BBI2, TailBB == 0);
1420 BBInfo &TailBBI = BBAnalysis[TailBB->
getNumber()];
1421 bool CanMergeTail = !TailBBI.HasFallThrough &&
1422 !TailBBI.BB->hasAddressTaken();
1425 unsigned NumPreds = TailBB->
pred_size();
1427 CanMergeTail =
false;
1428 else if (NumPreds == 1 && CanMergeTail) {
1430 if (*PI != BBI1->BB && *PI != BBI2->BB)
1431 CanMergeTail =
false;
1434 MergeBlocks(BBI, TailBBI);
1435 TailBBI.IsDone =
true;
1437 BBI.BB->addSuccessor(TailBB);
1439 BBI.HasFallThrough =
false;
1446 BBI.BB->removeSuccessor(BBI1->BB);
1447 BBI.BB->removeSuccessor(BBI2->BB);
1448 RemoveExtraEdges(BBI);
1451 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
1452 InvalidatePreds(BBI.BB);
1469 unsigned Reg = MO.
getReg();
1481 void IfConverter::PredicateBlock(BBInfo &BBI,
1485 bool AnyUnpred =
false;
1486 bool MaySpec = LaterRedefs != 0;
1502 dbgs() <<
"Unable to predicate " << *I <<
"!\n";
1512 std::copy(Cond.
begin(), Cond.
end(), std::back_inserter(BBI.Predicate));
1514 BBI.IsAnalyzed =
false;
1515 BBI.NonPredSize = 0;
1524 void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
1530 E = FromBBI.BB->end(); I != E; ++
I) {
1532 if (IgnoreBr && I->isBranch())
1536 ToBBI.BB->insert(ToBBI.BB->end(),
MI);
1537 ToBBI.NonPredSize++;
1538 unsigned ExtraPredCost =
TII->getPredicationCost(&*I);
1539 unsigned NumCycles = SchedModel.computeInstrLatency(&*I,
false);
1541 ToBBI.ExtraCost += NumCycles-1;
1542 ToBBI.ExtraCost2 += ExtraPredCost;
1547 dbgs() <<
"Unable to predicate " << *I <<
"!\n";
1558 if (!DontKill.empty())
1563 std::vector<MachineBasicBlock *> Succs(FromBBI.BB->succ_begin(),
1564 FromBBI.BB->succ_end());
1568 for (
unsigned i = 0, e = Succs.size(); i != e; ++i) {
1571 if (Succ == FallThrough)
1573 ToBBI.BB->addSuccessor(Succ);
1577 std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),
1578 std::back_inserter(ToBBI.Predicate));
1579 std::copy(Cond.
begin(), Cond.
end(), std::back_inserter(ToBBI.Predicate));
1581 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
1582 ToBBI.IsAnalyzed =
false;
1592 void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges) {
1593 assert(!FromBBI.BB->hasAddressTaken() &&
1594 "Removing a BB whose address is taken!");
1596 ToBBI.BB->splice(ToBBI.BB->end(),
1597 FromBBI.BB, FromBBI.BB->begin(), FromBBI.BB->end());
1599 std::vector<MachineBasicBlock *> Succs(FromBBI.BB->succ_begin(),
1600 FromBBI.BB->succ_end());
1604 for (
unsigned i = 0, e = Succs.size(); i != e; ++i) {
1607 if (Succ == FallThrough)
1609 FromBBI.BB->removeSuccessor(Succ);
1610 if (AddEdges && !ToBBI.BB->isSuccessor(Succ))
1611 ToBBI.BB->addSuccessor(Succ);
1615 if (NBB && !FromBBI.BB->isSuccessor(NBB))
1616 FromBBI.BB->addSuccessor(NBB);
1618 std::copy(FromBBI.Predicate.begin(), FromBBI.Predicate.end(),
1619 std::back_inserter(ToBBI.Predicate));
1620 FromBBI.Predicate.clear();
1622 ToBBI.NonPredSize += FromBBI.NonPredSize;
1623 ToBBI.ExtraCost += FromBBI.ExtraCost;
1624 ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
1625 FromBBI.NonPredSize = 0;
1626 FromBBI.ExtraCost = 0;
1627 FromBBI.ExtraCost2 = 0;
1629 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
1630 ToBBI.HasFallThrough = FromBBI.HasFallThrough;
1631 ToBBI.IsAnalyzed =
false;
1632 FromBBI.IsAnalyzed =
false;
virtual bool ReverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const
void push_back(const T &Elt)
const MachineFunction * getParent() const
virtual unsigned RemoveBranch(MachineBasicBlock &MBB) const
MachineInstr * getParent()
static PassRegistry * getPassRegistry()
virtual bool AnalyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
static cl::opt< bool > DisableDiamond("disable-ifcvt-diamond", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableTriangleFR("disable-ifcvt-triangle-false-rev", cl::init(false), cl::Hidden)
const MCSchedModel * getSchedModel() const
virtual bool isPredicated(const MachineInstr *MI) const
static cl::opt< bool > DisableSimple("disable-ifcvt-simple", cl::init(false), cl::Hidden)
STATISTIC(NumSimple,"Number of simple if-conversions performed")
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
bool contains(unsigned Reg, const MCRegisterInfo &MCRI) const
Returns true if register Reg (or one of its super register) is contained in the set.
Provide an instruction scheduling machine model to CodeGen passes.
const HexagonInstrInfo * TII
INITIALIZE_PASS(DeadMachineInstructionElim,"dead-mi-elimination","Remove dead machine instructions", false, false) bool DeadMachineInstructionElim bool SawStore
#define llvm_unreachable(msg)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
static MachineBasicBlock * getNextBlock(MachineBasicBlock *BB)
std::vector< MachineBasicBlock * >::iterator succ_iterator
void initializeIfConverterPass(PassRegistry &)
ID
LLVM Calling Convention Representation.
unsigned getNumOperands() const
bool LLVM_ATTRIBUTE_UNUSED_RESULT empty() const
std::vector< MachineBasicBlock * >::iterator pred_iterator
const MachineBasicBlock * getParent() const
bool isDebugValue() const
static cl::opt< bool > DisableTriangleR("disable-ifcvt-triangle-rev", cl::init(false), cl::Hidden)
bundle_iterator< MachineInstr, instr_iterator > iterator
initializer< Ty > init(const Ty &Val)
virtual bool isProfitableToDupForIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, const BranchProbability &Probability) const
static MachineBasicBlock * findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB)
* if(!EatIfPresent(lltok::kw_thread_local)) return false
const MachineOperand & getOperand(unsigned i) const
static cl::opt< bool > DisableTriangleF("disable-ifcvt-triangle-false", cl::init(false), cl::Hidden)
ItTy next(ItTy it, Dist n)
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl< MachineOperand > &Cond, DebugLoc DL) const
static void InsertUncondBranch(MachineBasicBlock *BB, MachineBasicBlock *ToBB, const TargetInstrInfo *TII)
static void RemoveKills(MachineInstr &MI, const LiveRegUnits &DontKill, const MCRegisterInfo &MCRI)
succ_iterator succ_begin()
pred_iterator pred_begin()
virtual bool PredicateInstruction(MachineInstr *MI, const SmallVectorImpl< MachineOperand > &Cond) const
MachineInstr * CloneMachineInstr(const MachineInstr *Orig)
static cl::opt< bool > DisableTriangle("disable-ifcvt-triangle", cl::init(false), cl::Hidden)
Predicate
Predicate - These are "(BI << 5) | BO" for various predicates.
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
static cl::opt< int > IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden)
virtual unsigned InsertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, const SmallVectorImpl< MachineOperand > &Cond, DebugLoc DL) const
raw_ostream & dbgs()
dbgs - Return a circular-buffered debug stream.
void addReg(unsigned Reg, const MCRegisterInfo &MCRI)
Adds a register to the set.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
bool isSafeToMove(const TargetInstrInfo *TII, AliasAnalysis *AA, bool &SawStore) const
bool count(const T &V) const
count - Return true if the element is in the set.
static bool MaySpeculate(const MachineInstr *MI, SmallSet< unsigned, 4 > &LaterRedefs, const TargetInstrInfo *TII)
bundle_iterator< const MachineInstr, const_instr_iterator > const_iterator
static bool canFallThroughTo(MachineBasicBlock *BB, MachineBasicBlock *ToBB)
static cl::opt< int > IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden)
virtual void getAnalysisUsage(AnalysisUsage &AU) const
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)
virtual bool isPredicable(MachineInstr *MI) const
unsigned getReg() const
getReg - Returns the register number.
virtual const HexagonRegisterInfo & getRegisterInfo() const
bool isValid() const
isValid - Returns true until all the operands have been visited.
std::reverse_iterator< iterator > reverse_iterator
BasicBlockListType::iterator iterator
virtual bool SubsumesPredicate(const SmallVectorImpl< MachineOperand > &Pred1, const SmallVectorImpl< MachineOperand > &Pred2) const
const MCRegisterInfo & MRI
bool OptimizeFunction(MachineFunction &MF, const TargetInstrInfo *tii, const TargetRegisterInfo *tri, MachineModuleInfo *mmi)
void removeReg(unsigned Reg, const MCRegisterInfo &MCRI)
Removes a register from the set.
static void UpdatePredRedefs(MachineInstr *MI, LiveRegUnits &Redefs, const TargetRegisterInfo *TRI)
virtual bool DefinesPredicate(MachineInstr *MI, std::vector< MachineOperand > &Pred) const
virtual bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, const BranchProbability &Probability) const
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
unsigned pred_size() const
static cl::opt< int > IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden)
BranchProbability getCompl() const