48#define DEBUG_TYPE "early-ifcvt"
54 cl::desc(
"Maximum number of instructions per speculated block."));
63 cl::desc(
"Enable hard-to-predict branch analysis for if-conversion"));
69 cl::desc(
"Limit the number of steps taken when searching for a "
70 "recently loaded value"));
73STATISTIC(NumDiamondsConv,
"Number of diamonds converted");
75STATISTIC(NumTrianglesConv,
"Number of triangles converted");
77 "Number of data dependent conditional branches encountered");
78STATISTIC(NumLikelyBiased,
"Number of branches with a hot path encountered");
122 bool isTriangle()
const {
return TBB ==
Tail || FBB ==
Tail; }
125 MachineBasicBlock *getTPred()
const {
return TBB == Tail ? Head : TBB; }
128 MachineBasicBlock *getFPred()
const {
return FBB == Tail ? Head : FBB; }
135 int CondCycles = 0, TCycles = 0, FCycles = 0;
137 PHIInfo(MachineInstr *phi) : PHI(
phi) {}
148 SmallPtrSet<MachineInstr*, 8> InsertAfter;
151 BitVector ClobberedRegUnits;
154 SparseSet<MCRegUnit, MCRegUnit, MCRegUnitToIndex> LiveRegUnits;
162 bool canSpeculateInstrs(MachineBasicBlock *
MBB);
166 bool canPredicateInstrs(MachineBasicBlock *
MBB);
170 bool InstrDependenciesAllowIfConv(MachineInstr *
I);
174 void PredicateBlock(MachineBasicBlock *
MBB,
bool ReversePredicate);
177 bool findInsertionPoint();
180 void replacePHIInstrs();
183 void rewritePHIOperands();
187 void clearRepeatedKillFlagsFromTBB(MachineBasicBlock *TBB,
188 MachineBasicBlock *FBB);
192 void init(MachineFunction &MF) {
196 LiveRegUnits.clear();
197 LiveRegUnits.setUniverse(TRI->getNumRegUnits());
198 ClobberedRegUnits.clear();
199 ClobberedRegUnits.resize(TRI->getNumRegUnits());
206 bool canConvertIf(MachineBasicBlock *
MBB,
bool Predicate =
false);
210 void convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
211 bool Predicate =
false);
235 for (MachineInstr &
MI :
237 if (
MI.isDebugInstr())
261 bool DontMoveAcrossStore =
true;
262 if (!
MI.isSafeToMove(DontMoveAcrossStore)) {
268 if (!InstrDependenciesAllowIfConv(&
MI))
278bool SSAIfConv::InstrDependenciesAllowIfConv(MachineInstr *
I) {
279 for (
const MachineOperand &MO :
I->operands()) {
280 if (MO.isRegMask()) {
291 ClobberedRegUnits.
set(
static_cast<unsigned>(Unit));
302 LLVM_DEBUG(
dbgs() <<
"Can't insert instructions below terminator.\n");
317bool SSAIfConv::canPredicateInstrs(MachineBasicBlock *
MBB) {
332 if (
I->isDebugInstr())
360 if (!InstrDependenciesAllowIfConv(&(*
I)))
367void SSAIfConv::PredicateBlock(MachineBasicBlock *
MBB,
bool ReversePredicate) {
368 auto Condition =
Cond;
369 if (ReversePredicate) {
371 assert(CanRevCond &&
"Reversed predicate is not supported");
378 if (
I->isDebugInstr())
394bool SSAIfConv::findInsertionPoint() {
397 LiveRegUnits.
clear();
405 if (InsertAfter.
count(&*
I)) {
411 for (
const MachineOperand &MO :
I->operands()) {
421 LiveRegUnits.
erase(Unit);
427 while (!Reads.
empty())
429 if (ClobberedRegUnits.
test(
static_cast<unsigned>(Unit)))
430 LiveRegUnits.
insert(Unit);
433 if (
I != FirstTerm &&
I->isTerminator())
438 if (!LiveRegUnits.
empty()) {
440 dbgs() <<
"Would clobber";
441 for (MCRegUnit LRU : LiveRegUnits)
443 dbgs() <<
" live before " << *
I;
462bool SSAIfConv::canConvertIf(MachineBasicBlock *
MBB,
bool Predicate) {
468 MachineBasicBlock *Succ0 = Head->
succ_begin()[0];
469 MachineBasicBlock *Succ1 = Head->
succ_begin()[1];
492 if (!
Tail->livein_empty()) {
505 if (!Predicate && (
Tail->empty() || !
Tail->front().isPHI())) {
519 LLVM_DEBUG(
dbgs() <<
"analyzeBranch didn't find conditional branch.\n");
526 LLVM_DEBUG(
dbgs() <<
"analyzeBranch found an unconditional branch.\n");
532 FBB =
TBB == Succ0 ? Succ1 : Succ0;
536 MachineBasicBlock *TPred = getTPred();
537 MachineBasicBlock *FPred = getFPred();
539 I !=
E &&
I->isPHI(); ++
I) {
541 PHIInfo &PI = PHIs.
back();
543 for (
unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) {
544 if (PI.PHI->getOperand(i+1).getMBB() == TPred)
545 PI.TReg = PI.PHI->getOperand(i).getReg();
546 if (PI.PHI->getOperand(i+1).getMBB() == FPred)
547 PI.FReg = PI.PHI->getOperand(i).getReg();
549 assert(PI.TReg.isVirtual() &&
"Bad PHI");
550 assert(PI.FReg.isVirtual() &&
"Bad PHI");
553 if (!
TII->canInsertSelect(*Head,
Cond, PI.PHI->getOperand(0).getReg(),
554 PI.TReg, PI.FReg, PI.CondCycles, PI.TCycles,
563 ClobberedRegUnits.
reset();
567 if (FBB !=
Tail && !canPredicateInstrs(FBB))
572 if (FBB !=
Tail && !canSpeculateInstrs(FBB))
578 if (!findInsertionPoint())
595 if (!TReg.isVirtual() || !FReg.
isVirtual())
617 return MO.isReg() && MO.getReg().isPhysical();
622 if (!
TII->produceSameValue(*TDef, *FDef, &
MRI))
628 if (TIdx == -1 || FIdx == -1)
637void SSAIfConv::replacePHIInstrs() {
638 assert(
Tail->pred_size() == 2 &&
"Cannot replace PHIs");
640 assert(FirstTerm != Head->
end() &&
"No terminators");
641 DebugLoc HeadDL = FirstTerm->getDebugLoc();
644 for (PHIInfo &PI : PHIs) {
646 Register DstReg = PI.PHI->getOperand(0).getReg();
650 BuildMI(*Head, FirstTerm, HeadDL,
TII->get(TargetOpcode::COPY), DstReg)
653 TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg,
Cond, PI.TReg,
657 PI.PHI->eraseFromParent();
665void SSAIfConv::rewritePHIOperands() {
667 assert(FirstTerm != Head->
end() &&
"No terminators");
668 DebugLoc HeadDL = FirstTerm->getDebugLoc();
671 for (PHIInfo &PI : PHIs) {
680 Register PHIDst = PI.PHI->getOperand(0).getReg();
681 DstReg =
MRI->createVirtualRegister(
MRI->getRegClass(PHIDst));
682 TII->insertSelect(*Head, FirstTerm, HeadDL,
683 DstReg,
Cond, PI.TReg, PI.FReg);
688 for (
unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) {
689 MachineBasicBlock *
MBB = PI.PHI->getOperand(i-1).getMBB();
690 if (
MBB == getTPred()) {
691 PI.PHI->getOperand(i-1).setMBB(Head);
692 PI.PHI->getOperand(i-2).setReg(DstReg);
693 }
else if (
MBB == getFPred()) {
694 PI.PHI->removeOperand(i-1);
695 PI.PHI->removeOperand(i-2);
702void SSAIfConv::clearRepeatedKillFlagsFromTBB(MachineBasicBlock *
TBB,
703 MachineBasicBlock *FBB) {
707 SmallDenseSet<Register> FBBKilledRegs;
708 for (MachineInstr &
MI : FBB->
instrs()) {
709 for (MachineOperand &MO :
MI.operands()) {
710 if (MO.isReg() && MO.isKill() && MO.getReg().isVirtual())
711 FBBKilledRegs.
insert(MO.getReg());
715 if (FBBKilledRegs.
empty())
720 for (MachineOperand &MO :
MI.operands()) {
721 if (MO.isReg() && MO.isKill() && FBBKilledRegs.
contains(MO.getReg()))
732void SSAIfConv::convertIf(SmallVectorImpl<MachineBasicBlock *> &RemoveBlocks,
734 assert(Head &&
Tail &&
TBB && FBB &&
"Call canConvertIf first.");
747 clearRepeatedKillFlagsFromTBB(
TBB, FBB);
752 PredicateBlock(
TBB,
false);
757 PredicateBlock(FBB,
true);
761 bool ExtraPreds =
Tail->pred_size() != 2;
763 rewritePHIOperands();
803 if (
Tail != &
Tail->getParent()->back())
804 Tail->moveAfter(&
Tail->getParent()->back());
820class EarlyIfConverter {
821 const TargetInstrInfo *
TII =
nullptr;
822 const TargetRegisterInfo *
TRI =
nullptr;
823 MCSchedModel SchedModel;
824 MachineRegisterInfo *
MRI =
nullptr;
825 MachineDominatorTree *DomTree =
nullptr;
826 MachineLoopInfo *
Loops =
nullptr;
827 MachineTraceMetrics *Traces =
nullptr;
829 MachineBranchProbabilityInfo *MBPI =
nullptr;
833 EarlyIfConverter(MachineDominatorTree &DT, MachineLoopInfo &LI,
834 MachineTraceMetrics &MTM, MachineBranchProbabilityInfo *MBPI)
835 : DomTree(&DT),
Loops(&LI), Traces(&MTM), MBPI(MBPI) {}
836 EarlyIfConverter() =
delete;
838 bool run(MachineFunction &MF);
841 bool tryConvertIf(MachineBasicBlock *);
842 void invalidateTraces();
843 bool shouldConvertIf();
844 bool isConditionDataDependent();
848class EarlyIfConverterLegacy :
public MachineFunctionPass {
851 EarlyIfConverterLegacy() : MachineFunctionPass(
ID) {}
852 void getAnalysisUsage(AnalysisUsage &AU)
const override;
853 bool runOnMachineFunction(MachineFunction &MF)
override;
854 StringRef getPassName()
const override {
return "Early If-Conversion"; }
858char EarlyIfConverterLegacy::ID = 0;
869void EarlyIfConverterLegacy::getAnalysisUsage(
AnalysisUsage &AU)
const {
882void updateDomTree(MachineDominatorTree *DomTree,
const SSAIfConv &IfConv,
888 for (
auto *
B : Removed) {
890 assert(Node != HeadNode &&
"Cannot erase the head node");
891 while (!
Node->isLeaf()) {
892 assert(
Node->getBlock() == IfConv.Tail &&
"Unexpected children");
900void updateLoops(MachineLoopInfo *
Loops,
904 for (
auto *
B : Removed)
910void EarlyIfConverter::invalidateTraces() {
921 const PseudoSourceValue *PSV = MOp->getPseudoValue();
922 return PSV && PSV->isConstantPool();
928 constexpr int MaxInstructionsToCheck = 64;
933 return ++
Count > MaxInstructionsToCheck ||
MI.isCall();
943bool EarlyIfConverter::doOperandsComeFromMemory(
Register Reg) {
948 SmallPtrSet<const MachineInstr *, 8> VisitedInstrs;
949 SmallVector<const MachineInstr *> Worklist;
950 SmallVector<Register, 16> VisitedRegs;
963 if (!VisitedInstrs.
insert(
MI).second)
967 if (
MI->getParent() != IfConv.Head)
974 !
MI->isDereferenceableInvariantLoad() &&
979 for (
const MachineOperand &MO :
MI->operands()) {
980 if (!MO.isReg() || !MO.isUse())
986 if (MachineInstr *UseDef =
MRI->getVRegDef(
UseReg)) {
987 if (!VisitedInstrs.
count(UseDef)) {
999bool EarlyIfConverter::isConditionDataDependent() {
1000 TargetInstrInfo::MachineBranchPredicate MBP;
1001 if (
TII->analyzeBranchPredicate(*IfConv.Head, MBP,
false))
1012 if (TBBProb != FBBProb) {
1030 if (Delta < 0 && Cyc + Delta > Cyc)
1042 return R <<
ore::NV(
C.Key,
C.Value) << (
C.Value == 1 ?
" cycle" :
" cycles");
1049bool EarlyIfConverter::shouldConvertIf() {
1056 MachineLoop *CurrentLoop =
Loops->getLoopFor(IfConv.Head);
1062 if (CurrentLoop &&
any_of(IfConv.Cond, [&](MachineOperand &MO) {
1063 if (!MO.isReg() || !MO.isUse())
1065 Register Reg = MO.getReg();
1066 if (Reg.isPhysical())
1069 MachineInstr *Def = MRI->getVRegDef(Reg);
1070 return CurrentLoop->isLoopInvariant(*Def) ||
1071 all_of(Def->operands(), [&](MachineOperand &Op) {
1074 if (!Op.isReg() || !Op.isUse())
1076 Register Reg = Op.getReg();
1077 if (Reg.isPhysical())
1080 MachineInstr *Def = MRI->getVRegDef(Reg);
1081 return CurrentLoop->isLoopInvariant(*Def);
1087 MinInstr = Traces->getEnsemble(MachineTraceStrategy::TS_MinInstrCount);
1091 LLVM_DEBUG(
dbgs() <<
"TBB: " << TBBTrace <<
"FBB: " << FBBTrace);
1098 bool DataDependent =
false;
1100 DataDependent = isConditionDataDependent();
1102 unsigned CritLimit = DataDependent ? SchedModel.MispredictPenalty
1103 : SchedModel.MispredictPenalty / 2;
1105 MachineBasicBlock &
MBB = *IfConv.Head;
1109 if (DataDependent) {
1111 return MachineOptimizationRemarkAnalysis(
DEBUG_TYPE,
1112 "DataDependentCondition",
1114 <<
"branch condition is data-dependent (from memory load), "
1115 <<
"using higher CritLimit of " <<
ore::NV(
"CritLimit", CritLimit)
1124 if (IfConv.TBB != IfConv.Tail)
1128 <<
", minimal critical path " << MinCrit <<
'\n');
1129 if (ResLength > MinCrit + CritLimit) {
1132 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"IfConversion",
1134 R <<
"did not if-convert branch: the resulting critical path ("
1135 << Cycles{
"ResLength", ResLength}
1136 <<
") would extend the shorter leg's critical path ("
1137 << Cycles{
"MinCrit", MinCrit} <<
") by more than the threshold of "
1138 << Cycles{
"CritLimit", CritLimit}
1139 <<
", which cannot be hidden by available ILP.";
1149 unsigned BranchDepth =
1156 struct CriticalPathInfo {
1160 CriticalPathInfo
Cond{};
1161 CriticalPathInfo TBlock{};
1162 CriticalPathInfo FBlock{};
1163 bool ShouldConvert =
true;
1164 for (SSAIfConv::PHIInfo &PI : IfConv.PHIs) {
1170 unsigned CondDepth =
adjCycles(BranchDepth, PI.CondCycles);
1171 if (CondDepth > MaxDepth) {
1172 unsigned Extra = CondDepth - MaxDepth;
1173 LLVM_DEBUG(
dbgs() <<
"Condition adds " << Extra <<
" cycles.\n");
1174 if (Extra >
Cond.Extra)
1175 Cond = {Extra, CondDepth};
1176 if (Extra > CritLimit) {
1178 ShouldConvert =
false;
1184 if (TDepth > MaxDepth) {
1185 unsigned Extra = TDepth - MaxDepth;
1187 if (Extra > TBlock.Extra)
1188 TBlock = {Extra, TDepth};
1189 if (Extra > CritLimit) {
1191 ShouldConvert =
false;
1197 if (FDepth > MaxDepth) {
1198 unsigned Extra = FDepth - MaxDepth;
1200 if (Extra > FBlock.Extra)
1201 FBlock = {Extra, FDepth};
1202 if (Extra > CritLimit) {
1204 ShouldConvert =
false;
1212 const CriticalPathInfo
Short = TBlock.Extra > FBlock.Extra ? FBlock : TBlock;
1213 const CriticalPathInfo
Long = TBlock.Extra > FBlock.Extra ? TBlock : FBlock;
1215 if (ShouldConvert) {
1217 MachineOptimizationRemark
R(
DEBUG_TYPE,
"IfConversion",
1219 R <<
"performing if-conversion on branch: the condition adds "
1220 << Cycles{
"CondCycles",
Cond.Extra} <<
" to the critical path";
1221 if (
Short.Extra > 0)
1222 R <<
", and the short leg adds another "
1223 << Cycles{
"ShortCycles",
Short.Extra};
1225 R <<
", and the long leg adds another "
1226 << Cycles{
"LongCycles",
Long.Extra};
1227 R <<
", each staying under the threshold of "
1228 << Cycles{
"CritLimit", CritLimit} <<
".";
1233 MachineOptimizationRemarkMissed
R(
DEBUG_TYPE,
"IfConversion",
1235 R <<
"did not if-convert branch: the condition would add "
1236 << Cycles{
"CondCycles",
Cond.Extra} <<
" to the critical path";
1237 if (
Cond.Extra > CritLimit)
1238 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1239 if (
Short.Extra > 0) {
1240 R <<
", and the short leg would add another "
1241 << Cycles{
"ShortCycles",
Short.Extra};
1242 if (
Short.Extra > CritLimit)
1243 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1245 if (
Long.Extra > 0) {
1246 R <<
", and the long leg would add another "
1247 << Cycles{
"LongCycles",
Long.Extra};
1248 if (
Long.Extra > CritLimit)
1249 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1256 return ShouldConvert;
1261bool EarlyIfConverter::tryConvertIf(MachineBasicBlock *
MBB) {
1263 while (IfConv.canConvertIf(
MBB) && shouldConvertIf()) {
1266 SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
1267 IfConv.convertIf(RemoveBlocks);
1269 updateDomTree(DomTree, IfConv, RemoveBlocks);
1270 for (MachineBasicBlock *
MBB : RemoveBlocks)
1272 updateLoops(
Loops, RemoveBlocks);
1277bool EarlyIfConverter::run(MachineFunction &MF) {
1278 LLVM_DEBUG(
dbgs() <<
"********** EARLY IF-CONVERSION **********\n"
1279 <<
"********** Function: " << MF.
getName() <<
'\n');
1300 if (tryConvertIf(DomNode->getBlock()))
1316 EarlyIfConverter Impl(MDT, LI, MTM, MBPI);
1328bool EarlyIfConverterLegacy::runOnMachineFunction(
MachineFunction &MF) {
1333 getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1334 MachineLoopInfo &LI = getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1336 getAnalysis<MachineTraceMetricsWrapperPass>().getMTM();
1339 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1341 return EarlyIfConverter(MDT, LI, MTM, MBPI).run(MF);
1362 void getAnalysisUsage(AnalysisUsage &AU)
const override;
1363 bool runOnMachineFunction(MachineFunction &MF)
override;
1364 StringRef getPassName()
const override {
return "Early If-predicator"; }
1367 bool tryConvertIf(MachineBasicBlock *);
1368 bool shouldConvertIf();
1373#define DEBUG_TYPE "early-if-predicator"
1375char EarlyIfPredicator::ID = 0;
1385void EarlyIfPredicator::getAnalysisUsage(
AnalysisUsage &AU)
const {
1395bool EarlyIfPredicator::shouldConvertIf() {
1397 if (IfConv.isTriangle()) {
1398 MachineBasicBlock &IfBlock =
1399 (IfConv.TBB == IfConv.Tail) ? *IfConv.FBB : *IfConv.
TBB;
1401 unsigned ExtraPredCost = 0;
1402 unsigned Cycles = 0;
1403 for (MachineInstr &
I : IfBlock) {
1404 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1406 Cycles += NumCycles - 1;
1407 ExtraPredCost +=
TII->getPredicationCost(
I);
1413 unsigned TExtra = 0;
1414 unsigned FExtra = 0;
1415 unsigned TCycle = 0;
1416 unsigned FCycle = 0;
1417 for (MachineInstr &
I : *IfConv.TBB) {
1418 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1420 TCycle += NumCycles - 1;
1421 TExtra +=
TII->getPredicationCost(
I);
1423 for (MachineInstr &
I : *IfConv.FBB) {
1424 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1426 FCycle += NumCycles - 1;
1427 FExtra +=
TII->getPredicationCost(
I);
1430 FCycle, FExtra, TrueProbability);
1435bool EarlyIfPredicator::tryConvertIf(MachineBasicBlock *
MBB) {
1437 while (IfConv.canConvertIf(
MBB,
true) && shouldConvertIf()) {
1439 SmallVector<MachineBasicBlock *, 4> RemoveBlocks;
1440 IfConv.convertIf(RemoveBlocks,
true);
1442 updateDomTree(DomTree, IfConv, RemoveBlocks);
1443 for (MachineBasicBlock *
MBB : RemoveBlocks)
1445 updateLoops(
Loops, RemoveBlocks);
1450bool EarlyIfPredicator::runOnMachineFunction(MachineFunction &MF) {
1451 LLVM_DEBUG(
dbgs() <<
"********** EARLY IF-PREDICATOR **********\n"
1452 <<
"********** Function: " << MF.
getName() <<
'\n');
1460 SchedModel.
init(&STI);
1461 DomTree = &getAnalysis<MachineDominatorTreeWrapperPass>().getDomTree();
1462 Loops = &getAnalysis<MachineLoopInfoWrapperPass>().getLI();
1463 MBPI = &getAnalysis<MachineBranchProbabilityInfoWrapperPass>().getMBPI();
1473 if (tryConvertIf(DomNode->getBlock()))
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file implements the BitVector class.
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 DenseSet and SmallDenseSet classes.
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 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 bool callInRange(const MachineInstr *From, const MachineInstr *To)
Check if there are any calls in the range (From, To].
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.
const SmallVectorImpl< MachineOperand > MachineBasicBlock * TBB
const SmallVectorImpl< MachineOperand > & Cond
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
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.
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.
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
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...
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.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
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)
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...
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,...
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.
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.
unsigned getPHIDepth(const MachineInstr &PHI) const
Return the Depth of a PHI instruction in a trace center block successor.
void verifyAnalysis() const
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.
std::pair< iterator, bool > insert(const ValueT &V)
bool contains(const_arg_type_t< ValueT > V) const
Check if the set contains the given element.
self_iterator getIterator()
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ Tail
Attemps to make calls as fast as possible while guaranteeing that tail call optimization can always b...
@ C
The default llvm calling convention, compatible with C.
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.
FunctionAddr VTableAddr Value
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.
iterator_range< po_iterator< T > > post_order(const T &G)
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
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.
FunctionAddr VTableAddr Count
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
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 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