41 #define DEBUG_TYPE "machine-licm"
45 cl::desc(
"MachineLICM should avoid speculation"),
50 cl::desc(
"MachineLICM should hoist even cheap instructions"),
55 cl::desc(
"MachineLICM should sink instructions into "
56 "loops to avoid register spills"),
60 "Number of machine instructions hoisted out of loops");
62 "Number of instructions hoisted in low reg pressure situation");
64 "Number of high latency instructions hoisted");
66 "Number of hoisted machine instructions CSEed");
68 "Number of machine instructions hoisted out of loops post regalloc");
121 unsigned SpeculationState;
130 explicit MachineLICM(
bool PreRA) :
146 void releaseMemory()
override {
156 struct CandidateInfo {
161 :
MI(mi),
Def(def), FI(fi) {}
164 void HoistRegionPostRA();
172 void AddToLiveIns(
unsigned Reg);
198 void ExitScopeIfDone(
213 bool ConsiderUnseenAsDef);
216 bool ConsiderUnseenAsDef =
false);
222 std::vector<const MachineInstr *> &PrevMIs);
226 DenseMap<
unsigned, std::vector<const MachineInstr *>>::iterator &CI);
241 "Machine Loop Invariant Code Motion",
false,
false)
251 if (!CurLoop->getLoopPredecessor())
265 Changed = FirstInLoop =
false;
274 PreRegAlloc =
MRI->isSSA();
277 DEBUG(
dbgs() <<
"******** Pre-regalloc Machine LICM: ");
279 DEBUG(
dbgs() <<
"******** Post-regalloc Machine LICM: ");
284 unsigned NumRPS = TRI->getNumRegPressureSets();
287 RegLimit.resize(NumRPS);
288 for (
unsigned i = 0, e = NumRPS;
i != e; ++
i)
289 RegLimit[
i] = TRI->getRegPressureSetLimit(MF,
i);
293 MLI = &getAnalysis<MachineLoopInfo>();
294 DT = &getAnalysis<MachineDominatorTree>();
295 AA = &getAnalysis<AAResultsWrapperPass>().getAAResults();
298 while (!Worklist.empty()) {
300 CurPreheader =
nullptr;
306 Worklist.append(CurLoop->begin(), CurLoop->end());
310 CurLoop->getExitBlocks(ExitBlocks);
337 if (!MemOp->isStore() || !MemOp->getPseudoValue())
340 dyn_cast<FixedStackPseudoSourceValue>(MemOp->getPseudoValue())) {
341 if (
Value->getFrameIndex() == FI)
355 bool RuledOut =
false;
356 bool HasNonInvariantUse =
false;
361 int FI = MO.getIndex();
362 if (!StoredFIs.
count(FI) &&
363 MFI->isSpillSlotObjectIndex(FI) &&
366 HasNonInvariantUse =
true;
372 if (MO.isRegMask()) {
379 unsigned Reg = MO.getReg();
383 "Not expecting virtual register!");
386 if (Reg && (PhysRegDefs.
test(Reg) || PhysRegClobbers.
test(Reg)))
389 HasNonInvariantUse =
true;
393 if (MO.isImplicit()) {
395 PhysRegClobbers.
set(*AI);
415 if (PhysRegDefs.
test(*AS))
416 PhysRegClobbers.
set(*AS);
417 PhysRegDefs.
set(*AS);
419 if (PhysRegClobbers.
test(Reg))
427 if (Def && !RuledOut) {
429 if ((!HasNonInvariantUse && IsLICMCandidate(*MI)) ||
431 Candidates.
push_back(CandidateInfo(MI, Def, FI));
437 void MachineLICM::HoistRegionPostRA() {
442 unsigned NumRegs = TRI->getNumRegs();
451 const std::vector<MachineBasicBlock *> &Blocks = CurLoop->getBlocks();
456 if (ML && ML->
getHeader()->isEHPad())
continue;
461 for (
const auto &LI : BB->liveins()) {
463 PhysRegDefs.
set(*AI);
466 SpeculationState = SpeculateUnknown;
468 ProcessMI(&MI, PhysRegDefs, PhysRegClobbers, StoredFIs, Candidates);
474 if (TI != Preheader->
end()) {
478 unsigned Reg = MO.getReg();
494 for (CandidateInfo &Candidate : Candidates) {
495 if (Candidate.FI != INT_MIN &&
496 StoredFIs.
count(Candidate.FI))
499 unsigned Def = Candidate.Def;
500 if (!PhysRegClobbers.
test(Def) && !TermRegs.test(Def)) {
504 if (!MO.isReg() || MO.isDef() || !MO.getReg())
506 unsigned Reg = MO.getReg();
507 if (PhysRegDefs.
test(Reg) ||
508 PhysRegClobbers.
test(Reg)) {
516 HoistPostRA(MI, Candidate.Def);
523 void MachineLICM::AddToLiveIns(
unsigned Reg) {
524 const std::vector<MachineBasicBlock *> &Blocks = CurLoop->getBlocks();
526 if (!BB->isLiveIn(Reg))
530 if (!MO.isReg() || !MO.getReg() || MO.isDef())
continue;
531 if (MO.getReg() == Reg || TRI->isSuperRegister(Reg, MO.getReg()))
540 void MachineLICM::HoistPostRA(
MachineInstr *MI,
unsigned Def) {
564 if (SpeculationState != SpeculateUnknown)
565 return SpeculationState == SpeculateFalse;
567 if (BB != CurLoop->getHeader()) {
570 CurLoop->getExitingBlocks(CurrentLoopExitingBlocks);
572 if (!DT->dominates(BB, CurrentLoopExitingBlock)) {
573 SpeculationState = SpeculateTrue;
578 SpeculationState = SpeculateFalse;
591 BackTrace.pop_back();
600 if (OpenChildren[Node])
604 ExitScope(Node->getBlock());
608 unsigned Left = --OpenChildren[Parent];
611 ExitScope(Parent->getBlock());
633 while (!WorkList.
empty()) {
635 assert(Node &&
"Null dominator tree node?");
645 if (!CurLoop->contains(BB))
649 const std::vector<MachineDomTreeNode*> &Children = Node->
getChildren();
650 unsigned NumChildren = Children.size();
658 OpenChildren[Node] = NumChildren;
662 for (
int i = (
int)NumChildren-1;
i >= 0; --
i) {
664 ParentMap[Child] = Node;
669 if (Scopes.
size() == 0)
675 InitRegPressure(Preheader);
684 SpeculationState = SpeculateUnknown;
686 MII = MBB->
begin(),
E = MBB->
end(); MII !=
E; ) {
689 if (!Hoist(MI, Preheader))
690 UpdateRegPressure(MI);
695 ExitScopeIfDone(Node, OpenChildren, ParentMap);
702 void MachineLICM::SinkIntoLoop() {
712 if (IsLoopInvariantInst(*
I) && !HasLoopPHIUse(&*
I))
737 B = DT->findNearestCommonDominator(B, MI.
getParent());
743 if (!CanSink || !B || B == Preheader)
771 UpdateRegPressure(&MI,
true);
775 void MachineLICM::UpdateRegPressure(
const MachineInstr *MI,
776 bool ConsiderUnseenAsDef) {
777 auto Cost = calcRegisterCost(MI,
true, ConsiderUnseenAsDef);
778 for (
const auto &RPIdAndCost : Cost) {
779 unsigned Class = RPIdAndCost.first;
780 if (static_cast<int>(
RegPressure[Class]) < -RPIdAndCost.second)
794 MachineLICM::calcRegisterCost(
const MachineInstr *MI,
bool ConsiderSeen,
795 bool ConsiderUnseenAsDef) {
803 unsigned Reg = MO.
getReg();
808 bool isNew = ConsiderSeen ? RegSeen.insert(Reg).second :
false;
817 if (isNew && !isKill && ConsiderUnseenAsDef)
820 else if (!isNew && isKill)
825 const int *
PS = TRI->getRegClassPressureSets(RC);
826 for (; *PS != -1; ++
PS) {
827 if (Cost.
find(*PS) == Cost.
end())
848 if (PSV->isGOT() || PSV->isConstantPool())
858 bool DontMoveAcrossStore =
true;
880 bool MachineLICM::IsLoopInvariantInst(
MachineInstr &I) {
881 if (!IsLICMCandidate(I))
889 unsigned Reg = MO.
getReg();
890 if (Reg == 0)
continue;
893 if (TargetRegisterInfo::isPhysicalRegister(Reg)) {
898 if (!
MRI->isConstantPhysReg(Reg))
902 }
else if (!MO.
isDead()) {
905 }
else if (CurLoop->getHeader()->isLiveIn(Reg)) {
916 "Machine instr not mapped for this vreg?!");
920 if (CurLoop->contains(
MRI->getVRegDef(Reg)))
931 bool MachineLICM::HasLoopPHIUse(
const MachineInstr *MI)
const {
934 MI = Work.pop_back_val();
938 unsigned Reg = MO.
getReg();
939 if (!TargetRegisterInfo::isVirtualRegister(Reg))
946 if (CurLoop->contains(&
UseMI))
956 if (
UseMI.isCopy() && CurLoop->contains(&
UseMI))
957 Work.push_back(&
UseMI);
960 }
while (!Work.empty());
966 bool MachineLICM::HasHighOperandLatency(
MachineInstr &MI,
967 unsigned DefIdx,
unsigned Reg)
const {
968 if (
MRI->use_nodbg_empty(Reg))
972 if (
UseMI.isCopyLike())
974 if (!CurLoop->contains(
UseMI.getParent()))
976 for (
unsigned i = 0, e =
UseMI.getNumOperands();
i != e; ++
i) {
980 unsigned MOReg = MO.
getReg();
984 if (
TII->hasHighOperandLatency(SchedModel,
MRI, MI, DefIdx,
UseMI,
i))
997 bool MachineLICM::IsCheapInstruction(
MachineInstr &MI)
const {
1001 bool isCheap =
false;
1008 unsigned Reg = DefMO.
getReg();
1009 if (TargetRegisterInfo::isPhysicalRegister(Reg))
1012 if (!
TII->hasLowDefLatency(SchedModel, MI,
i))
1024 for (
const auto &RPIdAndCost : Cost) {
1025 if (RPIdAndCost.second <= 0)
1028 unsigned Class = RPIdAndCost.first;
1029 int Limit = RegLimit[
Class];
1036 for (
const auto &
RP : BackTrace)
1037 if (static_cast<int>(
RP[Class]) + RPIdAndCost.second >= Limit)
1047 void MachineLICM::UpdateBackTraceRegPressure(
const MachineInstr *MI) {
1050 auto Cost = calcRegisterCost(MI,
false,
1054 for (
auto &
RP : BackTrace)
1055 for (
const auto &RPIdAndCost : Cost)
1056 RP[RPIdAndCost.first] += RPIdAndCost.second;
1061 bool MachineLICM::IsProfitableToHoist(
MachineInstr &MI) {
1077 bool CheapInstr = IsCheapInstruction(MI);
1078 bool CreatesCopy = HasLoopPHIUse(&MI);
1081 if (CheapInstr && CreatesCopy) {
1082 DEBUG(
dbgs() <<
"Won't hoist cheap instr with loop PHI use: " << MI);
1088 if (
TII->isTriviallyReMaterializable(MI, AA))
1097 unsigned Reg = MO.
getReg();
1098 if (!TargetRegisterInfo::isVirtualRegister(Reg))
1100 if (MO.
isDef() && HasHighOperandLatency(MI,
i, Reg)) {
1101 DEBUG(
dbgs() <<
"Hoist High Latency: " << MI);
1113 auto Cost = calcRegisterCost(&MI,
false,
1118 if (!CanCauseHighRegPressure(Cost, CheapInstr)) {
1119 DEBUG(
dbgs() <<
"Hoist non-reg-pressure: " << MI);
1126 DEBUG(
dbgs() <<
"Won't hoist instr with loop PHI use: " << MI);
1134 (!IsGuaranteedToExecute(MI.
getParent()) && !MayCSE(&MI))) {
1135 DEBUG(
dbgs() <<
"Won't speculate: " << MI);
1141 if (!
TII->isTriviallyReMaterializable(MI, AA) &&
1143 DEBUG(
dbgs() <<
"Can't remat / high reg-pressure: " << MI);
1165 unsigned LoadRegIndex;
1171 if (NewOpc == 0)
return nullptr;
1176 unsigned Reg =
MRI->createVirtualRegister(RC);
1179 bool Success =
TII->unfoldMemoryOperand(MF, *MI, Reg,
1184 "unfoldMemoryOperand failed when getOpcodeAfterMemoryUnfold "
1187 "Unfolded a load into multiple instructions!");
1190 MBB->insert(Pos, NewMIs[0]);
1191 MBB->insert(Pos, NewMIs[1]);
1194 if (!IsLoopInvariantInst(*NewMIs[0]) || !IsProfitableToHoist(*NewMIs[0])) {
1195 NewMIs[0]->eraseFromParent();
1196 NewMIs[1]->eraseFromParent();
1201 UpdateRegPressure(NewMIs[1]);
1220 std::vector<const MachineInstr*> &PrevMIs) {
1222 if (
TII->produceSameValue(*MI, *PrevMI, (PreRegAlloc ?
MRI :
nullptr)))
1233 DenseMap<
unsigned, std::vector<const MachineInstr*> >::iterator &CI) {
1239 if (
const MachineInstr *Dup = LookForDuplicate(MI, CI->second)) {
1240 DEBUG(
dbgs() <<
"CSEing " << *MI <<
" with " << *Dup);
1250 !TargetRegisterInfo::isPhysicalRegister(MO.
getReg()) ||
1251 MO.
getReg() == Dup->getOperand(
i).getReg()) &&
1252 "Instructions with different phys regs are not identical!");
1255 !TargetRegisterInfo::isPhysicalRegister(MO.
getReg()))
1260 for (
unsigned i = 0, e = Defs.
size();
i != e; ++
i) {
1261 unsigned Idx = Defs[
i];
1263 unsigned DupReg = Dup->getOperand(Idx).getReg();
1266 if (!
MRI->constrainRegClass(DupReg,
MRI->getRegClass(Reg))) {
1268 for (
unsigned j = 0; j !=
i; ++j)
1269 MRI->setRegClass(Dup->getOperand(Defs[j]).getReg(), OrigRCs[j]);
1274 for (
unsigned Idx : Defs) {
1276 unsigned DupReg = Dup->getOperand(Idx).getReg();
1277 MRI->replaceRegWith(Reg, DupReg);
1278 MRI->clearKillFlags(DupReg);
1293 CI = CSEMap.
find(Opcode);
1299 return LookForDuplicate(MI, CI->second) !=
nullptr;
1307 if (!IsLoopInvariantInst(*MI) || !IsProfitableToHoist(*MI)) {
1309 MI = ExtractHoistableLoad(MI);
1310 if (!MI)
return false;
1316 dbgs() <<
"Hoisting " << *
MI;
1327 InitCSEMap(Preheader);
1328 FirstInLoop =
false;
1334 CI = CSEMap.
find(Opcode);
1335 if (!EliminateCSE(MI, CI)) {
1345 UpdateBackTraceRegPressure(MI);
1355 if (CI != CSEMap.
end())
1356 CI->second.push_back(MI);
1358 CSEMap[Opcode].push_back(MI);
1373 if (CurPreheader == reinterpret_cast<MachineBasicBlock *>(-1))
1376 if (!CurPreheader) {
1377 CurPreheader = CurLoop->getLoopPreheader();
1378 if (!CurPreheader) {
1386 if (!CurPreheader) {
1392 return CurPreheader;
unsigned succ_size() const
void push_back(const T &Elt)
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
instr_iterator instr_begin()
instr_iterator instr_end()
const std::vector< DomTreeNodeBase< NodeT > * > & getChildren() const
STATISTIC(NumFunctions,"Total number of functions")
int getNumber() const
MachineBasicBlocks are uniquely numbered at the function level, unless they're not in a MachineFuncti...
unsigned getNumDefs() const
Return the number of MachineOperands that are register definitions.
char & MachineLICMID
MachineLICM - This pass performs LICM on machine instructions.
iterator getFirstTerminator()
Returns an iterator to the first terminator instruction of this basic block.
Describe properties that are true of each instruction in the target description file.
static bool isVirtualRegister(unsigned Reg)
Return true if the specified register number is in the virtual register namespace.
INITIALIZE_PASS_BEGIN(MachineLICM,"machinelicm","Machine Loop Invariant Code Motion", false, false) INITIALIZE_PASS_END(MachineLICM
void setBitsNotInMask(const uint32_t *Mask, unsigned MaskWords=~0u)
setBitsNotInMask - Add a bit to this vector for every '0' bit in Mask.
const MCInstrDesc & getDesc() const
Returns the target instruction descriptor of this MachineInstr.
LoopT * getParentLoop() const
const Function * getFunction() const
getFunction - Return the LLVM function that this machine code represents
iterator_range< mmo_iterator > memoperands()
bool canFoldAsLoad(QueryType Type=IgnoreBundle) const
Return true for instructions that can be folded as memory operands in other instructions.
iterator_range< mop_iterator > operands()
static bool mayLoadFromGOTOrConstantPool(MachineInstr &MI)
Return true if this machine instruction loads from global offset table or constant pool...
BlockT * getHeader() const
bool isDereferenceableInvariantLoad(AliasAnalysis *AA) const
Return true if this load instruction never traps and points to a memory location whose value doesn't ...
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...
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
A description of a memory reference used in the backend.
Each TargetRegisterClass has a per register weight, and weight limit which must be less than the limi...
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Provide an instruction scheduling machine model to CodeGen passes.
const HexagonInstrInfo * TII
static bool isOperandKill(const MachineOperand &MO, MachineRegisterInfo *MRI)
Machine Loop Invariant Code false
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void eraseFromParent()
Unlink 'this' from the containing basic block and delete it.
bool mayLoad(QueryType Type=AnyInBundle) const
Return true if this instruction could possibly read memory.
Reg
All possible values of the reg field in the ModR/M byte.
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted...
const MCSchedModel & getSchedModel() const
Get the machine model for this subtarget's CPU.
static cl::opt< bool > AvoidSpeculation("avoid-speculation", cl::desc("MachineLICM should avoid speculation"), cl::init(true), cl::Hidden)
LLVM_NODISCARD bool empty() const
unsigned getNumOperands() const
Access to explicit operands of the instruction.
Base class for the actual dominator tree node.
bool isCopyLike() const
Return true if the instruction behaves like a copy.
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
COFF::MachineTypes Machine
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
unsigned getOpcode() const
Returns the opcode of this MachineInstr.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
const MachineBasicBlock * getParent() const
TargetInstrInfo - Interface to description of machine instruction set.
bool isImplicitDef() const
initializer< Ty > init(const Ty &Val)
static cl::opt< bool > SinkInstsToAvoidSpills("sink-insts-to-avoid-spills", cl::desc("MachineLICM should sink instructions into ""loops to avoid register spills"), cl::init(false), cl::Hidden)
unsigned const MachineRegisterInfo * MRI
void getAnalysisUsage(AnalysisUsage &AU) const override
getAnalysisUsage - Subclasses that override getAnalysisUsage must call this.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
MachineInstrBuilder & UseMI
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
const MachineOperand & getOperand(unsigned i) const
static cl::opt< bool > HoistCheapInsts("hoist-cheap-insts", cl::desc("MachineLICM should hoist even cheap instructions"), cl::init(false), cl::Hidden)
MCRegAliasIterator enumerates all registers aliasing Reg.
Represent the analysis usage information of a pass.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
static bool InstructionStoresToFI(const MachineInstr *MI, int FI)
Return true if instruction stores to the specified frame.
std::pair< NoneType, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
pred_iterator pred_begin()
void initializeMachineLICMPass(PassRegistry &)
This base class for TargetLowering contains the SelectionDAG-independent parts that can be used from ...
size_type count(const T &V) const
count - Return 1 if the element is in the set, 0 otherwise.
bool isSafeToMove(AliasAnalysis *AA, bool &SawStore) const
Return true if it is safe to move this instruction.
bool memoperands_empty() const
Return true if we don't have any memory operands which described the the memory access done by this i...
Iterator for intrusive lists based on ilist_node.
MachineOperand class - Representation of each machine instruction operand.
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small...
bool test(unsigned Idx) const
virtual const TargetLowering * getTargetLowering() const
LLVM_NODISCARD T pop_back_val()
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
void setDebugLoc(DebugLoc dl)
Replace current source information with new such.
Special value supplied for machine level alias analysis.
Machine Loop Invariant Code static false bool LoopIsOuterMostWithPredecessor(MachineLoop *CurLoop)
Test if the given loop is the outer-most loop that has a unique predecessor.
unsigned isLoadFromStackSlot(const MachineInstr &MI, int &FrameIndex) const override
TargetInstrInfo overrides.
MachineRegisterInfo - Keep track of information for virtual and physical registers, including vreg register classes, use/def chains for registers, etc.
TargetSubtargetInfo - Generic base class for all target subtargets.
Representation of each machine instruction.
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
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 '...
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
Represents a single loop in the control flow graph.
bool hasOneNonDBGUse(unsigned RegNo) const
hasOneNonDBGUse - Return true if there is exactly one non-Debug instruction using the specified regis...
LLVM_ATTRIBUTE_ALWAYS_INLINE size_type size() const
iterator find(const KeyT &Val)
BlockT * getLoopPredecessor() const
If the given loop's header has exactly one unique predecessor outside the loop, return it...
iterator getFirstNonPHI()
Returns a pointer to the first instruction in this block that is not a PHINode instruction.
unsigned getReg() const
getReg - Returns the register number.
Machine Loop Invariant Code Motion
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
MachineBasicBlock * SplitCriticalEdge(MachineBasicBlock *Succ, Pass &P)
Split the critical edge from this block to the given successor block, and return the newly created bl...
virtual const TargetInstrInfo * getInstrInfo() const
LLVM Value Representation.
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
static bool isExitBlock(BasicBlock *BB, const SmallVectorImpl< BasicBlock * > &ExitBlocks)
Return true if the specified block is in the list.
virtual const TargetRegisterInfo * getRegisterInfo() const
getRegisterInfo - If register information is available, return it.
A specialized PseudoSourceValue for holding FixedStack values, which must include a frame index...
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
A wrapper pass to provide the legacy pass manager access to a suitably prepared AAResults object...
DominatorTree Class - Concrete subclass of DominatorTreeBase that is used to compute a normal dominat...
unsigned pred_size() const
This file describes how to lower LLVM code to machine code.
bool is_contained(R &&Range, const E &Element)
Wrapper function around std::find to detect if an element exists in a container.