57#define DEBUG_TYPE "if-converter"
80STATISTIC(NumSimple,
"Number of simple if-conversions performed");
81STATISTIC(NumSimpleFalse,
"Number of simple (F) if-conversions performed");
82STATISTIC(NumTriangle,
"Number of triangle if-conversions performed");
83STATISTIC(NumTriangleRev,
"Number of triangle (R) if-conversions performed");
84STATISTIC(NumTriangleFalse,
"Number of triangle (F) if-conversions performed");
85STATISTIC(NumTriangleFRev,
"Number of triangle (F/R) if-conversions performed");
86STATISTIC(NumDiamonds,
"Number of diamond if-conversions performed");
87STATISTIC(NumForkedDiamonds,
"Number of forked-diamond if-conversions performed");
88STATISTIC(NumIfConvBBs,
"Number of if-converted blocks");
90STATISTIC(NumUnpred,
"Number of true blocks of diamonds unpredicated");
140 bool IsBeingAnalyzed : 1;
143 bool IsBrAnalyzable : 1;
144 bool IsBrReversible : 1;
145 bool HasFallThrough : 1;
146 bool IsUnpredicable : 1;
147 bool CannotBeCopied : 1;
148 bool ClobbersPred : 1;
149 unsigned NonPredSize = 0;
150 unsigned ExtraCost = 0;
151 unsigned ExtraCost2 = 0;
152 MachineBasicBlock *BB =
nullptr;
153 MachineBasicBlock *TrueBB =
nullptr;
154 MachineBasicBlock *FalseBB =
nullptr;
158 BBInfo() : IsDone(
false), IsBeingAnalyzed(
false),
162 ClobbersPred(
false) {}
181 bool NeedSubsumption : 1;
182 bool TClobbersPred : 1;
183 bool FClobbersPred : 1;
185 IfcvtToken(BBInfo &b, IfcvtKind k,
bool s,
unsigned d,
unsigned d2 = 0,
186 bool tc =
false,
bool fc =
false)
187 : BBI(
b), Kind(
k), NumDups(d), NumDups2(d2), NeedSubsumption(s),
188 TClobbersPred(tc), FClobbersPred(fc) {}
193 std::vector<BBInfo> BBAnalysis;
194 TargetSchedModel SchedModel;
196 const TargetLoweringBase *TLI =
nullptr;
197 const TargetInstrInfo *TII =
nullptr;
198 const TargetRegisterInfo *TRI =
nullptr;
199 const MachineBranchProbabilityInfo *MBPI =
nullptr;
200 MachineRegisterInfo *MRI =
nullptr;
204 bool PreRegAlloc =
true;
205 bool MadeChange =
false;
207 std::function<bool(
const MachineFunction &)> PredicateFtor;
212 IfConverter(std::function<
bool(
const MachineFunction &)> Ftor =
nullptr)
213 : MachineFunctionPass(ID), PredicateFtor(std::
move(Ftor)) {}
215 void getAnalysisUsage(AnalysisUsage &AU)
const override {
216 AU.
addRequired<MachineBlockFrequencyInfoWrapperPass>();
217 AU.
addRequired<MachineBranchProbabilityInfoWrapperPass>();
222 bool runOnMachineFunction(MachineFunction &MF)
override;
224 MachineFunctionProperties getRequiredProperties()
const override {
225 return MachineFunctionProperties().setNoVRegs();
229 bool reverseBranchCondition(BBInfo &BBI)
const;
230 bool ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
231 BranchProbability Prediction)
const;
232 bool ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
233 bool FalseBranch,
unsigned &Dups,
234 BranchProbability Prediction)
const;
235 bool CountDuplicatedInstructions(
238 unsigned &Dups1,
unsigned &Dups2,
239 MachineBasicBlock &
TBB, MachineBasicBlock &FBB,
240 bool SkipUnconditionalBranches)
const;
241 bool ValidDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
242 unsigned &Dups1,
unsigned &Dups2,
243 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
244 bool ValidForkedDiamond(BBInfo &TrueBBI, BBInfo &FalseBBI,
245 unsigned &Dups1,
unsigned &Dups2,
246 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const;
247 void AnalyzeBranches(BBInfo &BBI);
248 void ScanInstructions(BBInfo &BBI,
251 bool BranchUnpredicable =
false)
const;
252 bool RescanInstructions(
255 BBInfo &TrueBBI, BBInfo &FalseBBI)
const;
256 void AnalyzeBlock(MachineBasicBlock &
MBB,
257 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
258 bool FeasibilityAnalysis(BBInfo &BBI, SmallVectorImpl<MachineOperand> &Pred,
259 bool isTriangle =
false,
bool RevBranch =
false,
260 bool hasCommonTail =
false);
261 void AnalyzeBlocks(MachineFunction &MF,
262 std::vector<std::unique_ptr<IfcvtToken>> &Tokens);
263 void InvalidatePreds(MachineBasicBlock &
MBB);
264 bool IfConvertSimple(BBInfo &BBI, IfcvtKind Kind);
265 bool IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind);
266 bool IfConvertDiamondCommon(BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
267 unsigned NumDups1,
unsigned NumDups2,
268 bool TClobbersPred,
bool FClobbersPred,
269 bool RemoveBranch,
bool MergeAddEdges);
270 bool IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
271 unsigned NumDups1,
unsigned NumDups2,
272 bool TClobbers,
bool FClobbers);
273 bool IfConvertForkedDiamond(BBInfo &BBI, IfcvtKind Kind,
274 unsigned NumDups1,
unsigned NumDups2,
275 bool TClobbers,
bool FClobbers);
277 SmallVectorImpl<MachineOperand> &
Cond,
278 SmallSet<MCRegister, 4> *LaterRedefs =
nullptr);
279 void CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
280 SmallVectorImpl<MachineOperand> &
Cond,
281 bool IgnoreBr =
false);
282 void MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges =
true);
284 bool MeetIfcvtSizeLimit(MachineBasicBlock &BB,
285 unsigned Cycle,
unsigned Extra,
286 BranchProbability Prediction)
const {
287 return Cycle > 0 && TII->isProfitableToIfCvt(BB,
Cycle, Extra,
291 bool MeetIfcvtSizeLimit(BBInfo &TBBInfo, BBInfo &FBBInfo,
292 MachineBasicBlock &CommBB,
unsigned Dups,
293 BranchProbability Prediction,
bool Forked)
const {
294 const MachineFunction &MF = *TBBInfo.BB->getParent();
301 unsigned Dups1 = 0, Dups2 = 0;
302 if (!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
303 *TBBInfo.BB, *FBBInfo.BB,
307 unsigned BranchBytes = 0;
308 unsigned CommonBytes = 0;
311 for (
auto &
I :
make_range(TBBInfo.BB->begin(), TIB)) {
313 CommonBytes += TII->getInstSizeInBytes(
I);
315 for (
auto &
I :
make_range(FBBInfo.BB->begin(), FIB)) {
317 CommonBytes += TII->getInstSizeInBytes(
I);
324 for (
auto &
I :
make_range(TIE, TBBInfo.BB->end())) {
325 if (
I.isBranch() && TBBInfo.IsBrAnalyzable && !Forked) {
327 BranchBytes += TII->predictBranchSizeForIfCvt(
I);
330 CommonBytes += TII->getInstSizeInBytes(
I);
333 for (
auto &
I :
make_range(FIE, FBBInfo.BB->end())) {
334 if (
I.isBranch() && FBBInfo.IsBrAnalyzable && !Forked) {
336 BranchBytes += TII->predictBranchSizeForIfCvt(
I);
339 CommonBytes += TII->getInstSizeInBytes(
I);
345 BranchBytes += TII->predictBranchSizeForIfCvt(
I);
354 unsigned NumPredicatedInstructions = 0;
356 if (!
I.isDebugInstr()) {
358 NumPredicatedInstructions++;
362 if (!
I.isDebugInstr()) {
364 NumPredicatedInstructions++;
370 if (NumPredicatedInstructions > 15)
375 unsigned ExtraPredicateBytes = TII->extraSizeToPredicateInstructions(
376 MF, NumPredicatedInstructions);
378 LLVM_DEBUG(
dbgs() <<
"MeetIfcvtSizeLimit(BranchBytes=" << BranchBytes
379 <<
", CommonBytes=" << CommonBytes
380 <<
", NumPredicatedInstructions="
381 << NumPredicatedInstructions
382 <<
", ExtraPredicateBytes=" << ExtraPredicateBytes
384 return (BranchBytes + CommonBytes) > ExtraPredicateBytes;
386 unsigned TCycle = TBBInfo.NonPredSize + TBBInfo.ExtraCost - Dups;
387 unsigned FCycle = FBBInfo.NonPredSize + FBBInfo.ExtraCost - Dups;
388 bool Res = TCycle > 0 && FCycle > 0 &&
389 TII->isProfitableToIfCvt(
390 *TBBInfo.BB, TCycle, TBBInfo.ExtraCost2, *FBBInfo.BB,
391 FCycle, FBBInfo.ExtraCost2, Prediction);
393 <<
", FCycle=" << FCycle
394 <<
", TExtra=" << TBBInfo.ExtraCost2 <<
", FExtra="
395 << FBBInfo.ExtraCost2 <<
") = " << Res <<
"\n");
401 bool blockAlwaysFallThrough(BBInfo &BBI)
const {
402 return BBI.IsBrAnalyzable && BBI.TrueBB ==
nullptr;
406 bool blockNeverFallThrough(BBInfo &BBI)
const {
408 if (BBI.IsBrAnalyzable)
409 return !BBI.HasFallThrough;
414 if (
I == BBI.BB->getParent()->end() || !PI->isSuccessor(&*
I))
421 static bool IfcvtTokenCmp(
const std::unique_ptr<IfcvtToken> &C1,
422 const std::unique_ptr<IfcvtToken> &C2) {
423 int Incr1 = (C1->Kind == ICDiamond)
424 ? -(
int)(C1->NumDups + C1->NumDups2) : (int)C1->NumDups;
425 int Incr2 = (C2->Kind == ICDiamond)
426 ? -(int)(C2->NumDups + C2->NumDups2) : (int)C2->NumDups;
429 else if (Incr1 == Incr2) {
431 if (!C1->NeedSubsumption && C2->NeedSubsumption)
433 else if (C1->NeedSubsumption == C2->NeedSubsumption) {
435 if ((
unsigned)C1->Kind < (
unsigned)C2->Kind)
437 else if (C1->Kind == C2->Kind)
438 return C1->BBI.BB->getNumber() < C2->BBI.BB->getNumber();
447char IfConverter::ID = 0;
457 if (skipFunction(MF.getFunction()) || (PredicateFtor && !PredicateFtor(MF)))
461 TLI = ST.getTargetLowering();
462 TII = ST.getInstrInfo();
463 TRI = ST.getRegisterInfo();
465 getAnalysis<MachineBlockFrequencyInfoWrapperPass>().getMBFI());
466 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
468 &getAnalysis<ProfileSummaryInfoWrapperPass>().getPSI();
469 MRI = &MF.getRegInfo();
470 SchedModel.
init(&ST);
472 if (!
TII)
return false;
474 PreRegAlloc =
MRI->isSSA();
476 bool BFChange =
false;
484 << MF.getName() <<
"\'");
493 BBAnalysis.resize(MF.getNumBlockIDs());
495 std::vector<std::unique_ptr<IfcvtToken>> Tokens;
497 unsigned NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle +
498 NumTriangleRev + NumTriangleFalse + NumTriangleFRev + NumDiamonds;
503 AnalyzeBlocks(MF, Tokens);
504 while (!Tokens.empty()) {
505 std::unique_ptr<IfcvtToken> Token = std::move(Tokens.back());
507 BBInfo &BBI = Token->BBI;
508 IfcvtKind Kind = Token->Kind;
509 unsigned NumDups = Token->NumDups;
510 unsigned NumDups2 = Token->NumDups2;
515 BBI.IsEnqueued =
false;
519 BBI.IsEnqueued =
false;
525 case ICSimpleFalse: {
526 bool isFalse = Kind == ICSimpleFalse;
529 << (Kind == ICSimpleFalse ?
" false" :
"")
531 << ((Kind == ICSimpleFalse) ? BBI.FalseBB->getNumber()
532 : BBI.TrueBB->getNumber())
534 RetVal = IfConvertSimple(BBI, Kind);
535 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
537 if (isFalse) ++NumSimpleFalse;
544 case ICTriangleFalse:
545 case ICTriangleFRev: {
546 bool isFalse = Kind == ICTriangleFalse;
547 bool isRev = (Kind == ICTriangleRev || Kind == ICTriangleFRev);
557 <<
" (T:" << BBI.TrueBB->getNumber()
558 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
559 RetVal = IfConvertTriangle(BBI, Kind);
560 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
574 <<
" (T:" << BBI.TrueBB->getNumber()
575 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
576 RetVal = IfConvertDiamond(BBI, Kind, NumDups, NumDups2,
577 Token->TClobbersPred,
578 Token->FClobbersPred);
579 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
580 if (RetVal) ++NumDiamonds;
582 case ICForkedDiamond:
586 <<
" (T:" << BBI.TrueBB->getNumber()
587 <<
",F:" << BBI.FalseBB->getNumber() <<
") ");
588 RetVal = IfConvertForkedDiamond(BBI, Kind, NumDups, NumDups2,
589 Token->TClobbersPred,
590 Token->FClobbersPred);
591 LLVM_DEBUG(
dbgs() << (RetVal ?
"succeeded!" :
"failed!") <<
"\n");
592 if (RetVal) ++NumForkedDiamonds;
596 if (RetVal &&
MRI->tracksLiveness())
601 NumIfCvts = NumSimple + NumSimpleFalse + NumTriangle + NumTriangleRev +
602 NumTriangleFalse + NumTriangleFRev + NumDiamonds;
609 MadeChange |= Change;
620 MadeChange |= BFChange;
628 if (SuccBB != TrueBB)
636bool IfConverter::reverseBranchCondition(BBInfo &BBI)
const {
660bool IfConverter::ValidSimple(BBInfo &TrueBBI,
unsigned &Dups,
661 BranchProbability Prediction)
const {
663 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
666 if (TrueBBI.IsBrAnalyzable)
669 if (TrueBBI.BB->pred_size() > 1) {
670 if (TrueBBI.CannotBeCopied ||
674 Dups = TrueBBI.NonPredSize;
685bool IfConverter::ValidTriangle(BBInfo &TrueBBI, BBInfo &FalseBBI,
686 bool FalseBranch,
unsigned &Dups,
687 BranchProbability Prediction)
const {
689 if (TrueBBI.BB == FalseBBI.BB)
692 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone)
695 if (TrueBBI.BB->pred_size() > 1) {
696 if (TrueBBI.CannotBeCopied)
699 unsigned Size = TrueBBI.NonPredSize;
700 if (TrueBBI.IsBrAnalyzable) {
701 if (TrueBBI.TrueBB && TrueBBI.BrCond.empty())
705 MachineBasicBlock *FExit = FalseBranch
706 ? TrueBBI.TrueBB : TrueBBI.FalseBB;
717 MachineBasicBlock *TExit = FalseBranch ? TrueBBI.FalseBB : TrueBBI.TrueBB;
718 if (!TExit && blockAlwaysFallThrough(TrueBBI)) {
720 if (++
I == TrueBBI.BB->getParent()->end())
724 return TExit && TExit == FalseBBI.BB;
747bool IfConverter::CountDuplicatedInstructions(
752 unsigned &Dups1,
unsigned &Dups2,
753 MachineBasicBlock &
TBB, MachineBasicBlock &FBB,
754 bool SkipUnconditionalBranches)
const {
755 while (TIB != TIE && FIB != FIE) {
759 if (TIB == TIE || FIB == FIE)
761 if (!TIB->isIdenticalTo(*FIB))
765 std::vector<MachineOperand> PredDefs;
769 if (!TIB->isBranch())
776 if (TIB == TIE || FIB == FIE)
788 if (SkipUnconditionalBranches) {
789 while (RTIE != RTIB && RTIE->isUnconditionalBranch())
791 while (RFIE != RFIB && RFIE->isUnconditionalBranch())
797 while (RTIE != RTIB && RFIE != RFIB) {
802 if (RTIE == RTIB || RFIE == RFIB)
804 if (!RTIE->isIdenticalTo(*RFIE))
808 if (!RTIE->isBranch())
827bool IfConverter::RescanInstructions(
830 BBInfo &TrueBBI, BBInfo &FalseBBI)
const {
831 bool BranchUnpredicable =
true;
832 TrueBBI.IsUnpredicable = FalseBBI.IsUnpredicable =
false;
833 ScanInstructions(TrueBBI, TIB, TIE, BranchUnpredicable);
834 if (TrueBBI.IsUnpredicable)
836 ScanInstructions(FalseBBI, FIB, FIE, BranchUnpredicable);
837 if (FalseBBI.IsUnpredicable)
839 if (TrueBBI.ClobbersPred && FalseBBI.ClobbersPred)
852 while (E1 != B1 && E2 != B2) {
855 if (E1 == B1 && E2 == B2)
859 assert(!E2->isBranch() &&
"Branch mis-match, one block is empty.");
863 assert(!E1->isBranch() &&
"Branch mis-match, one block is empty.");
867 if (E1->isBranch() || E2->isBranch())
868 assert(E1->isIdenticalTo(*E2) &&
869 "Branch mis-match, branch instructions don't match.");
891bool IfConverter::ValidForkedDiamond(
892 BBInfo &TrueBBI, BBInfo &FalseBBI,
893 unsigned &Dups1,
unsigned &Dups2,
894 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
896 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
897 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
900 if (!TrueBBI.IsBrAnalyzable || !FalseBBI.IsBrAnalyzable)
903 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
908 if (TrueBBI.BrCond.size() == 0 ||
909 FalseBBI.BrCond.size() == 0)
912 MachineBasicBlock *
TT = TrueBBI.TrueBB;
913 MachineBasicBlock *TF = TrueBBI.FalseBB;
914 MachineBasicBlock *FT = FalseBBI.TrueBB;
915 MachineBasicBlock *FF = FalseBBI.FalseBB;
930 if (!((TT == FT && TF == FF) || (TF == FT && TT == FF)))
933 bool FalseReversed =
false;
934 if (TF == FT && TT == FF) {
936 if (!FalseBBI.IsBrReversible)
938 FalseReversed =
true;
939 reverseBranchCondition(FalseBBI);
943 reverseBranchCondition(FalseBBI);
951 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
952 *TrueBBI.BB, *FalseBBI.BB,
956 TrueBBICalc.BB = TrueBBI.BB;
957 FalseBBICalc.BB = FalseBBI.BB;
958 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
959 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
960 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
966 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
967 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
973bool IfConverter::ValidDiamond(
974 BBInfo &TrueBBI, BBInfo &FalseBBI,
975 unsigned &Dups1,
unsigned &Dups2,
976 BBInfo &TrueBBICalc, BBInfo &FalseBBICalc)
const {
978 if (TrueBBI.IsBeingAnalyzed || TrueBBI.IsDone ||
979 FalseBBI.IsBeingAnalyzed || FalseBBI.IsDone)
984 if (TrueBBI.BB == FalseBBI.BB)
987 MachineBasicBlock *
TT = TrueBBI.TrueBB;
988 MachineBasicBlock *FT = FalseBBI.TrueBB;
990 if (!TT && blockAlwaysFallThrough(TrueBBI))
992 if (!FT && blockAlwaysFallThrough(FalseBBI))
996 if (!TT && (TrueBBI.IsBrAnalyzable || FalseBBI.IsBrAnalyzable))
998 if (TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1)
1002 if (TrueBBI.FalseBB || FalseBBI.FalseBB)
1009 bool SkipUnconditionalBranches =
1010 TrueBBI.IsBrAnalyzable && FalseBBI.IsBrAnalyzable;
1015 if(!CountDuplicatedInstructions(TIB, FIB, TIE, FIE, Dups1, Dups2,
1016 *TrueBBI.BB, *FalseBBI.BB,
1017 SkipUnconditionalBranches))
1020 TrueBBICalc.BB = TrueBBI.BB;
1021 FalseBBICalc.BB = FalseBBI.BB;
1022 TrueBBICalc.IsBrAnalyzable = TrueBBI.IsBrAnalyzable;
1023 FalseBBICalc.IsBrAnalyzable = FalseBBI.IsBrAnalyzable;
1024 if (!RescanInstructions(TIB, FIB, TIE, FIE, TrueBBICalc, FalseBBICalc))
1029 TrueBBICalc.NonPredSize = TrueBBI.NonPredSize;
1030 FalseBBICalc.NonPredSize = FalseBBI.NonPredSize;
1036void IfConverter::AnalyzeBranches(BBInfo &BBI) {
1040 BBI.TrueBB = BBI.FalseBB =
nullptr;
1042 BBI.IsBrAnalyzable =
1044 if (!BBI.IsBrAnalyzable) {
1045 BBI.TrueBB =
nullptr;
1046 BBI.FalseBB =
nullptr;
1051 BBI.IsBrReversible = (RevCond.size() == 0) ||
1053 BBI.HasFallThrough = BBI.IsBrAnalyzable && BBI.FalseBB ==
nullptr;
1055 if (BBI.BrCond.size()) {
1062 BBI.IsUnpredicable =
true;
1072void IfConverter::ScanInstructions(BBInfo &BBI,
1075 bool BranchUnpredicable)
const {
1076 if (BBI.IsDone || BBI.IsUnpredicable)
1079 bool AlreadyPredicated = !BBI.Predicate.empty();
1081 BBI.NonPredSize = 0;
1084 BBI.ClobbersPred =
false;
1086 if (
MI.isDebugInstr())
1119 if (
MI.isNotDuplicable() ||
MI.isConvergent())
1120 BBI.CannotBeCopied =
true;
1123 bool isCondBr = BBI.IsBrAnalyzable &&
MI.isConditionalBranch();
1125 if (BranchUnpredicable &&
MI.isBranch()) {
1126 BBI.IsUnpredicable =
true;
1134 if (!isPredicated) {
1136 unsigned ExtraPredCost =
TII->getPredicationCost(
MI);
1137 unsigned NumCycles = SchedModel.computeInstrLatency(&
MI,
false);
1139 BBI.ExtraCost += NumCycles-1;
1140 BBI.ExtraCost2 += ExtraPredCost;
1141 }
else if (!AlreadyPredicated) {
1145 BBI.IsUnpredicable =
true;
1149 if (BBI.ClobbersPred && !isPredicated) {
1154 BBI.IsUnpredicable =
true;
1160 std::vector<MachineOperand> PredDefs;
1162 BBI.ClobbersPred =
true;
1165 BBI.IsUnpredicable =
true;
1180bool IfConverter::FeasibilityAnalysis(BBInfo &BBI,
1181 SmallVectorImpl<MachineOperand> &Pred,
1182 bool isTriangle,
bool RevBranch,
1183 bool hasCommonTail) {
1188 if (BBI.IsDone || (BBI.IsUnpredicable && !hasCommonTail))
1194 if (BBI.Predicate.size() && !BBI.IsBrAnalyzable)
1202 if (!hasCommonTail && BBI.BrCond.size()) {
1223void IfConverter::AnalyzeBlock(
1224 MachineBasicBlock &
MBB, std::vector<std::unique_ptr<IfcvtToken>> &Tokens) {
1226 BBState(MachineBasicBlock &
MBB) :
MBB(&
MBB) {}
1227 MachineBasicBlock *
MBB;
1230 bool SuccsAnalyzed =
false;
1236 while (!BBStack.empty()) {
1237 BBState &State = BBStack.back();
1238 MachineBasicBlock *BB = State.MBB;
1239 BBInfo &BBI = BBAnalysis[BB->
getNumber()];
1241 if (!State.SuccsAnalyzed) {
1242 if (BBI.IsAnalyzed || BBI.IsBeingAnalyzed) {
1248 BBI.IsBeingAnalyzed =
true;
1250 AnalyzeBranches(BBI);
1253 ScanInstructions(BBI, Begin, End);
1257 if (!BBI.IsBrAnalyzable || BBI.BrCond.empty() || BBI.IsDone) {
1258 BBI.IsBeingAnalyzed =
false;
1259 BBI.IsAnalyzed =
true;
1265 if (BBI.TrueBB == BB || BBI.FalseBB == BB) {
1266 BBI.IsBeingAnalyzed =
false;
1267 BBI.IsAnalyzed =
true;
1274 BBI.IsBeingAnalyzed =
false;
1275 BBI.IsAnalyzed =
true;
1281 State.SuccsAnalyzed =
true;
1282 BBStack.push_back(*BBI.FalseBB);
1283 BBStack.push_back(*BBI.TrueBB);
1287 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1288 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1290 if (TrueBBI.IsDone && FalseBBI.IsDone) {
1291 BBI.IsBeingAnalyzed =
false;
1292 BBI.IsAnalyzed =
true;
1298 RevCond(BBI.BrCond.begin(), BBI.BrCond.end());
1303 bool TNeedSub = !TrueBBI.Predicate.empty();
1304 bool FNeedSub = !FalseBBI.Predicate.empty();
1305 bool Enqueued =
false;
1310 BBInfo TrueBBICalc, FalseBBICalc;
1311 auto feasibleDiamond = [&](
bool Forked) {
1312 bool MeetsSize = MeetIfcvtSizeLimit(TrueBBICalc, FalseBBICalc, *BB,
1313 Dups + Dups2, Prediction, Forked);
1314 bool TrueFeasible = FeasibilityAnalysis(TrueBBI, BBI.BrCond,
1317 bool FalseFeasible = FeasibilityAnalysis(FalseBBI, RevCond,
1320 return MeetsSize && TrueFeasible && FalseFeasible;
1323 if (ValidDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1324 TrueBBICalc, FalseBBICalc)) {
1325 if (feasibleDiamond(
false)) {
1334 Tokens.push_back(std::make_unique<IfcvtToken>(
1335 BBI, ICDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1336 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1339 }
else if (ValidForkedDiamond(TrueBBI, FalseBBI, Dups, Dups2,
1340 TrueBBICalc, FalseBBICalc)) {
1341 if (feasibleDiamond(
true)) {
1352 Tokens.push_back(std::make_unique<IfcvtToken>(
1353 BBI, ICForkedDiamond, TNeedSub | FNeedSub, Dups, Dups2,
1354 (
bool) TrueBBICalc.ClobbersPred, (
bool) FalseBBICalc.ClobbersPred));
1360 if (ValidTriangle(TrueBBI, FalseBBI,
false, Dups, Prediction) &&
1361 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1362 TrueBBI.ExtraCost2, Prediction) &&
1363 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true)) {
1372 std::make_unique<IfcvtToken>(BBI, ICTriangle, TNeedSub, Dups));
1376 if (ValidTriangle(TrueBBI, FalseBBI,
true, Dups, Prediction) &&
1377 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1378 TrueBBI.ExtraCost2, Prediction) &&
1379 FeasibilityAnalysis(TrueBBI, BBI.BrCond,
true,
true)) {
1381 std::make_unique<IfcvtToken>(BBI, ICTriangleRev, TNeedSub, Dups));
1385 if (ValidSimple(TrueBBI, Dups, Prediction) &&
1386 MeetIfcvtSizeLimit(*TrueBBI.BB, TrueBBI.NonPredSize + TrueBBI.ExtraCost,
1387 TrueBBI.ExtraCost2, Prediction) &&
1388 FeasibilityAnalysis(TrueBBI, BBI.BrCond)) {
1397 std::make_unique<IfcvtToken>(BBI, ICSimple, TNeedSub, Dups));
1403 if (ValidTriangle(FalseBBI, TrueBBI,
false, Dups,
1405 MeetIfcvtSizeLimit(*FalseBBI.BB,
1406 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1407 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1408 FeasibilityAnalysis(FalseBBI, RevCond,
true)) {
1409 Tokens.push_back(std::make_unique<IfcvtToken>(BBI, ICTriangleFalse,
1414 if (ValidTriangle(FalseBBI, TrueBBI,
true, Dups,
1416 MeetIfcvtSizeLimit(*FalseBBI.BB,
1417 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1418 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1419 FeasibilityAnalysis(FalseBBI, RevCond,
true,
true)) {
1421 std::make_unique<IfcvtToken>(BBI, ICTriangleFRev, FNeedSub, Dups));
1425 if (ValidSimple(FalseBBI, Dups, Prediction.
getCompl()) &&
1426 MeetIfcvtSizeLimit(*FalseBBI.BB,
1427 FalseBBI.NonPredSize + FalseBBI.ExtraCost,
1428 FalseBBI.ExtraCost2, Prediction.
getCompl()) &&
1429 FeasibilityAnalysis(FalseBBI, RevCond)) {
1431 std::make_unique<IfcvtToken>(BBI, ICSimpleFalse, FNeedSub, Dups));
1436 BBI.IsEnqueued = Enqueued;
1437 BBI.IsBeingAnalyzed =
false;
1438 BBI.IsAnalyzed =
true;
1444void IfConverter::AnalyzeBlocks(
1445 MachineFunction &MF, std::vector<std::unique_ptr<IfcvtToken>> &Tokens) {
1446 for (MachineBasicBlock &
MBB : MF)
1447 AnalyzeBlock(
MBB, Tokens);
1463 if (
I ==
E || !
I->empty() || !PI->isSuccessor(&*
I))
1468 return PI->isSuccessor(&*
I);
1473void IfConverter::InvalidatePreds(MachineBasicBlock &
MBB) {
1475 BBInfo &PBBI = BBAnalysis[Predecessor->getNumber()];
1476 if (PBBI.IsDone || PBBI.BB == &
MBB)
1478 PBBI.IsAnalyzed =
false;
1479 PBBI.IsEnqueued =
false;
1488 TII->insertBranch(
MBB, &ToMBB,
nullptr, NoCond, dl);
1501 for (
unsigned Reg : Redefs)
1508 for (
auto Clobber : Clobbers) {
1511 unsigned Reg = Clobber.first;
1515 if (
Op.isRegMask()) {
1530 [&](
MCPhysReg S) { return LiveBeforeMI.count(S); }))
1536bool IfConverter::IfConvertSimple(BBInfo &BBI, IfcvtKind Kind) {
1537 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1538 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1539 BBInfo *CvtBBI = &TrueBBI;
1540 BBInfo *NextBBI = &FalseBBI;
1543 if (Kind == ICSimpleFalse)
1546 MachineBasicBlock &CvtMBB = *CvtBBI->BB;
1547 MachineBasicBlock &NextMBB = *NextBBI->BB;
1548 if (CvtBBI->IsDone ||
1549 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1551 BBI.IsAnalyzed =
false;
1552 CvtBBI->IsAnalyzed =
false;
1560 if (Kind == ICSimpleFalse)
1566 if (
MRI->tracksLiveness()) {
1580 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond);
1583 BBI.BB->removeSuccessor(&CvtMBB,
true);
1586 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1590 MergeBlocks(BBI, *CvtBBI);
1593 bool IterIfcvt =
true;
1596 BBI.HasFallThrough =
false;
1613 InvalidatePreds(*BBI.BB);
1614 CvtBBI->IsDone =
true;
1621bool IfConverter::IfConvertTriangle(BBInfo &BBI, IfcvtKind Kind) {
1622 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
1623 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
1624 BBInfo *CvtBBI = &TrueBBI;
1625 BBInfo *NextBBI = &FalseBBI;
1629 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1632 MachineBasicBlock &CvtMBB = *CvtBBI->BB;
1633 MachineBasicBlock &NextMBB = *NextBBI->BB;
1634 if (CvtBBI->IsDone ||
1635 (CvtBBI->CannotBeCopied && CvtMBB.
pred_size() > 1)) {
1637 BBI.IsAnalyzed =
false;
1638 CvtBBI->IsAnalyzed =
false;
1646 if (Kind == ICTriangleFalse || Kind == ICTriangleFRev)
1650 if (Kind == ICTriangleRev || Kind == ICTriangleFRev) {
1651 if (reverseBranchCondition(*CvtBBI)) {
1657 BBInfo &PBBI = BBAnalysis[PBB->getNumber()];
1658 if (PBBI.IsEnqueued) {
1659 PBBI.IsAnalyzed =
false;
1660 PBBI.IsEnqueued =
false;
1669 if (
MRI->tracksLiveness()) {
1674 bool HasEarlyExit = CvtBBI->FalseBB !=
nullptr;
1675 BranchProbability CvtNext, CvtFalse, BBNext, BBCvt;
1692 CopyAndPredicateBlock(BBI, *CvtBBI,
Cond,
true);
1696 PredicateBlock(*CvtBBI, CvtMBB.
end(),
Cond);
1699 MergeBlocks(BBI, *CvtBBI,
false);
1703 BBI.BB->removeSuccessor(&CvtMBB,
true);
1708 CvtBBI->BrCond.end());
1719 auto NewNext = BBNext + BBCvt * CvtNext;
1720 auto NewTrueBBIter =
find(BBI.BB->successors(), NewTrueBB);
1721 if (NewTrueBBIter != BBI.BB->succ_end())
1722 BBI.BB->setSuccProbability(NewTrueBBIter, NewNext);
1724 auto NewFalse = BBCvt * CvtFalse;
1726 BBI.BB->addSuccessor(CvtBBI->FalseBB, NewFalse);
1731 bool FalseBBDead =
false;
1732 bool IterIfcvt =
true;
1734 if (!isFallThrough) {
1738 if (!HasEarlyExit && NextMBB.
pred_size() == 1 &&
1740 MergeBlocks(BBI, *NextBBI);
1744 BBI.HasFallThrough =
false;
1754 InvalidatePreds(*BBI.BB);
1755 CvtBBI->IsDone =
true;
1757 NextBBI->IsDone =
true;
1774bool IfConverter::IfConvertDiamondCommon(
1775 BBInfo &BBI, BBInfo &TrueBBI, BBInfo &FalseBBI,
1776 unsigned NumDups1,
unsigned NumDups2,
1777 bool TClobbersPred,
bool FClobbersPred,
1778 bool RemoveBranch,
bool MergeAddEdges) {
1780 if (TrueBBI.IsDone || FalseBBI.IsDone ||
1781 TrueBBI.BB->pred_size() > 1 || FalseBBI.BB->pred_size() > 1) {
1783 BBI.IsAnalyzed =
false;
1784 TrueBBI.IsAnalyzed =
false;
1785 FalseBBI.IsAnalyzed =
false;
1789 if (TrueBBI.BB->hasAddressTaken() || FalseBBI.BB->hasAddressTaken())
1796 BBInfo *BBI1 = &TrueBBI;
1797 BBInfo *BBI2 = &FalseBBI;
1805 bool DoSwap =
false;
1806 if (TClobbersPred && !FClobbersPred)
1808 else if (!TClobbersPred && !FClobbersPred) {
1809 if (TrueBBI.NonPredSize > FalseBBI.NonPredSize)
1811 }
else if (TClobbersPred && FClobbersPred)
1821 MachineBasicBlock &MBB1 = *BBI1->BB;
1822 MachineBasicBlock &MBB2 = *BBI2->BB;
1831 if (
MRI->tracksLiveness()) {
1840 BBI1->NonPredSize -= NumDups1;
1841 BBI2->NonPredSize -= NumDups1;
1846 for (
unsigned i = 0; i < NumDups1; ++DI1) {
1847 if (DI1 == MBB1.
end())
1849 if (!DI1->isDebugInstr())
1852 while (NumDups1 != 0) {
1855 if (DI2->shouldUpdateAdditionalCallInfo())
1859 if (DI2 == MBB2.
end())
1861 if (!DI2->isDebugInstr())
1865 if (
MRI->tracksLiveness()) {
1872 BBI.BB->splice(BBI.BB->end(), &MBB1, MBB1.
begin(), DI1);
1883 if (!BBI1->IsBrAnalyzable)
1889 while (DI1 != MBB1.
begin()) {
1891 if (!Prev->isBranch() && !Prev->isDebugInstr())
1895 for (
unsigned i = 0; i != NumDups2; ) {
1904 if (DI1->shouldUpdateAdditionalCallInfo())
1908 if (!DI1->isDebugInstr())
1913 DI2 = BBI2->BB->end();
1921 while (DI2 != MBB2.
begin()) {
1923 if (!Prev->isBranch() && !Prev->isDebugInstr())
1928 while (NumDups2 != 0) {
1934 if (!DI2->isDebugInstr())
1946 SmallSet<MCRegister, 4> RedefsByFalse;
1947 SmallSet<MCRegister, 4> ExtUses;
1948 if (
TII->isProfitableToUnpredicate(MBB1, MBB2)) {
1950 if (FI.isDebugInstr())
1953 for (
const MachineOperand &MO : FI.operands()) {
1961 }
else if (!RedefsByFalse.
count(
Reg)) {
1968 for (MCRegister
Reg : Defs) {
1976 PredicateBlock(*BBI1, MBB1.
end(), *Cond1, &RedefsByFalse);
1985 if (!MBB2.
empty() && (DI2 == MBB2.
end())) {
1990 if (BB2NonPredicated && (BB1Predicated || !BBI2->IsBrAnalyzable))
1995 PredicateBlock(*BBI2, DI2, *Cond2);
1998 MergeBlocks(BBI, *BBI1, MergeAddEdges);
1999 MergeBlocks(BBI, *BBI2, MergeAddEdges);
2005bool IfConverter::IfConvertForkedDiamond(
2006 BBInfo &BBI, IfcvtKind Kind,
2007 unsigned NumDups1,
unsigned NumDups2,
2008 bool TClobbersPred,
bool FClobbersPred) {
2009 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2010 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2015 if (TIE != TrueBBI.BB->end())
2016 dl = TIE->getDebugLoc();
2020 if (!IfConvertDiamondCommon(
2021 BBI, TrueBBI, FalseBBI,
2023 TClobbersPred, FClobbersPred,
2030 TrueBBI.BrCond, dl);
2033 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2034 InvalidatePreds(*BBI.BB);
2041bool IfConverter::IfConvertDiamond(BBInfo &BBI, IfcvtKind Kind,
2042 unsigned NumDups1,
unsigned NumDups2,
2043 bool TClobbersPred,
bool FClobbersPred) {
2044 BBInfo &TrueBBI = BBAnalysis[BBI.TrueBB->getNumber()];
2045 BBInfo &FalseBBI = BBAnalysis[BBI.FalseBB->getNumber()];
2046 MachineBasicBlock *TailBB = TrueBBI.TrueBB;
2050 if (blockAlwaysFallThrough(TrueBBI))
2051 TailBB = FalseBBI.TrueBB;
2052 assert((TailBB || !TrueBBI.IsBrAnalyzable) &&
"Unexpected!");
2055 if (!IfConvertDiamondCommon(
2056 BBI, TrueBBI, FalseBBI,
2058 TClobbersPred, FClobbersPred,
2059 TrueBBI.IsBrAnalyzable,
2070 BBI.BB->removeSuccessor(TrueBBI.BB);
2071 BBI.BB->removeSuccessor(FalseBBI.BB,
true);
2073 BBInfo &TailBBI = BBAnalysis[TailBB->
getNumber()];
2075 blockNeverFallThrough(TailBBI) && !TailBBI.BB->hasAddressTaken();
2081 CanMergeTail =
false;
2084 unsigned NumPreds = TailBB->
pred_size();
2086 CanMergeTail =
false;
2087 else if (NumPreds == 1 && CanMergeTail) {
2089 if (*PI != TrueBBI.BB && *PI != FalseBBI.BB)
2090 CanMergeTail =
false;
2093 MergeBlocks(BBI, TailBBI);
2094 TailBBI.IsDone =
true;
2098 BBI.HasFallThrough =
false;
2103 BBI.IsDone = TrueBBI.IsDone = FalseBBI.IsDone =
true;
2104 InvalidatePreds(*BBI.BB);
2112 bool SawStore =
true;
2113 if (!
MI.isSafeToMove(SawStore))
2122 if (MO.isDef() && !LaterRedefs.
count(
Reg))
2132 SmallVectorImpl<MachineOperand> &
Cond,
2133 SmallSet<MCRegister, 4> *LaterRedefs) {
2134 bool AnyUnpred =
false;
2135 bool MaySpec = LaterRedefs !=
nullptr;
2136 for (MachineInstr &
I :
make_range(BBI.BB->begin(),
E)) {
2151 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2161 BBI.Predicate.append(
Cond.begin(),
Cond.end());
2163 BBI.IsAnalyzed =
false;
2164 BBI.NonPredSize = 0;
2173void IfConverter::CopyAndPredicateBlock(BBInfo &ToBBI, BBInfo &FromBBI,
2174 SmallVectorImpl<MachineOperand> &
Cond,
2176 MachineFunction &MF = *ToBBI.BB->getParent();
2178 MachineBasicBlock &FromMBB = *FromBBI.BB;
2179 for (MachineInstr &
I : FromMBB) {
2181 if (IgnoreBr &&
I.isBranch())
2184 MachineInstr *
MI = MF.CloneMachineInstr(&
I);
2186 if (
I.isCandidateForAdditionalCallInfo())
2189 ToBBI.BB->insert(ToBBI.BB->end(),
MI);
2190 ToBBI.NonPredSize++;
2191 unsigned ExtraPredCost =
TII->getPredicationCost(
I);
2192 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
2194 ToBBI.ExtraCost += NumCycles-1;
2195 ToBBI.ExtraCost2 += ExtraPredCost;
2200 dbgs() <<
"Unable to predicate " <<
I <<
"!\n";
2212 std::vector<MachineBasicBlock *> Succs(FromMBB.succ_begin(),
2213 FromMBB.succ_end());
2215 MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB :
nullptr;
2217 for (MachineBasicBlock *Succ : Succs) {
2219 if (Succ == FallThrough)
2221 ToBBI.BB->addSuccessor(Succ);
2225 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2226 ToBBI.Predicate.append(
Cond.begin(),
Cond.end());
2228 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2229 ToBBI.IsAnalyzed =
false;
2239void IfConverter::MergeBlocks(BBInfo &ToBBI, BBInfo &FromBBI,
bool AddEdges) {
2240 MachineBasicBlock &FromMBB = *FromBBI.BB;
2242 "Removing a BB whose address is taken!");
2247 for (MachineInstr &
MI : FromMBB)
2248 if (
MI.getOpcode() == TargetOpcode::INLINEASM_BR)
2249 for (MachineOperand &MO :
MI.operands())
2250 if (MO.isMBB() && !ToBBI.BB->isSuccessor(MO.getMBB()))
2257 ToBBI.BB->splice(ToTI, &FromMBB, FromMBB.begin(), FromTI);
2261 ToTI = ToBBI.BB->end();
2262 ToBBI.BB->splice(ToTI, &FromMBB, FromTI, FromMBB.end());
2268 if (ToBBI.IsBrAnalyzable)
2269 ToBBI.BB->normalizeSuccProbs();
2271 SmallVector<MachineBasicBlock *, 4> FromSuccs(FromMBB.successors());
2273 MachineBasicBlock *FallThrough = FromBBI.HasFallThrough ? NBB :
nullptr;
2277 if (AddEdges && ToBBI.BB->isSuccessor(&FromMBB)) {
2281 ToBBI.BB->removeSuccessor(&FromMBB);
2284 for (MachineBasicBlock *Succ : FromSuccs) {
2286 if (Succ == FallThrough) {
2287 FromMBB.removeSuccessor(Succ);
2304 if (!To2FromProb.isZero())
2305 NewProb *= To2FromProb;
2308 FromMBB.removeSuccessor(Succ);
2333 if (ToBBI.BB->isSuccessor(Succ))
2334 ToBBI.BB->setSuccProbability(
2335 find(ToBBI.BB->successors(), Succ),
2338 ToBBI.BB->addSuccessor(Succ, NewProb);
2344 MachineBasicBlock *
Last = &*FromMBB.getParent()->rbegin();
2345 if (
Last != &FromMBB)
2346 FromMBB.moveAfter(
Last);
2350 if (ToBBI.IsBrAnalyzable && FromBBI.IsBrAnalyzable)
2351 ToBBI.BB->normalizeSuccProbs();
2353 ToBBI.Predicate.append(FromBBI.Predicate.begin(), FromBBI.Predicate.end());
2354 FromBBI.Predicate.clear();
2356 ToBBI.NonPredSize += FromBBI.NonPredSize;
2357 ToBBI.ExtraCost += FromBBI.ExtraCost;
2358 ToBBI.ExtraCost2 += FromBBI.ExtraCost2;
2359 FromBBI.NonPredSize = 0;
2360 FromBBI.ExtraCost = 0;
2361 FromBBI.ExtraCost2 = 0;
2363 ToBBI.ClobbersPred |= FromBBI.ClobbersPred;
2364 ToBBI.HasFallThrough = FromBBI.HasFallThrough;
2365 ToBBI.IsAnalyzed =
false;
2366 FromBBI.IsAnalyzed =
false;
2371 return new IfConverter(std::move(Ftor));
unsigned const MachineRegisterInfo * MRI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
Function Alias Analysis false
static MachineBasicBlock * findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB)
findFalseBlock - BB has a fallthrough.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
static cl::opt< bool > DisableTriangle("disable-ifcvt-triangle", cl::init(false), cl::Hidden)
static MachineBasicBlock * findFalseBlock(MachineBasicBlock *BB, MachineBasicBlock *TrueBB)
BB has a fallthrough. Find its 'false' successor given its 'true' successor.
static cl::opt< int > IfCvtFnStop("ifcvt-fn-stop", cl::init(-1), cl::Hidden)
static cl::opt< bool > IfCvtBranchFold("ifcvt-branch-fold", cl::init(true), cl::Hidden)
static cl::opt< bool > DisableTriangleF("disable-ifcvt-triangle-false", cl::init(false), cl::Hidden)
static cl::opt< int > IfCvtLimit("ifcvt-limit", cl::init(-1), cl::Hidden)
static void InsertUncondBranch(MachineBasicBlock &MBB, MachineBasicBlock &ToMBB, const TargetInstrInfo *TII)
Inserts an unconditional branch from MBB to ToMBB.
static void verifySameBranchInstructions(MachineBasicBlock *MBB1, MachineBasicBlock *MBB2)
static cl::opt< bool > DisableDiamond("disable-ifcvt-diamond", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableTriangleR("disable-ifcvt-triangle-rev", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableForkedDiamond("disable-ifcvt-forked-diamond", cl::init(false), cl::Hidden)
static MachineBasicBlock * getNextBlock(MachineBasicBlock &MBB)
Returns the next block in the function blocks ordering.
static bool MaySpeculate(const MachineInstr &MI, SmallSet< MCRegister, 4 > &LaterRedefs)
static void UpdatePredRedefs(MachineInstr &MI, LivePhysRegs &Redefs)
Behaves like LiveRegUnits::StepForward() but also adds implicit uses to all values defined in MI whic...
static cl::opt< bool > DisableSimpleF("disable-ifcvt-simple-false", cl::init(false), cl::Hidden)
static cl::opt< bool > DisableSimple("disable-ifcvt-simple", cl::init(false), cl::Hidden)
static bool canFallThroughTo(MachineBasicBlock &MBB, MachineBasicBlock &ToMBB)
Returns true either if ToMBB is the next block after MBB or that all the intervening blocks are empty...
static cl::opt< int > IfCvtFnStart("ifcvt-fn-start", cl::init(-1), cl::Hidden)
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
This file defines the make_scope_exit function, which executes user-defined cleanup logic at scope ex...
This file defines the SmallSet class.
This file defines the SmallVector class.
This file defines the SparseSet class derived from the version described in Briggs,...
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This file describes how to lower LLVM code to machine code.
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()
bool hasMinSize() const
Optimize this function for minimum size (-Oz).
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 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
MachineInstrBundleIterator< const MachineInstr > const_iterator
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
LLVM_ABI iterator getFirstNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the first non-debug instruction in the basic block, or end().
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
bool hasAddressTaken() const
Test whether this block is used as something other than the target of a terminator,...
SmallVectorImpl< MachineBasicBlock * >::iterator pred_iterator
pred_iterator pred_begin()
MachineInstrBundleIterator< MachineInstr, true > reverse_iterator
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
iterator_range< iterator > terminators()
iterator_range< succ_iterator > successors()
reverse_iterator rbegin()
iterator_range< pred_iterator > predecessors()
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI bool mayHaveInlineAsmBr() const
Returns true if this block may have an INLINEASM_BR (overestimate, by checking if any of the successo...
BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
Function & getFunction()
Return the LLVM function that this machine code represents.
BasicBlockListType::iterator iterator
void eraseAdditionalCallInfo(const MachineInstr *MI)
Following functions update call site info.
void copyAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New)
Copy the call site info from Old to \ New.
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
reverse_iterator getReverse() const
Get a reverse iterator to the same node.
Representation of each machine instruction.
LLVM_ABI const MachineFunction * getMF() const
Return the function that contains the basic block that this instruction belongs to.
MachineOperand class - Representation of each machine instruction operand.
An analysis pass based on legacy pass manager to deliver ProfileSummaryInfo.
Analysis providing profile information.
Wrapper class representing virtual and physical registers.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
void insert_range(Range &&R)
bool contains(const T &V) const
Check if the SmallSet contains the given element.
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.
std::pair< iterator, bool > insert(const ValueT &Val)
insert - Attempts to insert a new element.
size_type count(const KeyT &Key) const
count - Returns 1 if this set contains an element identified by Key, 0 otherwise.
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.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
TargetSubtargetInfo - Generic base class for all target subtargets.
self_iterator getIterator()
This provides a very simple, boring adaptor for a begin and end iterator into a range type.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool isPredicated(const MCInst &MI, const MCInstrInfo *MCII)
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
void stable_sort(R &&Range)
auto find(R &&Range, const T &Val)
Provide wrappers to std::find which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI FunctionPass * createIfConverter(std::function< bool(const MachineFunction &)> Ftor)
@ Implicit
Not emitted register (e.g. carry, or temporary result).
@ Define
Register definition.
scope_exit(Callable) -> scope_exit< Callable >
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
IterT skipDebugInstructionsForward(IterT It, IterT End, bool SkipPseudoOp=true)
Increment It until it points to a non-debug instruction or to End and return the resulting iterator.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
void recomputeLivenessFlags(MachineBasicBlock &MBB)
Recomputes dead and kill flags in MBB.
uint16_t MCPhysReg
An unsigned integer type large enough to represent all physical registers, but not necessarily virtua...
DWARFExpression::Operation Op
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
LLVM_ABI char & IfConverterID
IfConverter - This pass performs machine code if conversion.
LLVM_ABI Printable printMBBReference(const MachineBasicBlock &MBB)
Prints a machine basic block reference.
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.