43#define DEBUG_TYPE "early-ifcvt"
49 cl::desc(
"Maximum number of instructions per speculated block."));
56STATISTIC(NumDiamondsConv,
"Number of diamonds converted");
58STATISTIC(NumTrianglesConv,
"Number of triangles converted");
102 bool isTriangle()
const {
return TBB ==
Tail || FBB ==
Tail; }
113 unsigned TReg = 0, FReg = 0;
115 int CondCycles = 0, TCycles = 0, FCycles = 0;
157 bool findInsertionPoint();
160 void replacePHIInstrs();
163 void rewritePHIOperands();
173 ClobberedRegUnits.
clear();
174 ClobberedRegUnits.
resize(
TRI->getNumRegUnits());
186 bool Predicate =
false);
213 if (
MI.isDebugInstr())
237 bool DontMoveAcrossStore =
true;
238 if (!
MI.isSafeToMove(
nullptr, DontMoveAcrossStore)) {
244 if (!InstrDependenciesAllowIfConv(&
MI))
254bool SSAIfConv::InstrDependenciesAllowIfConv(
MachineInstr *
I) {
256 if (MO.isRegMask()) {
265 if (MO.isDef() &&
Reg.isPhysical())
268 ClobberedRegUnits.
set(*Units);
270 if (!MO.readsReg() || !
Reg.isVirtual())
279 LLVM_DEBUG(
dbgs() <<
"Can't insert instructions below terminator.\n");
309 if (
I->isDebugInstr())
337 if (!InstrDependenciesAllowIfConv(&(*
I)))
345 auto Condition =
Cond;
346 if (ReversePredicate) {
348 assert(CanRevCond &&
"Reversed predicate is not supported");
355 if (
I->isDebugInstr())
371bool SSAIfConv::findInsertionPoint() {
382 if (InsertAfter.
count(&*
I)) {
393 if (!
Reg.isPhysical())
405 while (!Reads.
empty())
408 if (ClobberedRegUnits.
test(*Units))
412 if (
I != FirstTerm &&
I->isTerminator())
419 dbgs() <<
"Would clobber";
422 dbgs() <<
" live before " << *
I;
471 if (!
Tail->livein_empty()) {
484 if (!Predicate && (
Tail->empty() || !
Tail->front().isPHI())) {
498 LLVM_DEBUG(
dbgs() <<
"analyzeBranch didn't find conditional branch.\n");
505 LLVM_DEBUG(
dbgs() <<
"analyzeBranch found an unconditional branch.\n");
511 FBB =
TBB == Succ0 ? Succ1 : Succ0;
518 I !=
E &&
I->isPHI(); ++
I) {
520 PHIInfo &PI = PHIs.
back();
522 for (
unsigned i = 1; i != PI.PHI->getNumOperands(); i += 2) {
523 if (PI.PHI->getOperand(i+1).getMBB() == TPred)
524 PI.TReg = PI.PHI->getOperand(i).getReg();
525 if (PI.PHI->getOperand(i+1).getMBB() == FPred)
526 PI.FReg = PI.PHI->getOperand(i).getReg();
532 if (!
TII->canInsertSelect(*Head,
Cond, PI.PHI->getOperand(0).getReg(),
533 PI.TReg, PI.FReg, PI.CondCycles, PI.TCycles,
542 ClobberedRegUnits.
reset();
546 if (FBB !=
Tail && !canPredicateInstrs(FBB))
551 if (FBB !=
Tail && !canSpeculateInstrs(FBB))
557 if (!findInsertionPoint())
596 return MO.isReg() && MO.getReg().isPhysical();
601 if (!
TII->produceSameValue(*TDef, *FDef, &
MRI))
607 if (TIdx == -1 || FIdx == -1)
616void SSAIfConv::replacePHIInstrs() {
617 assert(
Tail->pred_size() == 2 &&
"Cannot replace PHIs");
619 assert(FirstTerm != Head->
end() &&
"No terminators");
620 DebugLoc HeadDL = FirstTerm->getDebugLoc();
623 for (
unsigned i = 0, e = PHIs.
size(); i != e; ++i) {
624 PHIInfo &PI = PHIs[i];
626 Register DstReg = PI.PHI->getOperand(0).getReg();
630 BuildMI(*Head, FirstTerm, HeadDL,
TII->get(TargetOpcode::COPY), DstReg)
633 TII->insertSelect(*Head, FirstTerm, HeadDL, DstReg,
Cond, PI.TReg,
637 PI.PHI->eraseFromParent();
645void SSAIfConv::rewritePHIOperands() {
647 assert(FirstTerm != Head->
end() &&
"No terminators");
648 DebugLoc HeadDL = FirstTerm->getDebugLoc();
651 for (
unsigned i = 0, e = PHIs.
size(); i != e; ++i) {
652 PHIInfo &PI = PHIs[i];
661 Register PHIDst = PI.PHI->getOperand(0).getReg();
662 DstReg =
MRI->createVirtualRegister(
MRI->getRegClass(PHIDst));
663 TII->insertSelect(*Head, FirstTerm, HeadDL,
664 DstReg,
Cond, PI.TReg, PI.FReg);
669 for (
unsigned i = PI.PHI->getNumOperands(); i != 1; i -= 2) {
671 if (
MBB == getTPred()) {
672 PI.PHI->getOperand(i-1).setMBB(Head);
673 PI.PHI->getOperand(i-2).setReg(DstReg);
674 }
else if (
MBB == getFPred()) {
675 PI.PHI->removeOperand(i-1);
676 PI.PHI->removeOperand(i-2);
690 assert(Head &&
Tail &&
TBB && FBB &&
"Call canConvertIf first.");
701 PredicateBlock(
TBB,
false);
706 PredicateBlock(FBB,
true);
710 bool ExtraPreds =
Tail->pred_size() != 2;
712 rewritePHIOperands();
749 Tail->eraseFromParent();
785 void invalidateTraces();
786 bool shouldConvertIf();
790char EarlyIfConverter::ID = 0;
794 "Early If Converter",
false,
false)
801void EarlyIfConverter::getAnalysisUsage(
AnalysisUsage &AU)
const {
820 for (
auto *
B : Removed) {
822 assert(
Node != HeadNode &&
"Cannot erase the head node");
823 while (
Node->getNumChildren()) {
824 assert(
Node->getBlock() == IfConv.Tail &&
"Unexpected children");
838 for (
auto *
B : Removed)
844void EarlyIfConverter::invalidateTraces() {
845 Traces->verifyAnalysis();
846 Traces->invalidate(IfConv.Head);
847 Traces->invalidate(IfConv.Tail);
848 Traces->invalidate(IfConv.TBB);
849 Traces->invalidate(IfConv.FBB);
850 Traces->verifyAnalysis();
855 if (Delta < 0 && Cyc + Delta > Cyc)
867 return R <<
ore::NV(
C.Key,
C.Value) << (
C.Value == 1 ?
" cycle" :
" cycles");
874bool EarlyIfConverter::shouldConvertIf() {
888 if (!MO.isReg() || !MO.isUse())
890 Register Reg = MO.getReg();
891 if (Register::isPhysicalRegister(Reg))
894 MachineInstr *Def = MRI->getVRegDef(Reg);
895 return CurrentLoop->isLoopInvariant(*Def) ||
896 all_of(Def->operands(), [&](MachineOperand &Op) {
899 if (!MO.isReg() || !MO.isUse())
901 Register Reg = MO.getReg();
902 if (Register::isPhysicalRegister(Reg))
905 MachineInstr *Def = MRI->getVRegDef(Reg);
906 return CurrentLoop->isLoopInvariant(*Def);
912 MinInstr = Traces->getEnsemble(MachineTraceStrategy::TS_MinInstrCount);
921 unsigned CritLimit = SchedModel.MispredictPenalty/2;
930 if (IfConv.TBB != IfConv.Tail)
934 <<
", minimal critical path " << MinCrit <<
'\n');
935 if (ResLength > MinCrit + CritLimit) {
940 R <<
"did not if-convert branch: the resulting critical path ("
941 << Cycles{
"ResLength", ResLength}
942 <<
") would extend the shorter leg's critical path ("
943 << Cycles{
"MinCrit", MinCrit} <<
") by more than the threshold of "
944 << Cycles{
"CritLimit", CritLimit}
945 <<
", which cannot be hidden by available ILP.";
955 unsigned BranchDepth =
962 struct CriticalPathInfo {
966 CriticalPathInfo
Cond{};
967 CriticalPathInfo TBlock{};
968 CriticalPathInfo FBlock{};
969 bool ShouldConvert =
true;
970 for (
unsigned i = 0, e = IfConv.PHIs.size(); i != e; ++i) {
971 SSAIfConv::PHIInfo &PI = IfConv.PHIs[i];
977 unsigned CondDepth =
adjCycles(BranchDepth, PI.CondCycles);
979 unsigned Extra = CondDepth -
MaxDepth;
981 if (Extra >
Cond.Extra)
982 Cond = {Extra, CondDepth};
983 if (Extra > CritLimit) {
985 ShouldConvert =
false;
994 if (Extra > TBlock.Extra)
995 TBlock = {Extra, TDepth};
996 if (Extra > CritLimit) {
998 ShouldConvert =
false;
1005 unsigned Extra = FDepth -
MaxDepth;
1007 if (Extra > FBlock.Extra)
1008 FBlock = {Extra, FDepth};
1009 if (Extra > CritLimit) {
1011 ShouldConvert =
false;
1019 const CriticalPathInfo
Short = TBlock.Extra > FBlock.Extra ? FBlock : TBlock;
1020 const CriticalPathInfo
Long = TBlock.Extra > FBlock.Extra ? TBlock : FBlock;
1022 if (ShouldConvert) {
1026 R <<
"performing if-conversion on branch: the condition adds "
1027 << Cycles{
"CondCycles",
Cond.Extra} <<
" to the critical path";
1028 if (
Short.Extra > 0)
1029 R <<
", and the short leg adds another "
1030 << Cycles{
"ShortCycles",
Short.Extra};
1032 R <<
", and the long leg adds another "
1033 << Cycles{
"LongCycles",
Long.Extra};
1034 R <<
", each staying under the threshold of "
1035 << Cycles{
"CritLimit", CritLimit} <<
".";
1042 R <<
"did not if-convert branch: the condition would add "
1043 << Cycles{
"CondCycles",
Cond.Extra} <<
" to the critical path";
1044 if (
Cond.Extra > CritLimit)
1045 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1046 if (
Short.Extra > 0) {
1047 R <<
", and the short leg would add another "
1048 << Cycles{
"ShortCycles",
Short.Extra};
1049 if (
Short.Extra > CritLimit)
1050 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1052 if (
Long.Extra > 0) {
1053 R <<
", and the long leg would add another "
1054 << Cycles{
"LongCycles",
Long.Extra};
1055 if (
Long.Extra > CritLimit)
1056 R <<
" exceeding the limit of " << Cycles{
"CritLimit", CritLimit};
1063 return ShouldConvert;
1069 bool Changed =
false;
1070 while (IfConv.canConvertIf(
MBB) && shouldConvertIf()) {
1074 IfConv.convertIf(RemovedBlocks);
1076 updateDomTree(DomTree, IfConv, RemovedBlocks);
1077 updateLoops(
Loops, RemovedBlocks);
1083 LLVM_DEBUG(
dbgs() <<
"********** EARLY IF-CONVERSION **********\n"
1084 <<
"********** Function: " << MF.
getName() <<
'\n');
1097 DomTree = &getAnalysis<MachineDominatorTree>();
1098 Loops = getAnalysisIfAvailable<MachineLoopInfo>();
1099 Traces = &getAnalysis<MachineTraceMetrics>();
1102 bool Changed =
false;
1103 IfConv.runOnMachineFunction(MF);
1110 if (tryConvertIf(DomNode->getBlock()))
1140 bool shouldConvertIf();
1145#define DEBUG_TYPE "early-if-predicator"
1147char EarlyIfPredicator::ID = 0;
1157void EarlyIfPredicator::getAnalysisUsage(
AnalysisUsage &AU)
const {
1167bool EarlyIfPredicator::shouldConvertIf() {
1168 auto TrueProbability = MBPI->getEdgeProbability(IfConv.Head, IfConv.TBB);
1169 if (IfConv.isTriangle()) {
1171 (IfConv.TBB == IfConv.Tail) ? *IfConv.FBB : *IfConv.TBB;
1173 unsigned ExtraPredCost = 0;
1174 unsigned Cycles = 0;
1176 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1178 Cycles += NumCycles - 1;
1179 ExtraPredCost +=
TII->getPredicationCost(
I);
1185 unsigned TExtra = 0;
1186 unsigned FExtra = 0;
1187 unsigned TCycle = 0;
1188 unsigned FCycle = 0;
1190 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1192 TCycle += NumCycles - 1;
1193 TExtra +=
TII->getPredicationCost(
I);
1196 unsigned NumCycles = SchedModel.computeInstrLatency(&
I,
false);
1198 FCycle += NumCycles - 1;
1199 FExtra +=
TII->getPredicationCost(
I);
1202 FCycle, FExtra, TrueProbability);
1208 bool Changed =
false;
1209 while (IfConv.canConvertIf(
MBB,
true) && shouldConvertIf()) {
1212 IfConv.convertIf(RemovedBlocks,
true);
1214 updateDomTree(DomTree, IfConv, RemovedBlocks);
1215 updateLoops(
Loops, RemovedBlocks);
1221 LLVM_DEBUG(
dbgs() <<
"********** EARLY IF-PREDICATOR **********\n"
1222 <<
"********** Function: " << MF.
getName() <<
'\n');
1230 SchedModel.init(&STI);
1231 DomTree = &getAnalysis<MachineDominatorTree>();
1232 Loops = getAnalysisIfAvailable<MachineLoopInfo>();
1233 MBPI = &getAnalysis<MachineBranchProbabilityInfo>();
1235 bool Changed =
false;
1236 IfConv.runOnMachineFunction(MF);
1243 if (tryConvertIf(DomNode->getBlock()))
unsigned const MachineRegisterInfo * MRI
MachineInstrBuilder MachineInstrBuilder & DefMI
SmallVector< MachineOperand, 4 > Cond
This file implements the BitVector class.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static unsigned InstrCount
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."))
const HexagonInstrInfo * TII
static const unsigned MaxDepth
unsigned const TargetRegisterInfo * TRI
#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
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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)
Represent the analysis usage information of a pass.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool test(unsigned Idx) const
void resize(unsigned N, bool t=false)
resize - Grow or shrink the bitvector.
void clear()
clear - Removes all bits from the bitvector.
Base class for the actual dominator tree node.
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.
A set of register units used to track register liveness.
bool empty() const
Returns true if the set is empty.
void clear()
Clears the set.
bool isValid() const
isValid - returns true if this iterator is not yet at the end.
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
unsigned pred_size() const
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
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
unsigned succ_size() const
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
void removeSuccessor(MachineBasicBlock *Succ, bool NormalizeSuccProbs=false)
Remove successor from the successors list of this MachineBasicBlock.
DebugLoc findDebugLoc(instr_iterator MBBI)
Find the next valid DebugLoc starting at MBBI, skipping any debug instructions.
bool isLayoutSuccessor(const MachineBasicBlock *MBB) const
Return true if the specified MBB will be emitted immediately after this block, such that if this bloc...
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 '...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
MachineDomTreeNode * getNode(MachineBasicBlock *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
void eraseNode(MachineBasicBlock *BB)
eraseNode - Removes a node from the dominator tree.
void changeImmediateDominator(MachineBasicBlock *N, MachineBasicBlock *NewIDom)
changeImmediateDominator - This method is used to update the dominator tree information when a node's...
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.
virtual bool runOnMachineFunction(MachineFunction &MF)=0
runOnMachineFunction - This method must be overloaded to perform the desired machine code transformat...
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 MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, 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
int findRegisterDefOperandIdx(Register Reg, bool isDead=false, bool Overlap=false, const TargetRegisterInfo *TRI=nullptr) const
Returns the operand index that is a def of the specified register or -1 if it is not found.
bool isDereferenceableInvariantLoad() const
Return true if this load instruction never traps and points to a memory location whose value doesn't ...
iterator_range< mop_iterator > uses()
Returns a range that includes all operands that are register uses.
bool hasUnmodeledSideEffects() const
Return true if this instruction has side effects that are not modeled by mayLoad / mayStore,...
const DebugLoc & getDebugLoc() const
Returns the debug location id of this MachineInstr.
MachineOperand class - Representation of each machine instruction operand.
MachineRegisterInfo - Keep track of information for virtual and physical registers,...
A trace ensemble is a collection of traces selected using the same strategy, for example 'minimum res...
A trace represents a plausible sequence of executed basic blocks that passes through the current basi...
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 getResourceLength(ArrayRef< const MachineBasicBlock * > Extrablocks=std::nullopt, ArrayRef< const MCSchedClassDesc * > ExtraInstrs=std::nullopt, ArrayRef< const MCSchedClassDesc * > RemoveInstrs=std::nullopt) const
Return the resource length of the trace.
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.
virtual StringRef getPassName() const
getPassName - Return a nice clean name for a pass.
Wrapper class representing virtual and physical registers.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
bool isVirtual() const
Return true if the specified register number is in the virtual 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.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
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.
StringRef - Represent a constant reference to a string, i.e.
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.
TargetSubtargetInfo - Generic base class for all target subtargets.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
virtual const TargetInstrInfo * getInstrInfo() const
virtual bool enableEarlyIfConversion() const
Enable the use of the early if conversion pass.
LLVM Value Representation.
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.
Reg
All possible values of the reg field in the ModR/M byte.
initializer< Ty > init(const Ty &Val)
DiagnosticInfoOptimizationBase::Argument NV
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.
Printable printRegUnit(unsigned 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)
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
char & EarlyIfPredicatorID
EarlyIfPredicator - This pass performs if-conversion on SSA form by predicating if/else block and ins...
char & EarlyIfConverterID
EarlyIfConverter - This pass performs if-conversion on SSA form by inserting cmov instructions.
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
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.
Machine model for scheduling, bundling, and heuristics.
unsigned Depth
Earliest issue cycle as determined by data dependencies and instruction latencies from the beginning ...