50#define DEBUG_TYPE "early-ifcvt"
56 cl::desc(
"Maximum number of instructions per speculated block."));
65 cl::desc(
"Enable hard-to-predict branch analysis for if-conversion"));
71 cl::desc(
"Limit the number of steps taken when searching for a "
72 "recently loaded value"));
78 cl::desc(
"Limit the number of blocks and instructions examined when "
79 "searching for calls between a load and the condition it feeds"));
83 cl::desc(
"Cold edge probability threshold in percent for using no "
84 "critical-path extension budget (0 disables the threshold)"));
87STATISTIC(NumDiamondsConv,
"Number of diamonds converted");
89STATISTIC(NumTrianglesConv,
"Number of triangles converted");
91 "Number of data dependent conditional branches encountered");
92STATISTIC(NumLikelyBiased,
"Number of branches with a hot path encountered");
94 "Number of branches with reduced critical-path budget");
138 bool isTriangle()
const {
return TBB == Tail || FBB == Tail; }
141 MachineBasicBlock *getTPred()
const {
return TBB == Tail ? Head : TBB; }
144 MachineBasicBlock *getFPred()
const {
return FBB == Tail ? Head : FBB; }
151 TargetInstrInfo::SelectExpansion Select;
153 PHIInfo(MachineInstr *phi) : PHI(
phi) {}
159 SmallVector<MachineOperand, 4> Cond;
164 SmallPtrSet<MachineInstr*, 8> InsertAfter;
167 BitVector ClobberedRegUnits;
170 SparseSet<MCRegUnit, MCRegUnit, MCRegUnitToIndex> LiveRegUnits;
178 bool canSpeculateInstrs(MachineBasicBlock *
MBB);
182 bool canPredicateInstrs(MachineBasicBlock *
MBB);
186 bool InstrDependenciesAllowIfConv(MachineInstr *
I);
190 void PredicateBlock(MachineBasicBlock *
MBB,
bool ReversePredicate);
193 bool findInsertionPoint();
196 void replacePHIInstrs();
199 void rewritePHIOperands();
207 LiveRegUnits.clear();
208 LiveRegUnits.setUniverse(TRI->getNumRegUnits());
209 ClobberedRegUnits.clear();
210 ClobberedRegUnits.resize(TRI->getNumRegUnits());
217 bool canConvertIf(MachineBasicBlock *
MBB,
bool Predicate =
false);
221 void convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
222 bool Predicate =
false);
246 for (MachineInstr &
MI :
248 if (
MI.isDebugInstr())
272 bool DontMoveAcrossStore =
true;
273 if (!
MI.isSafeToMove(DontMoveAcrossStore)) {
279 if (!InstrDependenciesAllowIfConv(&
MI))
289bool SSAIfConv::InstrDependenciesAllowIfConv(MachineInstr *
I) {
290 for (
const MachineOperand &MO :
I->operands()) {
291 if (MO.isRegMask()) {
302 ClobberedRegUnits.
set(
static_cast<unsigned>(Unit));
313 LLVM_DEBUG(
dbgs() <<
"Can't insert instructions below terminator.\n");
328bool SSAIfConv::canPredicateInstrs(MachineBasicBlock *
MBB) {
343 if (
I->isDebugInstr())
371 if (!InstrDependenciesAllowIfConv(&(*
I)))
378void SSAIfConv::PredicateBlock(MachineBasicBlock *
MBB,
bool ReversePredicate) {
379 auto Condition =
Cond;
380 if (ReversePredicate) {
382 assert(CanRevCond &&
"Reversed predicate is not supported");
389 if (
I->isDebugInstr())
405bool SSAIfConv::findInsertionPoint() {
408 LiveRegUnits.
clear();
416 if (InsertAfter.
count(&*
I)) {
422 for (
const MachineOperand &MO :
I->operands()) {
432 LiveRegUnits.
erase(Unit);
438 while (!Reads.
empty())
440 if (ClobberedRegUnits.
test(
static_cast<unsigned>(Unit)))
441 LiveRegUnits.
insert(Unit);
444 if (
I != FirstTerm &&
I->isTerminator())
449 if (!LiveRegUnits.
empty()) {
451 dbgs() <<
"Would clobber";
452 for (MCRegUnit LRU : LiveRegUnits)
454 dbgs() <<
" live before " << *
I;
473bool SSAIfConv::canConvertIf(MachineBasicBlock *
MBB,
bool Predicate) {
479 MachineBasicBlock *Succ0 = Head->
succ_begin()[0];
480 MachineBasicBlock *Succ1 = Head->
succ_begin()[1];
503 if (!
Tail->livein_empty()) {
516 if (!Predicate && (
Tail->empty() || !
Tail->front().isPHI())) {
530 LLVM_DEBUG(
dbgs() <<
"analyzeBranch didn't find conditional branch.\n");
537 LLVM_DEBUG(
dbgs() <<
"analyzeBranch found an unconditional branch.\n");
543 FBB =
TBB == Succ0 ? Succ1 : Succ0;
547 MachineBasicBlock *TPred = getTPred();
548 MachineBasicBlock *FPred = getFPred();
550 I !=
E &&
I->isPHI(); ++
I) {
552 PHIInfo &PI = PHIs.
back();
554 for (
unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) {
555 if (PI.PHI->getOperand(i+1).getMBB() == TPred)
556 PI.TReg = PI.PHI->getOperand(i).getReg();
557 if (PI.PHI->getOperand(i+1).getMBB() == FPred)
558 PI.FReg = PI.PHI->getOperand(i).getReg();
560 assert(PI.TReg.isVirtual() &&
"Bad PHI");
561 assert(PI.FReg.isVirtual() &&
"Bad PHI");
564 if (!
TII->canInsertSelect(*Head,
Cond, PI.PHI->getOperand(0).getReg(),
565 PI.TReg, PI.FReg, PI.Select)) {
573 ClobberedRegUnits.
reset();
575 if (
TBB != Tail && !canPredicateInstrs(
TBB))
577 if (FBB != Tail && !canPredicateInstrs(FBB))
580 if (
TBB != Tail && !canSpeculateInstrs(
TBB))
582 if (FBB != Tail && !canSpeculateInstrs(FBB))
588 if (!findInsertionPoint())
605 if (!TReg.isVirtual() || !FReg.
isVirtual())
627 return MO.isReg() && MO.getReg().isPhysical();
632 if (!
TII->produceSameValue(*TDef, *FDef, &
MRI))
638 if (TIdx == -1 || FIdx == -1)
647void SSAIfConv::replacePHIInstrs() {
648 assert(
Tail->pred_size() == 2 &&
"Cannot replace PHIs");
650 assert(FirstTerm != Head->
end() &&
"No terminators");
651 DebugLoc HeadDL = FirstTerm->getDebugLoc();
654 for (PHIInfo &PI : PHIs) {
656 Register DstReg = PI.PHI->getOperand(0).getReg();
660 BuildMI(*Head, FirstTerm, HeadDL,
TII->get(TargetOpcode::COPY), DstReg)
663 TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg,
Cond, PI.TReg,
667 PI.PHI->eraseFromParent();
675void SSAIfConv::rewritePHIOperands() {
677 assert(FirstTerm != Head->
end() &&
"No terminators");
678 DebugLoc HeadDL = FirstTerm->getDebugLoc();
681 for (PHIInfo &PI : PHIs) {
690 Register PHIDst = PI.PHI->getOperand(0).getReg();
692 TII->insertSelect(*Head, FirstTerm, HeadDL,
693 DstReg,
Cond, PI.TReg, PI.FReg);
698 for (
unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) {
699 MachineBasicBlock *
MBB = PI.PHI->getOperand(i-1).getMBB();
700 if (
MBB == getTPred()) {
701 PI.PHI->getOperand(i-1).setMBB(Head);
702 PI.PHI->getOperand(i-2).setReg(DstReg);
703 }
else if (
MBB == getFPred()) {
704 PI.PHI->removeOperand(i-1);
705 PI.PHI->removeOperand(i-2);
717void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
719 assert(Head && Tail &&
TBB && FBB &&
"Call canConvertIf first.");
730 PredicateBlock(
TBB,
false);
735 PredicateBlock(FBB,
true);
739 bool ExtraPreds =
Tail->pred_size() != 2;
741 rewritePHIOperands();
749 TBB->removeSuccessor(Tail,
true);
781 if (Tail != &
Tail->getParent()->back())
782 Tail->moveAfter(&
Tail->getParent()->back());
798class EarlyIfConverter {
799 const TargetInstrInfo *
TII =
nullptr;
800 const TargetRegisterInfo *
TRI =
nullptr;
801 const TargetSubtargetInfo *STI =
nullptr;
802 MachineRegisterInfo *
MRI =
nullptr;
803 MachineDominatorTree *DomTree =
nullptr;
804 MachineLoopInfo *
Loops =
nullptr;
805 MachineTraceMetrics *Traces =
nullptr;
807 MachineBranchProbabilityInfo &MBPI;
812 DenseMap<const MachineBasicBlock *, unsigned> NoCallBlocksCache;
815 EarlyIfConverter(MachineDominatorTree &DT, MachineLoopInfo &LI,
816 MachineTraceMetrics &MTM, MachineBranchProbabilityInfo &MBPI)
817 : DomTree(&DT),
Loops(&LI), Traces(&MTM), MBPI(MBPI) {}
818 EarlyIfConverter() =
delete;
823 bool tryConvertIf(MachineBasicBlock *);
824 void invalidateTraces();
825 bool shouldConvertIf();
826 bool isConditionDataDependent();
827 bool doOperandsComeFromMemory(
const MachineInstr *ConditionDef);
828 bool hasCallOrLoopInRange(
const MachineInstr *From,
const MachineInstr *To);
831class EarlyIfConverterLegacy :
public MachineFunctionPass {
834 EarlyIfConverterLegacy() : MachineFunctionPass(
ID) {}
835 void getAnalysisUsage(AnalysisUsage &AU)
const override;
837 StringRef getPassName()
const override {
return "Early If-Conversion"; }
841char EarlyIfConverterLegacy::ID = 0;
852void EarlyIfConverterLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
866void updateDomTree(MachineDominatorTree *DomTree,
const SSAIfConv &IfConv,
872 for (
auto *
B : Removed) {
874 assert(Node != HeadNode &&
"Cannot erase the head node");
875 while (!
Node->isLeaf()) {
876 assert(
Node->getBlock() == IfConv.Tail &&
"Unexpected children");
884void updateLoops(MachineLoopInfo *
Loops,
888 for (
auto *
B : Removed)
894void EarlyIfConverter::invalidateTraces() {
905 const PseudoSourceValue *PSV = MOp->getPseudoValue();
906 return PSV && PSV->isConstantPool();
916bool EarlyIfConverter::hasCallOrLoopInRange(
const MachineInstr *From,
917 const MachineInstr *To) {
921 LLVM_DEBUG(
dbgs() <<
" checking for a call or loop between " << *From
923 assert(DomTree->
dominates(From, To) &&
"From is expected to dominate To");
925 const MachineBasicBlock *FromBB = From->
getParent();
926 const MachineBasicBlock *ToBB = To->
getParent();
928 unsigned NumScanned = 0;
929 auto HitSearchLimit = [&](
unsigned N) {
937 auto FoundCall = [](
const MachineInstr &
MI) {
941 auto IsCallOrHitSearchLimit = [&](
const MachineInstr &
MI) {
942 if (HitSearchLimit(1))
946 return FoundCall(
MI);
950 if (FromBB == ToBB) {
954 if (IsCallOrHitSearchLimit(
MI))
963 if (IsCallOrHitSearchLimit(
MI))
965 for (
const MachineInstr &
MI :
968 if (IsCallOrHitSearchLimit(
MI))
973 SmallPtrSet<const MachineBasicBlock *, 16> Enqueued = {FromBB, ToBB};
975 auto Enqueue = [&](
const MachineBasicBlock *BB) {
983 while (!Worklist.
empty()) {
989 if (
const MachineLoop *BBLoop =
Loops->getLoopFor(BB)) {
990 if (!BBLoop->contains(ToBB) && !BBLoop->contains(FromBB)) {
998 auto CacheIt = NoCallBlocksCache.find(BB);
999 if (CacheIt != NoCallBlocksCache.end()) {
1000 if (HitSearchLimit(CacheIt->second))
1003 unsigned NumBlockInstrs = 0;
1004 for (
const MachineInstr &
MI :
1008 if (IsCallOrHitSearchLimit(
MI))
1011 NoCallBlocksCache[BB] = NumBlockInstrs;
1027bool EarlyIfConverter::doOperandsComeFromMemory(
1028 const MachineInstr *ConditionDef) {
1033 LLVM_DEBUG(
dbgs() <<
" doOperandsComeFromMemory starting from reg "
1039 MachineLoop *IfConvLoop =
Loops->getLoopFor(IfConv.Head);
1042 SmallPtrSet<const MachineInstr *, 8> VisitedInstrs;
1043 SmallVector<const MachineInstr *> Worklist;
1055 if (!VisitedInstrs.
insert(
MI).second)
1064 const MachineBasicBlock *Parent =
MI->getParent();
1065 MachineLoop *ParentLoop =
Loops->getLoopFor(Parent);
1068 if (IfConvLoop && ParentLoop != IfConvLoop)
1075 !
MI->isDereferenceableInvariantLoad()) {
1080 if (!DomTree->
dominates(
MI, Br) || hasCallOrLoopInRange(
MI, Br))
1087 for (
const MachineOperand &MO :
MI->operands()) {
1088 if (!MO.isReg() || !MO.isUse())
1095 if (!VisitedInstrs.
count(UseDef)) {
1106bool EarlyIfConverter::isConditionDataDependent() {
1107 TargetInstrInfo::MachineBranchPredicate MBP;
1108 if (
TII->analyzeBranchPredicate(*IfConv.Head, MBP,
false))
1119 if (TBBProb != FBBProb) {
1137 if (Delta < 0 && Cyc + Delta > Cyc)
1149 return R <<
ore::NV(
C.Key,
C.Value) << (
C.Value == 1 ?
" cycle" :
" cycles");
1156bool EarlyIfConverter::shouldConvertIf() {
1163 MachineLoop *CurrentLoop =
Loops->getLoopFor(IfConv.Head);
1169 if (CurrentLoop &&
any_of(IfConv.Cond, [&](MachineOperand &MO) {
1170 if (!MO.isReg() || !MO.isUse())
1172 Register Reg = MO.getReg();
1173 if (Reg.isPhysical())
1176 MachineInstr *Def = MRI->getVRegDef(Reg);
1177 return CurrentLoop->isLoopInvariant(*Def) ||
1178 all_of(Def->operands(), [&](MachineOperand &Op) {
1181 if (!Op.isReg() || !Op.isUse())
1183 Register Reg = Op.getReg();
1184 if (Reg.isPhysical())
1187 MachineInstr *Def = MRI->getVRegDef(Reg);
1188 return CurrentLoop->isLoopInvariant(*Def);
1194 MinInstr = Traces->getEnsemble(MachineTraceStrategy::TS_MinInstrCount);
1198 LLVM_DEBUG(
dbgs() <<
"TBB: " << TBBTrace <<
"FBB: " << FBBTrace);
1207 bool DataDependent =
false;
1209 DataDependent = isConditionDataDependent();
1211 const unsigned MispredictPenalty = STI->getMispredictionPenalty();
1212 unsigned CritLimit =
1213 DataDependent ? MispredictPenalty : MispredictPenalty / 2;
1214 const BranchProbability ColdProb =
1215 std::min(MBPI.getEdgeProbability(IfConv.Head, IfConv.TBB),
1216 MBPI.getEdgeProbability(IfConv.Head, IfConv.FBB));
1218 const bool StronglyBiased =
1219 ColdProb < BranchProbability(ColdEdgePercent, 100);
1220 if (StronglyBiased) {
1222 ++NumStronglyBiased;
1225 MachineBasicBlock &
MBB = *IfConv.Head;
1229 <<
", critical-path budget: " << CritLimit <<
" cycles\n");
1230 if (StronglyBiased) {
1232 return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE,
1233 "StronglyBiasedBranch",
1235 <<
"branch has a cold edge below "
1236 <<
ore::NV(
"ColdEdgeThreshold", ColdEdgePercent)
1237 <<
"%, using a critical-path "
1238 "extension budget of "
1239 <<
ore::NV(
"CritLimit", CritLimit) <<
" cycles";
1244 if (DataDependent) {
1246 return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE,
1247 "DataDependentCondition",
1249 <<
"branch condition is data-dependent (from memory load), "
1250 <<
"using higher CritLimit of " <<
ore::NV(
"CritLimit", CritLimit)
1259 if (IfConv.TBB != IfConv.Tail)
1263 <<
", minimal critical path " << MinCrit <<
'\n');
1264 if (ResLength > MinCrit + CritLimit) {
1267 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"IfConversion",
1269 R <<
"did not if-convert branch: the resulting critical path ("
1270 << Cycles{
"ResLength", ResLength}
1271 <<
") would extend the shorter leg's critical path ("
1272 << Cycles{
"MinCrit", MinCrit} <<
") by more than the threshold of "
1273 << Cycles{
"CritLimit", CritLimit}
1274 <<
", which cannot be hidden by available ILP.";
1284 unsigned BranchDepth =
1291 struct CriticalPathInfo {
1295 CriticalPathInfo
Cond{};
1296 CriticalPathInfo TBlock{};
1297 CriticalPathInfo FBlock{};
1298 bool ShouldConvert =
true;
1299 for (SSAIfConv::PHIInfo &PI : IfConv.PHIs) {
1306 if (CondDepth > MaxDepth) {
1307 unsigned Extra = CondDepth - MaxDepth;
1308 LLVM_DEBUG(
dbgs() <<
"Condition adds " << Extra <<
" cycles.\n");
1309 if (Extra >
Cond.Extra)
1310 Cond = {Extra, CondDepth};
1311 if (Extra > CritLimit) {
1313 ShouldConvert =
false;
1320 if (TDepth > MaxDepth) {
1321 unsigned Extra = TDepth - MaxDepth;
1323 if (Extra > TBlock.Extra)
1324 TBlock = {Extra, TDepth};
1325 if (Extra > CritLimit) {
1327 ShouldConvert =
false;
1334 if (FDepth > MaxDepth) {
1335 unsigned Extra = FDepth - MaxDepth;
1337 if (Extra > FBlock.Extra)
1338 FBlock = {Extra, FDepth};
1339 if (Extra > CritLimit) {
1341 ShouldConvert =
false;
1349 const CriticalPathInfo
Short = TBlock.Extra > FBlock.Extra ? FBlock : TBlock;
1350 const CriticalPathInfo
Long = TBlock.Extra > FBlock.Extra ? TBlock : FBlock;
1352 if (ShouldConvert) {
1354 MachineOptimizationRemark
R(
DEBUG_TYPE,
"IfConversion",
1356 R <<
"performing if-conversion on branch: the condition adds "
1357 << Cycles{
"CondCycles",
Cond.Extra} <<
" to the critical path";
1358 if (
Short.Extra > 0)
1359 R <<
", and the short leg adds another "
1360 << Cycles{
"ShortCycles",
Short.Extra};
1362 R <<
", and the long leg adds another "
1363 << Cycles{
"LongCycles",
Long.Extra};
1364 R <<
", each staying under the threshold of "
1365 << Cycles{
"CritLimit", CritLimit} <<
".";
1370 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"IfConversion",
1372 R <<
"did not if-convert branch: the condition would add "
1373 << Cycles{
"CondCycles",
Cond.Extra} <<
" to the critical path";
1374 if (
Cond.Extra > CritLimit)
1375 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1376 if (
Short.Extra > 0) {
1377 R <<
", and the short leg would add another "
1378 << Cycles{
"ShortCycles",
Short.Extra};
1379 if (
Short.Extra > CritLimit)
1380 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1382 if (
Long.Extra > 0) {
1383 R <<
", and the long leg would add another "
1384 << Cycles{
"LongCycles",
Long.Extra};
1385 if (
Long.Extra > CritLimit)
1386 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1393 return ShouldConvert;
1398bool EarlyIfConverter::tryConvertIf(MachineBasicBlock *
MBB) {
1400 while (IfConv.canConvertIf(
MBB) && shouldConvertIf()) {
1403 SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
1404 IfConv.convertIf(RemoveBlocks);
1406 updateDomTree(DomTree, IfConv, RemoveBlocks);
1407 updateLoops(
Loops, RemoveBlocks);
1410 NoCallBlocksCache.erase(IfConv.Head);
1411 for (MachineBasicBlock *
MBB : RemoveBlocks) {
1412 NoCallBlocksCache.erase(
MBB);
1420 LLVM_DEBUG(
dbgs() <<
"********** EARLY IF-CONVERSION **********\n"
1421 <<
"********** Function: " << MF.
getName() <<
'\n');
1441 if (tryConvertIf(DomNode->getBlock()))
1456 EarlyIfConverter Impl(MDT, LI, MTM, MBPI);
1468bool EarlyIfConverterLegacy::runOnMachineFunction(
MachineFunction &MF) {
1473 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1474 MachineLoopInfo &LI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1476 getAnalysis<MachineTraceMetricsWrapperPass>().getMTM();
1478 getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1480 return EarlyIfConverter(MDT, LI, MTM, MBPI).run(MF);
1501 void getAnalysisUsage(AnalysisUsage &AU)
const override;
1503 StringRef getPassName()
const override {
return "Early If-predicator"; }
1506 bool tryConvertIf(MachineBasicBlock *);
1507 bool shouldConvertIf();
1512#define DEBUG_TYPE "early-if-predicator"
1514char EarlyIfPredicator::ID = 0;
1524void EarlyIfPredicator::getAnalysisUsage(
AnalysisUsage &AU)
const {
1534bool EarlyIfPredicator::shouldConvertIf() {
1536 if (IfConv.isTriangle()) {
1537 MachineBasicBlock &IfBlock =
1538 (IfConv.TBB == IfConv.Tail) ? *IfConv.FBB : *IfConv.
TBB;
1540 unsigned ExtraPredCost = 0;
1541 unsigned Cycles = 0;
1542 for (MachineInstr &
I : IfBlock) {
1543 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1545 Cycles += NumCycles - 1;
1546 ExtraPredCost +=
TII->getPredicationCost(
I);
1552 unsigned TExtra = 0;
1553 unsigned FExtra = 0;
1554 unsigned TCycle = 0;
1555 unsigned FCycle = 0;
1556 for (MachineInstr &
I : *IfConv.TBB) {
1557 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1559 TCycle += NumCycles - 1;
1560 TExtra +=
TII->getPredicationCost(
I);
1562 for (MachineInstr &
I : *IfConv.FBB) {
1563 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1565 FCycle += NumCycles - 1;
1566 FExtra +=
TII->getPredicationCost(
I);
1569 FCycle, FExtra, TrueProbability);
1574bool EarlyIfPredicator::tryConvertIf(MachineBasicBlock *
MBB) {
1576 while (IfConv.canConvertIf(
MBB,
true) && shouldConvertIf()) {
1578 SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
1579 IfConv.convertIf(RemoveBlocks,
true);
1581 updateDomTree(DomTree, IfConv, RemoveBlocks);
1582 updateLoops(
Loops, RemoveBlocks);
1583 for (MachineBasicBlock *
MBB : RemoveBlocks)
1590 LLVM_DEBUG(
dbgs() <<
"********** EARLY IF-PREDICATOR **********\n"
1591 <<
"********** Function: " << MF.
getName() <<
'\n');
1599 SchedModel.
init(&STI);
1600 DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1601 Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1602 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1612 if (tryConvertIf(DomNode->getBlock()))
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static unsigned InstrCount
This file defines the DenseMap class.
static cl::opt< unsigned > MaxRegionInstrs("early-ifcvt-max-region-instrs", cl::Hidden, cl::init(64), cl::desc("Limit the number of blocks and instructions examined when " "searching for calls between a load and the condition it feeds"))
static cl::opt< unsigned > MaxNumSteps("early-ifcvt-max-steps", cl::Hidden, cl::init(16), cl::desc("Limit the number of steps taken when searching for a " "recently loaded value"))
static cl::opt< unsigned > ColdEdgeThreshold("early-ifcvt-cold-edge-threshold", cl::Hidden, cl::init(1), cl::desc("Cold edge probability threshold in percent for using no " "critical-path extension budget (0 disables the threshold)"))
static bool hasSameValue(const MachineRegisterInfo &MRI, const TargetInstrInfo *TII, Register TReg, Register FReg)
static unsigned adjCycles(unsigned Cyc, int Delta)
static cl::opt< bool > Stress("stress-early-ifcvt", cl::Hidden, cl::desc("Turn all knobs to 11"))
static cl::opt< unsigned > BlockInstrLimit("early-ifcvt-limit", cl::init(30), cl::Hidden, cl::desc("Maximum number of instructions per speculated block."))
static bool isConstantPoolLoad(const MachineInstr *MI)
static cl::opt< bool > EnableDataDependentBranchAnalysis("enable-early-ifcvt-data-dependent", cl::Hidden, cl::init(false), cl::desc("Enable hard-to-predict branch analysis for if-conversion"))
static Register UseReg(const MachineOperand &MO)
const HexagonInstrInfo * TII
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)
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
SmallVector< MachineOperand, 4 > Cond
MachineRegisterInfo & MRI
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
This file defines the SmallPtrSet 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)
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent the analysis usage information of a pass.
bool test(unsigned Idx) const
Returns true if bit Idx is set.
BitVector & reset()
Reset all bits in the bitvector.
BitVector & set()
Set all bits in the bitvector.
void changeImmediateDominator(DomTreeNodeBase< NodeT > *N, DomTreeNodeBase< NodeT > *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
void eraseNode(NodeT *BB)
eraseNode - Removes a node from the dominator tree.
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
LLVM_ABI PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &MFAM)
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 analyzeBranch(MachineBasicBlock &MBB, MachineBasicBlock *&TBB, MachineBasicBlock *&FBB, SmallVectorImpl< MachineOperand > &Cond, bool AllowModify) const override
Analyze the branching code at the end of MBB, returning true if it cannot be understood (e....
bool reverseBranchCondition(SmallVectorImpl< MachineOperand > &Cond) const override
Reverses the branch condition of the specified condition list, returning false on success and true if...
unsigned insertBranch(MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB, ArrayRef< MachineOperand > Cond, const DebugLoc &DL, int *BytesAdded=nullptr) const override
Insert branch code into the end of the specified MachineBasicBlock.
bool isProfitableToIfCvt(MachineBasicBlock &MBB, unsigned NumCycles, unsigned ExtraPredCycles, BranchProbability Probability) const override
Return true if it's profitable to predicate instructions with accumulated instruction latency of "Num...
bool 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.
unsigned pred_size() const
LLVM_ABI void transferSuccessorsAndUpdatePHIs(MachineBasicBlock *FromMBB)
Transfers all the successors, as in transferSuccessors, and update PHI operands in the successor bloc...
instr_iterator instr_begin()
succ_iterator succ_begin()
bool livein_empty() const
LLVM_ABI iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
LLVM_ABI DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
LLVM_ABI bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
LLVM_ABI void eraseFromParent()
This method unlinks 'this' from the containing function and deletes it.
instr_iterator instr_end()
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
iterator_range< pred_iterator > predecessors()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
LLVM_ABI void moveAfter(MachineBasicBlock *NewBefore)
LLVM_ABI BranchProbability getEdgeProbability(const MachineBasicBlock *Src, const MachineBasicBlock *Dst) const
Analysis pass which computes a MachineDominatorTree.
Analysis pass which computes a MachineDominatorTree.
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
bool dominates(const MachineInstr *A, const MachineInstr *B) 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.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Function & getFunction()
Return the LLVM function that this machine code represents.
const MachineBasicBlock & back() const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
Representation of each machine instruction.
bool isTerminator(QueryType Type=AnyInBundle) const
Returns true if this instruction part of the terminator for a basic block.
bool mayLoadOrStore(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read or modify memory.
const MachineBasicBlock * getParent() const
LLVM_ABI bool isDereferenceableInvariantLoad() const
Return true if this load instruction never traps and points to a memory location whose value doesn't ...
LLVM_ABI bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
mop_range uses()
Returns all operands which may be register uses.
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
const MachineOperand & getOperand(unsigned i) const
LLVM_ABI int findRegisterDefOperandIdx(Register Reg, const TargetRegisterInfo *TRI, bool isDead=false, bool Overlap=false) const
Returns the operand index that is a def of the specified register or -1 if it is not found.
Analysis pass that exposes the MachineLoopInfo for a machine function.
A description of a memory reference used in the backend.
MachineOperand class - Representation of each machine instruction operand.
Register getReg() const
getReg - Returns the register number.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
LLVM_ABI LLVM_READONLY MachineInstr * getVRegDef(Register Reg) const
getVRegDef - Return the machine instr that defines the specified virtual register or null if none is ...
LLVM_ABI Register createVirtualRegister(const TargetRegisterClass *RegClass, StringRef Name="")
createVirtualRegister - Create and return a new virtual register in the function with the specified r...
LLVM_ABI unsigned getResourceLength(ArrayRef< const MachineBasicBlock * > Extrablocks={}, ArrayRef< const MCSchedClassDesc * > ExtraInstrs={}, ArrayRef< const MCSchedClassDesc * > RemoveInstrs={}) const
Return the resource length of the trace.
InstrCycles getInstrCycles(const MachineInstr &MI) const
Return the depth and height of MI.
LLVM_ABI unsigned getInstrSlack(const MachineInstr &MI) const
Return the slack of MI.
unsigned getCriticalPath() const
Return the length of the (data dependency) critical path through the trace.
LLVM_ABI unsigned getPHIDepth(const MachineInstr &PHI) const
Return the Depth of a PHI instruction in a trace center block successor.
LLVM_ABI void verifyAnalysis() const
LLVM_ABI void invalidate(const MachineBasicBlock *MBB)
Invalidate cached information about MBB.
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Wrapper class representing virtual and physical registers.
MCRegister asMCReg() const
Utility to check-convert this value to a MCRegister.
constexpr bool isVirtual() const
Return true if the specified register number is in the virtual register namespace.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
void push_back(const T &Elt)
iterator erase(iterator I)
erase - Erases an existing element identified by a valid iterator.
void clear()
clear - Clears the set.
std::pair< iterator, bool > insert(const ValueT &Val)
insert - Attempts to insert a new element.
bool empty() const
empty - Returns true if the set is empty.
TargetInstrInfo - Interface to description of machine instruction set.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Provide an instruction scheduling machine model to CodeGen passes.
LLVM_ABI void init(const TargetSubtargetInfo *TSInfo, bool EnableSModel=true, bool EnableSItins=true)
Initialize the machine model for instruction scheduling.
virtual const TargetInstrInfo * getInstrInfo() const
virtual const TargetRegisterInfo * getRegisterInfo() const =0
Return the target's register information.
virtual bool enableEarlyIfConversion() const
Enable the use of the early if conversion pass.
self_iterator getIterator()
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DiagnosticInfoOptimizationBase::Argument NV
NodeAddr< NodeBase * > Node
This is an optimization pass for GlobalISel generic memory operations.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
LLVM_ABI Printable printRegUnit(MCRegUnit Unit, const TargetRegisterInfo *TRI)
Create Printable object to print register units on a raw_ostream.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Value
LLVM_ABI char & EarlyIfConverterLegacyID
EarlyIfConverter - This pass performs if-conversion on SSA form by inserting cmov instructions.
LLVM_ABI PreservedAnalyses getMachineFunctionPassPreservedAnalyses()
Returns the minimum set of Analyses that all machine function passes must preserve.
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...
auto post_order(const T &G)
Post-order traversal of a graph.
auto instructionsWithoutDebug(IterT It, IterT End, bool SkipPseudoOp=true)
Construct a range iterator which begins at It and moves forwards until End is reached,...
LLVM_ABI char & EarlyIfPredicatorID
EarlyIfPredicator - This pass performs if-conversion on SSA form by predicating if/else block and ins...
DomTreeNodeBase< MachineBasicBlock > MachineDomTreeNode
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
ArrayRef(const T &OneElt) -> ArrayRef< T >
LLVM_ABI Printable printReg(Register Reg, const TargetRegisterInfo *TRI=nullptr, unsigned SubIdx=0, const MachineRegisterInfo *MRI=nullptr)
Prints virtual and physical registers with or without a TRI instance.
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.
unsigned Depth
Earliest issue cycle as determined by data dependencies and instruction latencies from the beginning ...
MachineInstr * ConditionDef