51#define DEBUG_TYPE "commgep"
66 using NodeSet = std::set<GepNode *>;
67 using NodeToValueMap = std::map<GepNode *, Value *>;
68 using NodeVect = std::vector<GepNode *>;
69 using NodeChildrenMap = std::map<GepNode *, NodeVect>;
71 using NodeToUsesMap = std::map<GepNode *, UseSet>;
76 NodeOrdering() =
default;
78 void insert(
const GepNode *
N) { Map.insert(std::make_pair(
N, ++LastNum)); }
79 void clear() { Map.clear(); }
81 bool operator()(
const GepNode *N1,
const GepNode *N2)
const {
82 auto F1 = Map.find(N1), F2 = Map.find(N2);
83 assert(F1 != Map.end() && F2 != Map.end());
84 return F1->second < F2->second;
88 std::map<const GepNode *, unsigned> Map;
96 HexagonCommonGEP() : FunctionPass(ID) {}
99 StringRef getPassName()
const override {
return "Hexagon Common GEP"; }
101 void getAnalysisUsage(AnalysisUsage &AU)
const override {
108 FunctionPass::getAnalysisUsage(AU);
112 using ValueToNodeMap = std::map<Value *, GepNode *>;
113 using ValueVect = std::vector<Value *>;
114 using NodeToValuesMap = std::map<GepNode *, ValueVect>;
116 void getBlockTraversalOrder(BasicBlock *Root, ValueVect &Order);
117 bool isHandledGepForm(GetElementPtrInst *GepI);
118 void processGepInst(GetElementPtrInst *GepI, ValueToNodeMap &NM);
122 BasicBlock *recalculatePlacement(GepNode *Node, NodeChildrenMap &NCM,
123 NodeToValueMap &Loc);
124 BasicBlock *recalculatePlacementRec(GepNode *Node, NodeChildrenMap &NCM,
125 NodeToValueMap &Loc);
126 bool isInvariantIn(
Value *Val, Loop *L);
127 bool isInvariantIn(GepNode *Node, Loop *L);
128 bool isInMainPath(BasicBlock *
B, Loop *L);
129 BasicBlock *adjustForInvariance(GepNode *Node, NodeChildrenMap &NCM,
130 NodeToValueMap &Loc);
131 void separateChainForNode(GepNode *Node, Use *U, NodeToValueMap &Loc);
132 void separateConstantChains(GepNode *Node, NodeChildrenMap &NCM,
133 NodeToValueMap &Loc);
134 void computeNodePlacement(NodeToValueMap &Loc);
138 void getAllUsersForNode(GepNode *Node, ValueVect &Values,
139 NodeChildrenMap &NCM);
140 void materialize(NodeToValueMap &Loc);
142 void removeDeadCode();
146 NodeOrdering NodeOrder;
147 SpecificBumpPtrAllocator<GepNode> *Mem;
151 PostDominatorTree *PDT;
157char HexagonCommonGEP::ID = 0;
243 OS <<
"Parent:" << GN.
Parent;
247 OS << CI->getValue().getSExtValue();
251 OS <<
"<anon> =" << *GN.
Idx;
259 OS <<
"<anon-struct>:" << *STy;
267 template <
typename NodeContainer>
272 OS << *
I <<
' ' << **
I <<
'\n';
282 const NodeToUsesMap &M);
284 for (
const auto &
I : M) {
285 const UseSet &Us =
I.second;
286 OS <<
I.first <<
" -> #" << Us.size() <<
'{';
287 for (
const Use *U : Us) {
288 User *R = U->getUser();
290 OS <<
' ' << R->getName();
292 OS <<
" <?>(" << *R <<
')';
303 return NS.find(
N) != NS.end();
316void HexagonCommonGEP::getBlockTraversalOrder(
BasicBlock *Root,
322 Order.push_back(Root);
324 getBlockTraversalOrder(DTN->getBlock(), Order);
327bool HexagonCommonGEP::isHandledGepForm(GetElementPtrInst *GepI) {
337void HexagonCommonGEP::processGepInst(GetElementPtrInst *GepI,
338 ValueToNodeMap &NM) {
340 GepNode *
N =
new (*Mem) GepNode;
342 uint32_t InBounds = GepI->
isInBounds() ? GepNode::InBounds : 0;
343 ValueToNodeMap::iterator
F = NM.find(PtrOp);
346 N->Flags |= GepNode::Root | InBounds;
351 N->Parent =
F->second;
354 N->Flags |= GepNode::Pointer;
366 if (isHandledGepForm(UserG))
369 Us.insert(&UI.getUse());
380 GepNode *Nx =
new (*Mem) GepNode;
382 Nx->Flags |= GepNode::Internal | InBounds;
394 PN->Flags |= GepNode::Used;
395 Uses[PN].insert_range(Us);
400 NM.insert(std::make_pair(GepI, PN));
403void HexagonCommonGEP::collect() {
406 getBlockTraversalOrder(&Fn->
front(), BO);
414 for (Instruction &J : *
B)
416 if (isHandledGepForm(GepI))
417 processGepInst(GepI, NM);
420 LLVM_DEBUG(
dbgs() <<
"Gep nodes after initial collection:\n" << Nodes);
425 for (GepNode *
N : Nodes) {
426 if (
N->Flags & GepNode::Root) {
430 GepNode *PN =
N->Parent;
431 NCM[PN].push_back(
N);
438 Work.push_back(Root);
441 while (!Work.empty()) {
442 NodeVect::iterator
First = Work.begin();
445 NodeChildrenMap::iterator CF = NCM.find(
N);
446 if (CF != NCM.end()) {
448 Nodes.
insert(CF->second.begin(), CF->second.end());
455 using NodeSymRel = std::set<NodeSet>;
456 using NodePair = std::pair<GepNode *, GepNode *>;
457 using NodePairSet = std::set<NodePair>;
472 uintptr_t P1 =
reinterpret_cast<uintptr_t
>(N1);
473 uintptr_t P2 =
reinterpret_cast<uintptr_t
>(N2);
475 return std::make_pair(N1, N2);
476 return std::make_pair(N2, N1);
482 ID.AddPointer(
N->Idx);
483 ID.AddPointer(
N->PTy);
484 return ID.ComputeHash();
487static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq,
495 NodePairSet::iterator FEq = Eq.find(NP);
498 NodePairSet::iterator FNe = Ne.find(NP);
502 bool Root1 = N1->Flags & GepNode::Root;
503 uint32_t CmpFlags = GepNode::Root | GepNode::Pointer;
504 bool Different = (N1->Flags & CmpFlags) != (N2->Flags & CmpFlags);
510 if (Different || (Root1 && N1->BaseVal != N2->BaseVal)) {
517 if (Root1 ||
node_eq(N1->Parent, N2->Parent, Eq, Ne)) {
524void HexagonCommonGEP::common() {
529 using NodeSetMap = std::map<unsigned, NodeSet>;
532 for (GepNode *
N : Nodes) {
534 MaybeEq[
H].insert(
N);
541 for (
auto &
I : MaybeEq) {
560 std::pair<NodeSymRel::iterator, bool>
Ins = EqRel.insert(
C);
562 assert(
Ins.second &&
"Cannot add a class");
568 dbgs() <<
"Gep node equality:\n";
569 for (NodePairSet::iterator
I = Eq.begin(),
E = Eq.end();
I !=
E; ++
I)
570 dbgs() <<
"{ " <<
I->first <<
", " <<
I->second <<
" }\n";
572 dbgs() <<
"Gep equivalence classes:\n";
573 for (
const NodeSet &S : EqRel) {
575 for (NodeSet::const_iterator J = S.
begin(),
F = S.
end(); J !=
F; ++J) {
585 using ProjMap = std::map<const NodeSet *, GepNode *>;
587 for (
const NodeSet &S : EqRel) {
589 std::pair<ProjMap::iterator,bool>
Ins = PM.insert(std::make_pair(&S, Min));
591 assert(
Ins.second &&
"Cannot add minimal element");
595 UseSet &MinUs =
Uses[Min];
596 for (GepNode *
N : S) {
597 uint32_t NF =
N->Flags;
600 if (NF & GepNode::Used) {
602 MinUs.insert_range(U);
610 assert((Min->Flags & Flags) == Min->Flags);
618 for (GepNode *
N : Nodes) {
619 if (
N->Flags & GepNode::Root)
624 ProjMap::iterator
F = PM.find(PC);
628 GepNode *Rep =
F->second;
636 for (GepNode *
N : Nodes) {
640 ProjMap::iterator
F = PM.find(PC);
650 LLVM_DEBUG(
dbgs() <<
"Gep nodes after post-commoning cleanup:\n" << Nodes);
656 dbgs() <<
"NCD of {";
657 for (
typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
I !=
E;
662 dbgs() <<
' ' <<
B->getName();
668 typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
686 typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
688 while (
I !=
E && !*
I)
712 using iterator =
typename T::iterator;
714 for (
iterator I = Values.begin(),
E = Values.end();
I !=
E; ++
I) {
726 if (In->getParent() !=
B)
729 if (std::distance(FirstUse, BEnd) < std::distance(It, BEnd))
736 return B->empty() || (&*
B->begin() ==
B->getTerminator());
739BasicBlock *HexagonCommonGEP::recalculatePlacement(GepNode *Node,
740 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
752 if (
Node->Flags & GepNode::Used) {
755 NodeToUsesMap::iterator
UF =
Uses.find(Node);
756 assert(UF !=
Uses.end() &&
"Used node with no use information");
757 UseSet &Us =
UF->second;
769 NodeChildrenMap::iterator CF = NCM.find(Node);
770 if (CF != NCM.end()) {
771 NodeVect &Cs = CF->second;
772 for (GepNode *CN : Cs) {
773 NodeToValueMap::iterator LF = Loc.find(CN);
779 Bs.push_back(LF->second);
796 DomB =
N->getBlock();
804BasicBlock *HexagonCommonGEP::recalculatePlacementRec(GepNode *Node,
805 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
809 NodeChildrenMap::iterator CF = NCM.find(Node);
810 if (CF != NCM.end()) {
811 NodeVect &Cs = CF->second;
812 for (GepNode *
C : Cs)
813 recalculatePlacementRec(
C, NCM, Loc);
815 BasicBlock *LB = recalculatePlacement(Node, NCM, Loc);
820bool HexagonCommonGEP::isInvariantIn(
Value *Val, Loop *L) {
830bool HexagonCommonGEP::isInvariantIn(GepNode *Node, Loop *L) {
831 if (
Node->Flags & GepNode::Root)
832 if (!isInvariantIn(
Node->BaseVal, L))
834 return isInvariantIn(
Node->Idx, L);
837bool HexagonCommonGEP::isInMainPath(BasicBlock *
B, Loop *L) {
859BasicBlock *HexagonCommonGEP::adjustForInvariance(GepNode *Node,
860 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
865 if (
Node->Flags & GepNode::Root) {
867 Bs.push_back(PIn->getParent());
869 Bs.push_back(Loc[
Node->Parent]);
872 Bs.push_back(IIn->getParent());
887 if (!isInvariantIn(Node, Lp) || !isInMainPath(LocB, Lp))
890 if (!NewLoc || !DT->
dominates(TopB, NewLoc))
899 NodeChildrenMap::iterator CF = NCM.find(Node);
900 if (CF != NCM.end()) {
901 NodeVect &Cs = CF->second;
902 for (GepNode *
C : Cs)
903 adjustForInvariance(
C, NCM, Loc);
910 struct LocationAsBlock {
911 LocationAsBlock(
const NodeToValueMap &L) : Map(
L) {}
913 const NodeToValueMap ⤅
916 [[maybe_unused]] raw_ostream &
operator<<(raw_ostream &OS,
917 const LocationAsBlock &Loc) {
918 for (
const auto &
I : Loc.Map) {
919 OS <<
I.first <<
" -> ";
921 OS <<
B->getName() <<
'(' <<
B <<
')';
923 OS <<
"<null-block>";
929 inline bool is_constant(GepNode *
N) {
935void HexagonCommonGEP::separateChainForNode(GepNode *Node, Use *U,
936 NodeToValueMap &Loc) {
938 LLVM_DEBUG(
dbgs() <<
"Separating chain for node (" << Node <<
") user: " << *R
943 GepNode *
C =
nullptr, *NewNode =
nullptr;
944 while (is_constant(
N) && !(
N->Flags & GepNode::Root)) {
946 GepNode *NewN =
new (*Mem) GepNode(
N);
947 Nodes.push_back(NewN);
952 NewN->Flags &= ~GepNode::Used;
962 NodeToUsesMap::iterator
UF =
Uses.find(Node);
964 UseSet &Us =
UF->second;
967 if (
U->getUser() == R)
974 Node->Flags &= ~GepNode::Used;
979 NewNode->Flags |= GepNode::Used;
980 LLVM_DEBUG(
dbgs() <<
"new node: " << NewNode <<
" " << *NewNode <<
'\n');
982 Uses[NewNode] = NewUs;
985void HexagonCommonGEP::separateConstantChains(GepNode *Node,
986 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
991 LLVM_DEBUG(
dbgs() <<
"Separating constant chains for node: " << Node <<
'\n');
995 for (GepNode *
N : Ns) {
996 if (!(
N->Flags & GepNode::Used))
998 NodeToUsesMap::iterator
UF =
Uses.find(
N);
1000 UseSet &Us =
UF->second;
1010 if (&Ld->getOperandUse(PtrX) == U)
1014 if (&St->getOperandUse(PtrX) == U)
1023 FNs.insert(std::make_pair(
N, LSs));
1028 for (
auto &FN : FNs) {
1029 GepNode *
N = FN.first;
1030 UseSet &Us = FN.second;
1032 separateChainForNode(
N, U, Loc);
1036void HexagonCommonGEP::computeNodePlacement(NodeToValueMap &Loc) {
1039 NodeChildrenMap NCM;
1045 for (GepNode *Root : Roots)
1046 recalculatePlacementRec(Root, NCM, Loc);
1048 LLVM_DEBUG(
dbgs() <<
"Initial node placement:\n" << LocationAsBlock(Loc));
1051 for (GepNode *Root : Roots)
1052 adjustForInvariance(Root, NCM, Loc);
1054 LLVM_DEBUG(
dbgs() <<
"Node placement after adjustment for invariance:\n"
1055 << LocationAsBlock(Loc));
1058 for (GepNode *Root : Roots)
1059 separateConstantChains(Root, NCM, Loc);
1067 LLVM_DEBUG(
dbgs() <<
"Final node placement:\n" << LocationAsBlock(Loc));
1075 unsigned Num = NA.size();
1076 GepNode *
RN = NA[0];
1077 assert((
RN->Flags & GepNode::Root) &&
"Creating GEP for non-root");
1079 GetElementPtrInst *NewInst =
nullptr;
1089 if (!(NA[Idx]->Flags & GepNode::Pointer)) {
1096 while (++Idx <= Num) {
1097 GepNode *
N = NA[Idx-1];
1101 if (NA[Idx]->Flags & GepNode::Pointer)
1110 InpTy = NA[Idx]->PTy;
1112 }
while (Idx <= Num);
1117void HexagonCommonGEP::getAllUsersForNode(GepNode *Node, ValueVect &Values,
1118 NodeChildrenMap &NCM) {
1120 Work.push_back(Node);
1122 while (!Work.empty()) {
1123 NodeVect::iterator
First = Work.begin();
1126 if (
N->Flags & GepNode::Used) {
1127 NodeToUsesMap::iterator
UF =
Uses.find(
N);
1128 assert(UF !=
Uses.end() &&
"No use information for used node");
1129 UseSet &Us =
UF->second;
1130 for (
const auto &U : Us)
1131 Values.push_back(
U->getUser());
1133 NodeChildrenMap::iterator CF = NCM.find(
N);
1134 if (CF != NCM.end()) {
1135 NodeVect &Cs = CF->second;
1141void HexagonCommonGEP::materialize(NodeToValueMap &Loc) {
1142 LLVM_DEBUG(
dbgs() <<
"Nodes before materialization:\n" << Nodes <<
'\n');
1143 NodeChildrenMap NCM;
1149 while (!Roots.empty()) {
1150 NodeVect::iterator
First = Roots.begin();
1160 bool LastUsed =
false;
1161 unsigned LastCN = 0;
1170 LastUsed = (
Last->Flags & GepNode::Used);
1173 NodeChildrenMap::iterator CF = NCM.find(
Last);
1174 LastCN = (CF != NCM.end()) ? CF->second.size() : 0;
1177 GepNode *Child = CF->second.front();
1179 if (ChildB !=
nullptr && LastB != ChildB)
1185 if (LastUsed || LastCN > 0) {
1187 getAllUsersForNode(Root, Urs, NCM);
1189 if (FirstUse != LastB->
end())
1190 InsertAt = FirstUse;
1194 Value *NewInst = fabricateGEP(NA, InsertAt, LastB);
1199 NodeVect &Cs = NCM[
Last];
1200 for (GepNode *CN : Cs) {
1201 CN->Flags &= ~GepNode::Internal;
1202 CN->Flags |= GepNode::Root;
1203 CN->BaseVal = NewInst;
1204 Roots.push_back(CN);
1211 NodeToUsesMap::iterator
UF =
Uses.find(
Last);
1212 assert(UF !=
Uses.end() &&
"No use information found");
1213 UseSet &Us =
UF->second;
1220void HexagonCommonGEP::removeDeadCode() {
1222 BO.push_back(&Fn->
front());
1224 for (
unsigned i = 0; i < BO.size(); ++i) {
1227 BO.push_back(DTN->getBlock());
1238 In->eraseFromParent();
1243bool HexagonCommonGEP::runOnFunction(Function &
F) {
1244 if (skipFunction(
F))
1248 for (
const BasicBlock &BB :
F)
1249 for (
const Instruction &
I : BB)
1254 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1255 PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
1256 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1257 Ctx = &
F.getContext();
1263 SpecificBumpPtrAllocator<GepNode>
Allocator;
1270 computeNodePlacement(Loc);
1274#ifdef EXPENSIVE_CHECKS
1285 return new HexagonCommonGEP();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static bool runOnFunction(Function &F, bool PostInlining)
This file defines a hash set that can be used to remove duplication of nodes in a graph.
This file defines the little GraphTraits<X> template class that should be specialized by classes that...
static unsigned node_hash(GepNode *N)
static cl::opt< bool > OptEnableInv("commgep-inv", cl::init(true), cl::Hidden)
static NodePair node_pair(GepNode *N1, GepNode *N2)
static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq, NodePairSet &Ne)
static const NodeSet * node_class(GepNode *N, NodeSymRel &Rel)
static cl::opt< bool > OptEnableConst("commgep-const", cl::init(true), cl::Hidden)
static BasicBlock * nearest_common_dominatee(DominatorTree *DT, T &Blocks)
static cl::opt< bool > OptSpeculate("commgep-speculate", cl::init(true), cl::Hidden)
static void invert_find_roots(const NodeVect &Nodes, NodeChildrenMap &NCM, NodeVect &Roots)
static BasicBlock * nearest_common_dominator(DominatorTree *DT, T &Blocks)
static bool is_empty(const BasicBlock *B)
static void nodes_for_root(GepNode *Root, NodeChildrenMap &NCM, NodeSet &Nodes)
static BasicBlock * preheader(DominatorTree *DT, Loop *L)
static BasicBlock::iterator first_use_of_in_block(T &Values, BasicBlock *B)
This defines the Use class.
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
#define INITIALIZE_PASS_DEPENDENCY(depName)
#define INITIALIZE_PASS_END(passName, arg, name, cfg, analysis)
#define INITIALIZE_PASS_BEGIN(passName, arg, name, cfg, analysis)
Remove Loads Into Fake Uses
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallVector class.
AnalysisUsage & addRequired()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
LLVM Basic Block Representation.
LLVM_ABI BasicBlock::iterator erase(BasicBlock::iterator FromIt, BasicBlock::iterator ToIt)
Erases a range of instructions from FromIt to (not including) ToIt.
InstListType::iterator iterator
Instruction iterators...
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
This is the shared class of boolean and integer constants.
DomTreeNodeBase * getIDom() const
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
bool properlyDominates(const DomTreeNodeBase< NodeT > *A, const DomTreeNodeBase< NodeT > *B) const
properlyDominates - Returns true iff A dominates B and A != B.
Legacy analysis pass which computes a DominatorTree.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree.
LLVM_ABI Instruction * findNearestCommonDominator(Instruction *I1, Instruction *I2) const
Find the nearest instruction I that dominates both I1 and I2, in the sense that a result produced bef...
LLVM_ABI bool dominates(const BasicBlock *BB, const Use &U) const
Return true if the (end of the) basic block BB dominates the use U.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
FunctionPass class - This class is used to implement most global optimizations.
const BasicBlock & front() const
LLVM_ABI bool isInBounds() const
Determine whether the GEP has the inbounds flag.
static LLVM_ABI Type * getTypeAtIndex(Type *Ty, Value *Idx)
Return the type of the element at the given index of an indexable type.
Value * getPointerOperand()
iterator_range< op_iterator > indices()
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", InsertPosition InsertBefore=nullptr)
LLVM_ABI void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
Type * getSourceElementType() const
static unsigned getPointerOperandIndex()
LoopT * getParentLoop() const
Return the parent loop if it exists or nullptr for top level loops.
LoopT * getLoopFor(const BlockT *BB) const
Return the inner most loop that BB lives in.
The legacy pass manager's analysis pass to compute loop information.
Represents a single loop in the control flow graph.
A NodeSet contains a set of SUnit DAG nodes with additional information that assigns a priority to th...
SetVector< SUnit * >::const_iterator iterator
LLVM_ABI bool dominates(const Instruction *I1, const Instruction *I2) const
Return true if I1 dominates I2.
A vector that has set insertion semantics.
void push_back(const T &Elt)
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
static unsigned getPointerOperandIndex()
Class to represent struct types.
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition.
The instances of the Type class are immutable: once they are created, they are never changed.
bool isPointerTy() const
True if this is an instance of PointerType.
LLVM_ABI StringRef getStructName() const
bool isStructTy() const
True if this is an instance of StructType.
A Use represents the edge between a Value definition and its users.
LLVM Value Representation.
Type * getType() const
All values are typed, get the type of this value.
user_iterator user_begin()
LLVM_ABI StringRef getName() const
Return a constant reference to the value's name.
const ParentTy * getParent() const
self_iterator getIterator()
This class implements an extremely fast bulk output stream that can only output to a stream.
void dump_node_container(raw_ostream &OS, const NodeContainer &S)
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
@ C
The default llvm calling convention, compatible with C.
@ BasicBlock
Various leaf nodes.
initializer< Ty > init(const Ty &Val)
@ User
could "use" a pointer
NodeAddr< NodeBase * > Node
std::set< NodeId > NodeSet
friend class Instruction
Iterator for Instructions in a `BasicBlock.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
FunctionAddr VTableAddr Value
auto min_element(R &&Range)
Provide wrappers to std::min_element which take ranges instead of having to pass begin/end explicitly...
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
FunctionAddr VTableAddr uintptr_t uintptr_t Int32Ty
LLVM_ABI bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
auto cast_or_null(const Y &Val)
DomTreeNodeBase< BasicBlock > DomTreeNode
LLVM_ABI bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction will return.
auto reverse(ContainerTy &&C)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
LLVM_ABI void report_fatal_error(Error Err, bool gen_crash_diag=true)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
FunctionPass * createHexagonCommonGEP()
DWARFExpression::Operation Op
raw_ostream & operator<<(raw_ostream &OS, const APFixedPoint &FX)
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
iterator_range< typename GraphTraits< GraphType >::ChildIteratorType > children(const typename GraphTraits< GraphType >::NodeRef &G)
GepNode(const GepNode *N)