57#define DEBUG_TYPE "mem2reg"
59STATISTIC(NumLocalPromoted,
"Number of alloca's promoted within one block");
60STATISTIC(NumSingleStore,
"Number of alloca's promoted with a single store");
61STATISTIC(NumDeadAlloca,
"Number of dead alloca's removed");
62STATISTIC(NumPHIInsert,
"Number of PHI nodes inserted");
67 if (
const LoadInst *LI = dyn_cast<LoadInst>(U)) {
72 }
else if (
const StoreInst *SI = dyn_cast<StoreInst>(U)) {
73 if (SI->getValueOperand() == AI ||
80 }
else if (
const IntrinsicInst *II = dyn_cast<IntrinsicInst>(U)) {
81 if (!II->isLifetimeStartOrEnd() && !II->isDroppable())
83 }
else if (
const BitCastInst *BCI = dyn_cast<BitCastInst>(U)) {
87 if (!GEPI->hasAllZeroIndices())
119 DIB.insertDbgValueIntrinsic(NewValue, Variable,
Expression, DI, InsertBefore);
123class AssignmentTrackingInfo {
145 void updateForDeletedStore(
161 auto InsertValueForAssign = [&](
auto *DbgAssign,
auto *&AssignList) {
163 AssignList->insert(DbgAssign);
164 createDebugValue(DIB, DbgAssign->getValue(), DbgAssign->getVariable(),
165 DbgAssign->getExpression(), DbgAssign->getDebugLoc(),
169 InsertValueForAssign(Assign, DbgAssignsToDelete);
171 InsertValueForAssign(Assign, DVRAssignsToDelete);
181 auto ConvertUnlinkedAssignToValue = [&](
auto *
Assign) {
186 for_each(DbgAssigns, ConvertUnlinkedAssignToValue);
187 for_each(DVRAssigns, ConvertUnlinkedAssignToValue);
196 for (
auto *DAI : DbgAssigns)
198 for (
auto *DVR : DVRAssigns)
206 bool empty() {
return DbgAssigns.empty() && DVRAssigns.
empty(); }
218 bool OnlyUsedInOneBlock;
224 AssignmentTrackingInfo AssignmentTracking;
227 DefiningBlocks.
clear();
231 OnlyUsedInOneBlock =
true;
234 AssignmentTracking.clear();
259 if (OnlyUsedInOneBlock) {
261 OnlyBlock =
User->getParent();
262 else if (OnlyBlock !=
User->getParent())
263 OnlyUsedInOneBlock =
false;
266 DbgUserVec AllDbgUsers;
269 std::copy_if(AllDbgUsers.begin(), AllDbgUsers.end(),
271 return !isa<DbgAssignIntrinsic>(DII);
273 std::copy_if(AllDPUsers.
begin(), AllDPUsers.
end(),
274 std::back_inserter(DPUsers),
276 AssignmentTracking.init(AI);
281struct RenamePassData {
282 using ValVector = std::vector<Value *>;
283 using LocationVector = std::vector<DebugLoc>;
299class LargeBlockInfo {
310 static bool isInterestingInstruction(
const Instruction *
I) {
311 return (isa<LoadInst>(
I) && isa<AllocaInst>(
I->getOperand(0))) ||
312 (isa<StoreInst>(
I) && isa<AllocaInst>(
I->getOperand(1)));
317 assert(isInterestingInstruction(
I) &&
318 "Not a load/store to/from an alloca?");
322 if (It != InstNumbers.
end())
331 if (isInterestingInstruction(&BBI))
332 InstNumbers[&BBI] = InstNo++;
333 It = InstNumbers.
find(
I);
335 assert(It != InstNumbers.
end() &&
"Didn't insert instruction?");
344struct PromoteMem2Reg {
346 std::vector<AllocaInst *> Allocas;
398 : Allocas(Allocas.
begin(), Allocas.
end()), DT(DT),
406 void RemoveFromAllocasList(
unsigned &AllocaIdx) {
407 Allocas[AllocaIdx] = Allocas.back();
413 unsigned &NP = BBNumPreds[BB];
423 RenamePassData::ValVector &IncVals,
424 RenamePassData::LocationVector &IncLocs,
425 std::vector<RenamePassData> &Worklist);
426 bool QueuePhiNode(
BasicBlock *BB,
unsigned AllocaIdx,
unsigned &Version);
429 void cleanUpDbgAssigns() {
430 for (
auto *DAI : DbgAssignsToDelete)
431 DAI->eraseFromParent();
432 DbgAssignsToDelete.clear();
433 for (
auto *DVR : DVRAssignsToDelete)
434 DVR->eraseFromParent();
435 DVRAssignsToDelete.clear();
460 if (AC && LI->
getMetadata(LLVMContext::MD_nonnull) &&
472 if (isa<LoadInst>(
I) || isa<StoreInst>(
I))
476 if (
I->isDroppable()) {
477 I->dropDroppableUse(U);
481 if (!
I->getType()->isVoidTy()) {
486 Instruction *Inst = cast<Instruction>(UU.getUser());
496 I->eraseFromParent();
515 bool StoringGlobalVal = !isa<Instruction>(OnlyStore->
getOperand(0));
520 Info.UsingBlocks.clear();
524 if (UserInst == OnlyStore)
526 LoadInst *LI = cast<LoadInst>(UserInst);
532 if (!StoringGlobalVal) {
537 if (StoreIndex == -1)
538 StoreIndex = LBI.getInstructionIndex(OnlyStore);
540 if (
unsigned(StoreIndex) > LBI.getInstructionIndex(LI)) {
542 Info.UsingBlocks.push_back(StoreBB);
568 if (!
Info.UsingBlocks.empty())
573 Info.AssignmentTracking.updateForDeletedStore(
574 Info.OnlyStore, DIB, DbgAssignsToDelete, DVRAssignsToDelete);
578 auto ConvertDebugInfoForStore = [&](
auto &Container) {
579 for (
auto *DbgItem : Container) {
580 if (DbgItem->isAddressOfVariable()) {
582 DbgItem->eraseFromParent();
583 }
else if (DbgItem->getExpression()->startsWithDeref()) {
584 DbgItem->eraseFromParent();
588 ConvertDebugInfoForStore(
Info.DbgUsers);
589 ConvertDebugInfoForStore(
Info.DPUsers);
595 Info.OnlyStore->eraseFromParent();
596 LBI.deleteValue(
Info.OnlyStore);
631 StoresByIndexTy StoresByIndex;
634 if (
StoreInst *SI = dyn_cast<StoreInst>(U))
635 StoresByIndex.
push_back(std::make_pair(LBI.getInstructionIndex(SI), SI));
644 LoadInst *LI = dyn_cast<LoadInst>(U);
648 unsigned LoadIdx = LBI.getInstructionIndex(LI);
653 std::make_pair(LoadIdx,
static_cast<StoreInst *
>(
nullptr)),
656 if (
I == StoresByIndex.begin()) {
657 if (StoresByIndex.empty())
667 ReplVal = std::prev(
I)->second->getOperand(0);
687 Info.AssignmentTracking.updateForDeletedStore(SI, DIB, DbgAssignsToDelete,
690 auto DbgUpdateForStore = [&](
auto &Container) {
691 for (
auto *DbgItem : Container) {
692 if (DbgItem->isAddressOfVariable()) {
697 DbgUpdateForStore(
Info.DbgUsers);
698 DbgUpdateForStore(
Info.DPUsers);
700 SI->eraseFromParent();
709 auto DbgUpdateForAlloca = [&](
auto &Container) {
710 for (
auto *DbgItem : Container)
711 if (DbgItem->isAddressOfVariable() ||
712 DbgItem->getExpression()->startsWithDeref())
713 DbgItem->eraseFromParent();
715 DbgUpdateForAlloca(
Info.DbgUsers);
716 DbgUpdateForAlloca(
Info.DPUsers);
722void PromoteMem2Reg::run() {
725 AllocaDbgUsers.
resize(Allocas.size());
726 AllocaATInfo.
resize(Allocas.size());
727 AllocaDPUsers.
resize(Allocas.size());
733 for (
unsigned AllocaNum = 0; AllocaNum != Allocas.size(); ++AllocaNum) {
738 "All allocas should be in the same function, which is same as DF!");
747 RemoveFromAllocasList(AllocaNum);
754 Info.AnalyzeAlloca(AI);
758 if (
Info.DefiningBlocks.size() == 1) {
760 &DbgAssignsToDelete, &DVRAssignsToDelete)) {
762 RemoveFromAllocasList(AllocaNum);
770 if (
Info.OnlyUsedInOneBlock &&
772 &DbgAssignsToDelete, &DVRAssignsToDelete)) {
774 RemoveFromAllocasList(AllocaNum);
780 if (BBNumbers.
empty()) {
783 BBNumbers[&BB] =
ID++;
787 if (!
Info.DbgUsers.empty())
788 AllocaDbgUsers[AllocaNum] =
Info.DbgUsers;
789 if (!
Info.AssignmentTracking.empty())
790 AllocaATInfo[AllocaNum] =
Info.AssignmentTracking;
791 if (!
Info.DPUsers.empty())
792 AllocaDPUsers[AllocaNum] =
Info.DPUsers;
795 AllocaLookup[Allocas[AllocaNum]] = AllocaNum;
799 Info.DefiningBlocks.end());
810 IDF.setLiveInBlocks(LiveInBlocks);
811 IDF.setDefiningBlocks(DefBlocks);
813 IDF.calculate(PHIBlocks);
815 return BBNumbers.
find(
A)->second < BBNumbers.
find(
B)->second;
820 QueuePhiNode(BB, AllocaNum, CurrentVersion);
823 if (Allocas.empty()) {
832 RenamePassData::ValVector Values(Allocas.size());
833 for (
unsigned i = 0, e = Allocas.size(); i != e; ++i)
838 RenamePassData::LocationVector
Locations(Allocas.size());
842 std::vector<RenamePassData> RenamePassWorkList;
843 RenamePassWorkList.emplace_back(&
F.front(),
nullptr, std::move(Values),
844 std::move(Locations));
846 RenamePassData RPD = std::move(RenamePassWorkList.back());
847 RenamePassWorkList.pop_back();
849 RenamePass(RPD.BB, RPD.Pred, RPD.Values, RPD.Locations, RenamePassWorkList);
850 }
while (!RenamePassWorkList.empty());
864 A->eraseFromParent();
868 auto RemoveDbgDeclares = [&](
auto &Container) {
869 for (
auto &DbgUsers : Container) {
870 for (
auto *DbgItem : DbgUsers)
871 if (DbgItem->isAddressOfVariable() ||
872 DbgItem->getExpression()->startsWithDeref())
873 DbgItem->eraseFromParent();
876 RemoveDbgDeclares(AllocaDbgUsers);
877 RemoveDbgDeclares(AllocaDPUsers);
883 bool EliminatedAPHI =
true;
884 while (EliminatedAPHI) {
885 EliminatedAPHI =
false;
893 E = NewPhiNodes.
end();
902 EliminatedAPHI =
true;
916 E = NewPhiNodes.
end();
922 if (&BB->
front() != SomePHI)
938 return BBNumbers.
find(
A)->second < BBNumbers.
find(
B)->second;
949 "PHI node has entry for a block which is not a predecessor!");
961 while ((SomePHI = dyn_cast<PHINode>(BBI++)) &&
978void PromoteMem2Reg::ComputeLiveInBlocks(
986 Info.UsingBlocks.end());
991 for (
unsigned i = 0, e = LiveInBlockWorklist.size(); i != e; ++i) {
993 if (!DefBlocks.
count(BB))
1000 if (
SI->getOperand(1) != AI)
1005 LiveInBlockWorklist[i] = LiveInBlockWorklist.
back();
1006 LiveInBlockWorklist.pop_back();
1012 if (
LoadInst *LI = dyn_cast<LoadInst>(
I))
1022 while (!LiveInBlockWorklist.empty()) {
1023 BasicBlock *BB = LiveInBlockWorklist.pop_back_val();
1027 if (!LiveInBlocks.
insert(BB).second)
1039 LiveInBlockWorklist.push_back(
P);
1047bool PromoteMem2Reg::QueuePhiNode(
BasicBlock *BB,
unsigned AllocaNo,
1048 unsigned &Version) {
1050 PHINode *&PN = NewPhiNodes[std::make_pair(BBNumbers[BB], AllocaNo)];
1058 PN =
PHINode::Create(Allocas[AllocaNo]->getAllocatedType(), getNumPreds(BB),
1059 Allocas[AllocaNo]->
getName() +
"." +
Twine(Version++));
1062 PhiToAllocaMap[PN] = AllocaNo;
1069 bool ApplyMergedLoc) {
1082 RenamePassData::ValVector &IncomingVals,
1083 RenamePassData::LocationVector &IncomingLocs,
1084 std::vector<RenamePassData> &Worklist) {
1091 if (PhiToAllocaMap.
count(APN)) {
1098 unsigned NewPHINumOperands = APN->getNumOperands();
1101 assert(NumEdges &&
"Must be at least one edge from Pred to BB!");
1106 unsigned AllocaNo = PhiToAllocaMap[APN];
1110 APN->getNumIncomingValues() > 0);
1113 for (
unsigned i = 0; i != NumEdges; ++i)
1114 APN->addIncoming(IncomingVals[AllocaNo], Pred);
1117 IncomingVals[AllocaNo] = APN;
1118 AllocaATInfo[AllocaNo].updateForNewPhi(APN, DIB);
1119 auto ConvertDbgDeclares = [&](
auto &Container) {
1120 for (
auto *DbgItem : Container)
1121 if (DbgItem->isAddressOfVariable())
1124 ConvertDbgDeclares(AllocaDbgUsers[AllocaNo]);
1125 ConvertDbgDeclares(AllocaDPUsers[AllocaNo]);
1129 APN = dyn_cast<PHINode>(PNI);
1135 }
while (APN->getNumOperands() == NewPHINumOperands);
1140 if (!Visited.
insert(BB).second)
1146 if (
LoadInst *LI = dyn_cast<LoadInst>(
I)) {
1152 if (AI == AllocaLookup.
end())
1155 Value *
V = IncomingVals[AI->second];
1161 }
else if (
StoreInst *SI = dyn_cast<StoreInst>(
I)) {
1164 AllocaInst *Dest = dyn_cast<AllocaInst>(
SI->getPointerOperand());
1169 if (ai == AllocaLookup.
end())
1173 unsigned AllocaNo = ai->second;
1174 IncomingVals[AllocaNo] =
SI->getOperand(0);
1177 IncomingLocs[AllocaNo] =
SI->getDebugLoc();
1178 AllocaATInfo[AllocaNo].updateForDeletedStore(SI, DIB, &DbgAssignsToDelete,
1179 &DVRAssignsToDelete);
1180 auto ConvertDbgDeclares = [&](
auto &Container) {
1181 for (
auto *DbgItem : Container)
1182 if (DbgItem->isAddressOfVariable())
1185 ConvertDbgDeclares(AllocaDbgUsers[ai->second]);
1186 ConvertDbgDeclares(AllocaDPUsers[ai->second]);
1187 SI->eraseFromParent();
1206 if (VisitedSuccs.
insert(*I).second)
1207 Worklist.emplace_back(*
I, Pred, IncomingVals, IncomingLocs);
1215 if (Allocas.
empty())
1218 PromoteMem2Reg(Allocas, DT, AC).run();
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
static const Function * getParent(const Value *V)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
Analysis containing CSE Info
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static void clear(coro::Shape &Shape)
This file defines the DenseMap class.
This file provides various utilities for inspecting and working with the control flow graph in LLVM I...
Module.h This file contains the declarations for the Module class.
static StringRef getName(Value *V)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
static void ComputeLiveInBlocks(const SmallPtrSetImpl< BasicBlock * > &UsingBlocks, const SmallPtrSetImpl< BasicBlock * > &DefBlocks, SmallPtrSetImpl< BasicBlock * > &LiveInBlocks, PredIteratorCache &PredCache)
Given sets of UsingBlocks and DefBlocks, compute the set of LiveInBlocks.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
This class represents a conversion between pointers from one address space to another.
an instruction to allocate memory on the stack
Type * getAllocatedType() const
Return the type that is being allocated by the instruction.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
bool empty() const
empty - Check if the array is empty.
A cache of @llvm.assume calls within a function.
void registerAssumption(AssumeInst *CI)
Add an @llvm.assume intrinsic to this function's cache.
LLVM Basic Block Representation.
iterator begin()
Instruction iterator methods.
const Instruction & front() const
const Function * getParent() const
Return the enclosing method, or null if none.
InstListType::iterator iterator
Instruction iterators...
const Instruction & back() const
This class represents a no-op cast from one type to another.
This class represents a function call, abstracting a target machine's calling convention.
static CallInst * Create(FunctionType *Ty, Value *F, const Twine &NameStr, BasicBlock::iterator InsertBefore)
static Constant * getNullValue(Type *Ty)
Constructor to create a '0' constant of arbitrary type.
A parsed version of the target data layout string in and methods for querying it.
This represents the llvm.dbg.assign instruction.
This is the common base class for debug info intrinsics for variables.
Record of a variable value-assignment, aka a non instruction representation of the dbg....
static DbgVariableRecord * createDbgVariableRecord(Value *Location, DILocalVariable *DV, DIExpression *Expr, const DILocation *DI)
Identifies a unique instance of a whole variable (discards/ignores fragment information).
Identifies a unique instance of a variable.
iterator find(const_arg_type_t< KeyT > Val)
bool erase(const KeyT &Val)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
Class representing an expression and its matching format.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs
This instruction compares its operands according to the predicate given to the constructor.
void insertBefore(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately before the specified instruction.
const DebugLoc & getDebugLoc() const
Return the debug location for this node as a DebugLoc.
const Module * getModule() const
Return the module owning the function this instruction belongs to or nullptr it the function does not...
const BasicBlock * getParent() const
InstListType::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
Instruction * user_back()
Specialize the methods defined in Value, as we know that an instruction can only be used by other ins...
MDNode * getMetadata(unsigned KindID) const
Get the metadata of given kind attached to this Instruction.
void applyMergedLocation(DILocation *LocA, DILocation *LocB)
Merge 2 debug locations and apply it to the Instruction.
void setDebugLoc(DebugLoc Loc)
Set the debug location information for this instruction.
void insertAfter(Instruction *InsertPos)
Insert an unlinked instruction into a basic block immediately after the specified instruction.
A wrapper class for inspecting calls to intrinsic functions.
An instruction for reading from memory.
Value * getPointerOperand()
void addIncoming(Value *V, BasicBlock *BB)
Add an incoming value to the end of the PHI list.
static PHINode * Create(Type *Ty, unsigned NumReservedValues, const Twine &NameStr, BasicBlock::iterator InsertBefore)
Constructors - NumReservedValues is a hint for the number of incoming edges that this phi node will h...
BasicBlock * getIncomingBlock(unsigned i) const
Return incoming basic block number i.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
static PoisonValue * get(Type *T)
Static factory methods - Return an 'poison' object of the specified type.
A templated base class for SmallPtrSet which provides the typesafe interface that is common across al...
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.
SmallSet - This maintains a set of unique values, optimizing for the case when the set is small (less...
bool contains(const T &V) const
Check if the SmallSet contains the given element.
std::pair< const_iterator, bool > insert(const T &V)
insert - Insert an element into the set if it isn't already there.
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
An instruction for storing to memory.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
static UndefValue * get(Type *T)
Static factory methods - Return an 'undef' object of the specified type.
A Use represents the edge between a Value definition and its users.
Value * getOperand(unsigned i) const
bool isDroppable() const
A droppable user is a user for which uses can be dropped without affecting correctness and should be ...
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
void replaceAllUsesWith(Value *V)
Change all uses of this to point to a new Value.
iterator_range< user_iterator > users()
static void dropDroppableUse(Use &U)
Remove the droppable use U.
iterator_range< use_iterator > uses()
Function * getDeclaration(Module *M, ID id, ArrayRef< Type * > Tys=std::nullopt)
Create or insert an LLVM Function declaration for an intrinsic, and return it.
AssignmentMarkerRange getAssignmentMarkers(DIAssignID *ID)
Return a range of dbg.assign intrinsics which use \ID as an operand.
SmallVector< DbgVariableRecord * > getDVRAssignmentMarkers(const Instruction *Inst)
void deleteAssignmentMarkers(const Instruction *Inst)
Delete the llvm.dbg.assign intrinsics linked to Inst.
initializer< Ty > init(const Ty &Val)
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
const_iterator end(StringRef path)
Get end iterator over path.
This is an optimization pass for GlobalISel generic memory operations.
Interval::succ_iterator succ_end(Interval *I)
bool isKnownNonZero(const Value *V, const DataLayout &DL, unsigned Depth=0, AssumptionCache *AC=nullptr, const Instruction *CxtI=nullptr, const DominatorTree *DT=nullptr, bool UseInstrInfo=true)
Return true if the given value is known to be non-zero when defined.
UnaryFunction for_each(R &&Range, UnaryFunction F)
Provide wrappers to std::for_each which take ranges instead of having to pass begin/end explicitly.
void PromoteMemToReg(ArrayRef< AllocaInst * > Allocas, DominatorTree &DT, AssumptionCache *AC=nullptr)
Promote the specified list of alloca instructions into scalar registers, inserting PHI nodes as appro...
void findDbgUsers(SmallVectorImpl< DbgVariableIntrinsic * > &DbgInsts, Value *V, SmallVectorImpl< DbgVariableRecord * > *DbgVariableRecords=nullptr)
Finds the debug info intrinsics describing a value.
auto successors(const MachineBasicBlock *BB)
bool onlyUsedByLifetimeMarkersOrDroppableInsts(const Value *V)
Return true if the only users of this pointer are lifetime markers or droppable instructions.
Interval::succ_iterator succ_begin(Interval *I)
succ_begin/succ_end - define methods so that Intervals may be used just like BasicBlocks can with the...
iterator_range< early_inc_iterator_impl< detail::IterOfRange< RangeT > > > make_early_inc_range(RangeT &&Range)
Make a range that does early increment to allow mutation of the underlying range without disrupting i...
bool isAllocaPromotable(const AllocaInst *AI)
Return true if this alloca is legal for promotion.
Value * simplifyInstruction(Instruction *I, const SimplifyQuery &Q)
See if we can compute a simplified version of this instruction.
void sort(IteratorTy Start, IteratorTy End)
void ConvertDebugDeclareToDebugValue(DbgVariableIntrinsic *DII, StoreInst *SI, DIBuilder &Builder)
===------------------------------------------------------------------—===// Dbg Intrinsic utilities
bool onlyUsedByLifetimeMarkers(const Value *V)
Return true if the only users of this pointer are lifetime markers.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
auto count(R &&Range, const E &Element)
Wrapper function around std::count to count the number of times an element Element occurs in the give...
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
auto predecessors(const MachineBasicBlock *BB)
unsigned pred_size(const MachineBasicBlock *BB)
Implement std::hash so that hash_code can be used in STL containers.
Function object to check whether the first component of a container supported by std::get (like std::...