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';
285 for (
const auto &
I : M) {
286 const UseSet &Us =
I.second;
287 OS <<
I.first <<
" -> #" << Us.size() <<
'{';
288 for (
const Use *U : Us) {
289 User *R = U->getUser();
291 OS <<
' ' << R->getName();
293 OS <<
" <?>(" << *R <<
')';
304 return NS.find(
N) != NS.end();
317void HexagonCommonGEP::getBlockTraversalOrder(
BasicBlock *Root,
323 Order.push_back(Root);
325 getBlockTraversalOrder(DTN->getBlock(), Order);
328bool HexagonCommonGEP::isHandledGepForm(GetElementPtrInst *GepI) {
338void HexagonCommonGEP::processGepInst(GetElementPtrInst *GepI,
339 ValueToNodeMap &NM) {
341 GepNode *
N =
new (*Mem) GepNode;
343 uint32_t InBounds = GepI->
isInBounds() ? GepNode::InBounds : 0;
344 ValueToNodeMap::iterator
F = NM.find(PtrOp);
347 N->Flags |= GepNode::Root | InBounds;
352 N->Parent =
F->second;
355 N->Flags |= GepNode::Pointer;
367 if (isHandledGepForm(UserG))
370 Us.insert(&UI.getUse());
381 GepNode *Nx =
new (*Mem) GepNode;
383 Nx->Flags |= GepNode::Internal | InBounds;
395 PN->Flags |= GepNode::Used;
396 Uses[PN].insert_range(Us);
401 NM.insert(std::make_pair(GepI, PN));
404void HexagonCommonGEP::collect() {
407 getBlockTraversalOrder(&Fn->
front(), BO);
415 for (Instruction &J : *
B)
417 if (isHandledGepForm(GepI))
418 processGepInst(GepI, NM);
421 LLVM_DEBUG(
dbgs() <<
"Gep nodes after initial collection:\n" << Nodes);
426 for (GepNode *
N : Nodes) {
427 if (
N->Flags & GepNode::Root) {
431 GepNode *PN =
N->Parent;
432 NCM[PN].push_back(
N);
439 Work.push_back(Root);
442 while (!Work.empty()) {
443 NodeVect::iterator
First = Work.begin();
446 NodeChildrenMap::iterator CF = NCM.find(
N);
447 if (CF != NCM.end()) {
449 Nodes.
insert(CF->second.begin(), CF->second.end());
456 using NodeSymRel = std::set<NodeSet>;
457 using NodePair = std::pair<GepNode *, GepNode *>;
458 using NodePairSet = std::set<NodePair>;
473 uintptr_t P1 =
reinterpret_cast<uintptr_t
>(N1);
474 uintptr_t P2 =
reinterpret_cast<uintptr_t
>(N2);
476 return std::make_pair(N1, N2);
477 return std::make_pair(N2, N1);
483 ID.AddPointer(
N->Idx);
484 ID.AddPointer(
N->PTy);
485 return ID.ComputeHash();
488static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq,
496 NodePairSet::iterator FEq = Eq.find(NP);
499 NodePairSet::iterator FNe = Ne.find(NP);
503 bool Root1 = N1->Flags & GepNode::Root;
504 uint32_t CmpFlags = GepNode::Root | GepNode::Pointer;
505 bool Different = (N1->Flags & CmpFlags) != (N2->Flags & CmpFlags);
511 if (Different || (Root1 && N1->BaseVal != N2->BaseVal)) {
518 if (Root1 ||
node_eq(N1->Parent, N2->Parent, Eq, Ne)) {
525void HexagonCommonGEP::common() {
530 using NodeSetMap = std::map<unsigned, NodeSet>;
533 for (GepNode *
N : Nodes) {
535 MaybeEq[
H].insert(
N);
542 for (
auto &
I : MaybeEq) {
561 std::pair<NodeSymRel::iterator, bool>
Ins = EqRel.insert(
C);
563 assert(
Ins.second &&
"Cannot add a class");
569 dbgs() <<
"Gep node equality:\n";
570 for (NodePairSet::iterator
I = Eq.begin(),
E = Eq.end();
I !=
E; ++
I)
571 dbgs() <<
"{ " <<
I->first <<
", " <<
I->second <<
" }\n";
573 dbgs() <<
"Gep equivalence classes:\n";
574 for (
const NodeSet &S : EqRel) {
576 for (NodeSet::const_iterator J = S.
begin(),
F = S.
end(); J !=
F; ++J) {
586 using ProjMap = std::map<const NodeSet *, GepNode *>;
588 for (
const NodeSet &S : EqRel) {
590 std::pair<ProjMap::iterator,bool>
Ins = PM.insert(std::make_pair(&S, Min));
592 assert(
Ins.second &&
"Cannot add minimal element");
596 UseSet &MinUs =
Uses[Min];
597 for (GepNode *
N : S) {
598 uint32_t NF =
N->Flags;
601 if (NF & GepNode::Used) {
603 MinUs.insert_range(U);
611 assert((Min->Flags & Flags) == Min->Flags);
619 for (GepNode *
N : Nodes) {
620 if (
N->Flags & GepNode::Root)
625 ProjMap::iterator
F = PM.find(PC);
629 GepNode *Rep =
F->second;
637 for (GepNode *
N : Nodes) {
641 ProjMap::iterator
F = PM.find(PC);
651 LLVM_DEBUG(
dbgs() <<
"Gep nodes after post-commoning cleanup:\n" << Nodes);
657 dbgs() <<
"NCD of {";
658 for (
typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
I !=
E;
663 dbgs() <<
' ' <<
B->getName();
669 typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
687 typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
689 while (
I !=
E && !*
I)
713 using iterator =
typename T::iterator;
715 for (
iterator I = Values.begin(),
E = Values.end();
I !=
E; ++
I) {
727 if (In->getParent() !=
B)
730 if (std::distance(FirstUse, BEnd) < std::distance(It, BEnd))
737 return B->empty() || (&*
B->begin() ==
B->getTerminator());
740BasicBlock *HexagonCommonGEP::recalculatePlacement(GepNode *Node,
741 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
753 if (
Node->Flags & GepNode::Used) {
756 NodeToUsesMap::iterator
UF =
Uses.find(Node);
757 assert(UF !=
Uses.end() &&
"Used node with no use information");
758 UseSet &Us =
UF->second;
770 NodeChildrenMap::iterator CF = NCM.find(Node);
771 if (CF != NCM.end()) {
772 NodeVect &Cs = CF->second;
773 for (GepNode *CN : Cs) {
774 NodeToValueMap::iterator LF = Loc.find(CN);
780 Bs.push_back(LF->second);
797 DomB =
N->getBlock();
805BasicBlock *HexagonCommonGEP::recalculatePlacementRec(GepNode *Node,
806 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
810 NodeChildrenMap::iterator CF = NCM.find(Node);
811 if (CF != NCM.end()) {
812 NodeVect &Cs = CF->second;
813 for (GepNode *
C : Cs)
814 recalculatePlacementRec(
C, NCM, Loc);
816 BasicBlock *LB = recalculatePlacement(Node, NCM, Loc);
821bool HexagonCommonGEP::isInvariantIn(
Value *Val, Loop *L) {
831bool HexagonCommonGEP::isInvariantIn(GepNode *Node, Loop *L) {
832 if (
Node->Flags & GepNode::Root)
833 if (!isInvariantIn(
Node->BaseVal, L))
835 return isInvariantIn(
Node->Idx, L);
838bool HexagonCommonGEP::isInMainPath(BasicBlock *
B, Loop *L) {
860BasicBlock *HexagonCommonGEP::adjustForInvariance(GepNode *Node,
861 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
866 if (
Node->Flags & GepNode::Root) {
868 Bs.push_back(PIn->getParent());
870 Bs.push_back(Loc[
Node->Parent]);
873 Bs.push_back(IIn->getParent());
888 if (!isInvariantIn(Node, Lp) || !isInMainPath(LocB, Lp))
891 if (!NewLoc || !DT->
dominates(TopB, NewLoc))
900 NodeChildrenMap::iterator CF = NCM.find(Node);
901 if (CF != NCM.end()) {
902 NodeVect &Cs = CF->second;
903 for (GepNode *
C : Cs)
904 adjustForInvariance(
C, NCM, Loc);
911 struct LocationAsBlock {
912 LocationAsBlock(
const NodeToValueMap &L) : Map(
L) {}
914 const NodeToValueMap ⤅
919 raw_ostream &
operator<< (raw_ostream &OS,
const LocationAsBlock &Loc) {
920 for (
const auto &
I : Loc.Map) {
921 OS <<
I.first <<
" -> ";
923 OS <<
B->getName() <<
'(' <<
B <<
')';
925 OS <<
"<null-block>";
931 inline bool is_constant(GepNode *
N) {
937void HexagonCommonGEP::separateChainForNode(GepNode *Node, Use *U,
938 NodeToValueMap &Loc) {
940 LLVM_DEBUG(
dbgs() <<
"Separating chain for node (" << Node <<
") user: " << *R
945 GepNode *
C =
nullptr, *NewNode =
nullptr;
946 while (is_constant(
N) && !(
N->Flags & GepNode::Root)) {
948 GepNode *NewN =
new (*Mem) GepNode(
N);
949 Nodes.push_back(NewN);
954 NewN->Flags &= ~GepNode::Used;
964 NodeToUsesMap::iterator
UF =
Uses.find(Node);
966 UseSet &Us =
UF->second;
969 if (
U->getUser() == R)
976 Node->Flags &= ~GepNode::Used;
981 NewNode->Flags |= GepNode::Used;
982 LLVM_DEBUG(
dbgs() <<
"new node: " << NewNode <<
" " << *NewNode <<
'\n');
984 Uses[NewNode] = NewUs;
987void HexagonCommonGEP::separateConstantChains(GepNode *Node,
988 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
993 LLVM_DEBUG(
dbgs() <<
"Separating constant chains for node: " << Node <<
'\n');
997 for (GepNode *
N : Ns) {
998 if (!(
N->Flags & GepNode::Used))
1000 NodeToUsesMap::iterator
UF =
Uses.find(
N);
1002 UseSet &Us =
UF->second;
1012 if (&Ld->getOperandUse(PtrX) == U)
1016 if (&St->getOperandUse(PtrX) == U)
1025 FNs.insert(std::make_pair(
N, LSs));
1030 for (
auto &FN : FNs) {
1031 GepNode *
N = FN.first;
1032 UseSet &Us = FN.second;
1034 separateChainForNode(
N, U, Loc);
1038void HexagonCommonGEP::computeNodePlacement(NodeToValueMap &Loc) {
1041 NodeChildrenMap NCM;
1047 for (GepNode *Root : Roots)
1048 recalculatePlacementRec(Root, NCM, Loc);
1050 LLVM_DEBUG(
dbgs() <<
"Initial node placement:\n" << LocationAsBlock(Loc));
1053 for (GepNode *Root : Roots)
1054 adjustForInvariance(Root, NCM, Loc);
1056 LLVM_DEBUG(
dbgs() <<
"Node placement after adjustment for invariance:\n"
1057 << LocationAsBlock(Loc));
1060 for (GepNode *Root : Roots)
1061 separateConstantChains(Root, NCM, Loc);
1069 LLVM_DEBUG(
dbgs() <<
"Final node placement:\n" << LocationAsBlock(Loc));
1077 unsigned Num = NA.size();
1078 GepNode *
RN = NA[0];
1079 assert((
RN->Flags & GepNode::Root) &&
"Creating GEP for non-root");
1081 GetElementPtrInst *NewInst =
nullptr;
1091 if (!(NA[Idx]->Flags & GepNode::Pointer)) {
1098 while (++Idx <= Num) {
1099 GepNode *
N = NA[Idx-1];
1103 if (NA[Idx]->Flags & GepNode::Pointer)
1112 InpTy = NA[Idx]->PTy;
1114 }
while (Idx <= Num);
1119void HexagonCommonGEP::getAllUsersForNode(GepNode *Node, ValueVect &Values,
1120 NodeChildrenMap &NCM) {
1122 Work.push_back(Node);
1124 while (!Work.empty()) {
1125 NodeVect::iterator
First = Work.begin();
1128 if (
N->Flags & GepNode::Used) {
1129 NodeToUsesMap::iterator
UF =
Uses.find(
N);
1130 assert(UF !=
Uses.end() &&
"No use information for used node");
1131 UseSet &Us =
UF->second;
1132 for (
const auto &U : Us)
1133 Values.push_back(
U->getUser());
1135 NodeChildrenMap::iterator CF = NCM.find(
N);
1136 if (CF != NCM.end()) {
1137 NodeVect &Cs = CF->second;
1143void HexagonCommonGEP::materialize(NodeToValueMap &Loc) {
1144 LLVM_DEBUG(
dbgs() <<
"Nodes before materialization:\n" << Nodes <<
'\n');
1145 NodeChildrenMap NCM;
1151 while (!Roots.empty()) {
1152 NodeVect::iterator
First = Roots.begin();
1162 bool LastUsed =
false;
1163 unsigned LastCN = 0;
1172 LastUsed = (
Last->Flags & GepNode::Used);
1175 NodeChildrenMap::iterator CF = NCM.find(
Last);
1176 LastCN = (CF != NCM.end()) ? CF->second.size() : 0;
1179 GepNode *Child = CF->second.front();
1181 if (ChildB !=
nullptr && LastB != ChildB)
1187 if (LastUsed || LastCN > 0) {
1189 getAllUsersForNode(Root, Urs, NCM);
1191 if (FirstUse != LastB->
end())
1192 InsertAt = FirstUse;
1196 Value *NewInst = fabricateGEP(NA, InsertAt, LastB);
1201 NodeVect &Cs = NCM[
Last];
1202 for (GepNode *CN : Cs) {
1203 CN->Flags &= ~GepNode::Internal;
1204 CN->Flags |= GepNode::Root;
1205 CN->BaseVal = NewInst;
1206 Roots.push_back(CN);
1213 NodeToUsesMap::iterator
UF =
Uses.find(
Last);
1214 assert(UF !=
Uses.end() &&
"No use information found");
1215 UseSet &Us =
UF->second;
1222void HexagonCommonGEP::removeDeadCode() {
1224 BO.push_back(&Fn->
front());
1226 for (
unsigned i = 0; i < BO.size(); ++i) {
1229 BO.push_back(DTN->getBlock());
1240 In->eraseFromParent();
1245bool HexagonCommonGEP::runOnFunction(Function &
F) {
1246 if (skipFunction(
F))
1250 for (
const BasicBlock &BB :
F)
1251 for (
const Instruction &
I : BB)
1256 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1257 PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
1258 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1259 Ctx = &
F.getContext();
1265 SpecificBumpPtrAllocator<GepNode>
Allocator;
1272 computeNodePlacement(Loc);
1276#ifdef EXPENSIVE_CHECKS
1287 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")
#define LLVM_ATTRIBUTE_UNUSED
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)