10 #define DEBUG_TYPE "commgep" 70 using NodeSet = std::set<GepNode *>;
71 using NodeToValueMap = std::map<GepNode *, Value *>;
72 using NodeVect = std::vector<GepNode *>;
73 using NodeChildrenMap = std::map<GepNode *, NodeVect>;
74 using UseSet = std::set<Use *>;
75 using NodeToUsesMap = std::map<GepNode *, UseSet>;
80 NodeOrdering() =
default;
82 void insert(
const GepNode *
N) { Map.insert(std::make_pair(N, ++LastNum)); }
83 void clear() { Map.clear(); }
85 bool operator()(
const GepNode *N1,
const GepNode *N2)
const {
86 auto F1 = Map.find(N1), F2 = Map.find(N2);
87 assert(F1 != Map.end() && F2 != Map.end());
88 return F1->second < F2->second;
92 std::map<const GepNode *, unsigned> Map;
105 StringRef getPassName()
const override {
return "Hexagon Common GEP"; }
118 using ValueToNodeMap = std::map<Value *, GepNode *>;
119 using ValueVect = std::vector<Value *>;
120 using NodeToValuesMap = std::map<GepNode *, ValueVect>;
122 void getBlockTraversalOrder(
BasicBlock *Root, ValueVect &Order);
128 BasicBlock *recalculatePlacement(GepNode *Node, NodeChildrenMap &NCM,
129 NodeToValueMap &Loc);
130 BasicBlock *recalculatePlacementRec(GepNode *Node, NodeChildrenMap &NCM,
131 NodeToValueMap &Loc);
133 bool isInvariantIn(GepNode *Node,
Loop *L);
135 BasicBlock *adjustForInvariance(GepNode *Node, NodeChildrenMap &NCM,
136 NodeToValueMap &Loc);
137 void separateChainForNode(GepNode *Node,
Use *U, NodeToValueMap &Loc);
138 void separateConstantChains(GepNode *Node, NodeChildrenMap &NCM,
139 NodeToValueMap &Loc);
140 void computeNodePlacement(NodeToValueMap &Loc);
144 void getAllUsersForNode(GepNode *Node, ValueVect &Values,
145 NodeChildrenMap &NCM);
146 void materialize(NodeToValueMap &Loc);
148 void removeDeadCode();
204 if (
auto *PTy = dyn_cast<PointerType>(Ty))
205 return PTy->getElementType();
208 Type *NexTy = cast<SequentialType>(Ty)->getElementType();
213 assert(CI &&
"Struct type with non-constant index");
215 Type *NextTy = cast<StructType>(Ty)->getElementType(i);
222 if (GN.
Flags & GepNode::Root) {
226 if (GN.
Flags & GepNode::Internal) {
232 if (GN.
Flags & GepNode::Used) {
237 if (GN.
Flags & GepNode::InBounds) {
243 if (GN.
Flags & GepNode::Root)
246 OS <<
"Parent:" << GN.
Parent;
250 OS << CI->getValue().getSExtValue();
254 OS <<
"<anon> =" << *GN.
Idx;
262 OS <<
"<anon-struct>:" << *STy;
270 template <
typename NodeContainer>
272 using const_iterator =
typename NodeContainer::const_iterator;
274 for (const_iterator
I = S.begin(),
E = S.end();
I !=
E; ++
I)
275 OS << *
I <<
' ' << **
I <<
'\n';
288 using const_iterator = NodeToUsesMap::const_iterator;
290 for (const_iterator
I = M.begin(),
E = M.end();
I !=
E; ++
I) {
291 const UseSet &Us =
I->second;
292 OS <<
I->first <<
" -> #" << Us.size() <<
'{';
293 for (UseSet::const_iterator J = Us.begin(),
F = Us.end(); J !=
F; ++J) {
294 User *R = (*J)->getUser();
298 OS <<
" <?>(" << *R <<
')';
309 return NS.find(N) != NS.end();
322 void HexagonCommonGEP::getBlockTraversalOrder(
BasicBlock *Root,
328 Order.push_back(Root);
329 for (
auto *DTN : children<DomTreeNode*>(DT->getNode(Root)))
330 getBlockTraversalOrder(DTN->getBlock(), Order);
344 ValueToNodeMap &NM) {
346 GepNode *N =
new (*Mem) GepNode;
349 ValueToNodeMap::iterator
F = NM.find(PtrOp);
352 N->Flags |= GepNode::Root | InBounds;
357 N->Parent = F->second;
369 if (isa<GetElementPtrInst>(*UI)) {
371 if (isHandledGepForm(UserG))
374 Us.insert(&UI.getUse());
382 Type *PtrTy = cast<PointerType>(PtrOp->
getType())->getElementType();
386 GepNode *Nx =
new (*Mem) GepNode;
388 Nx->Flags |= GepNode::Internal | InBounds;
400 PN->Flags |= GepNode::Used;
401 Uses[PN].insert(Us.begin(), Us.end());
406 NM.insert(std::make_pair(GepI, PN));
409 void HexagonCommonGEP::collect() {
412 getBlockTraversalOrder(&Fn->front(), BO);
418 for (ValueVect::iterator
I = BO.begin(),
E = BO.end();
I !=
E; ++
I) {
421 if (!isa<GetElementPtrInst>(J))
424 if (isHandledGepForm(GepI))
425 processGepInst(GepI, NM);
429 LLVM_DEBUG(
dbgs() <<
"Gep nodes after initial collection:\n" << Nodes);
434 using const_iterator = NodeVect::const_iterator;
436 for (const_iterator
I = Nodes.begin(),
E = Nodes.end();
I !=
E; ++
I) {
438 if (N->Flags & GepNode::Root) {
442 GepNode *PN = N->Parent;
443 NCM[PN].push_back(N);
450 Work.push_back(Root);
453 while (!Work.empty()) {
454 NodeVect::iterator First = Work.begin();
457 NodeChildrenMap::iterator CF = NCM.find(N);
458 if (CF != NCM.end()) {
459 Work.insert(Work.end(), CF->second.begin(), CF->second.end());
460 Nodes.
insert(CF->second.begin(), CF->second.end());
467 using NodeSymRel = std::set<NodeSet>;
468 using NodePair = std::pair<GepNode *, GepNode *>;
469 using NodePairSet = std::set<NodePair>;
474 for (NodeSymRel::iterator
I = Rel.begin(),
E = Rel.end();
I !=
E; ++
I)
484 uintptr_t P1 = uintptr_t(N1), P2 = uintptr_t(N2);
486 return std::make_pair(N1, N2);
487 return std::make_pair(N2, N1);
498 static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq,
506 NodePairSet::iterator FEq = Eq.find(NP);
509 NodePairSet::iterator FNe = Ne.find(NP);
513 bool Root1 = N1->Flags & GepNode::Root;
514 bool Root2 = N2->Flags & GepNode::Root;
519 if (Root1 != Root2 || (Root1 && N1->BaseVal != N2->BaseVal)) {
526 if (Root1 ||
node_eq(N1->Parent, N2->Parent, Eq, Ne)) {
533 void HexagonCommonGEP::common() {
538 using NodeSetMap = std::map<unsigned, NodeSet>;
541 for (NodeVect::iterator
I = Nodes.begin(),
E = Nodes.end();
I !=
E; ++
I) {
544 MaybeEq[
H].insert(N);
551 for (NodeSetMap::iterator
I = MaybeEq.begin(),
E = MaybeEq.end();
571 std::pair<NodeSymRel::iterator, bool>
Ins = EqRel.insert(C);
573 assert(Ins.second &&
"Cannot add a class");
579 dbgs() <<
"Gep node equality:\n";
580 for (NodePairSet::iterator
I = Eq.begin(),
E = Eq.end();
I !=
E; ++
I)
581 dbgs() <<
"{ " <<
I->first <<
", " <<
I->second <<
" }\n";
583 dbgs() <<
"Gep equivalence classes:\n";
584 for (NodeSymRel::iterator
I = EqRel.begin(),
E = EqRel.end();
I !=
E; ++
I) {
587 for (NodeSet::const_iterator J = S.
begin(),
F = S.
end(); J !=
F; ++J) {
597 using ProjMap = std::map<const NodeSet *, GepNode *>;
599 for (NodeSymRel::iterator
I = EqRel.begin(),
E = EqRel.end();
I !=
E; ++
I) {
602 std::pair<ProjMap::iterator,bool>
Ins = PM.insert(std::make_pair(&S, Min));
604 assert(Ins.second &&
"Cannot add minimal element");
608 UseSet &MinUs = Uses[Min];
614 if (NF & GepNode::Used)
615 MinUs.insert(Uses[N].
begin(), Uses[N].
end());
622 assert((Min->Flags & Flags) == Min->Flags);
630 for (NodeVect::iterator
I = Nodes.begin(),
E = Nodes.end();
I !=
E; ++
I) {
632 if (N->Flags & GepNode::Root)
637 ProjMap::iterator
F = PM.find(PC);
641 GepNode *Rep = F->second;
649 for (NodeVect::iterator
I = Nodes.begin(),
E = Nodes.end();
I !=
E; ++
I) {
654 ProjMap::iterator
F = PM.find(PC);
662 NodeVect::iterator NewE =
remove_if(Nodes, in_set(Erase));
663 Nodes.resize(std::distance(Nodes.begin(), NewE));
665 LLVM_DEBUG(
dbgs() <<
"Gep nodes after post-commoning cleanup:\n" << Nodes);
668 template <
typename T>
671 dbgs() <<
"NCD of {";
672 for (
typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
I !=
E;
683 typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
697 template <
typename T>
701 typename T::iterator
I = Blocks.begin(),
E = Blocks.end();
703 while (I !=
E && !*I)
723 template <
typename T>
727 using iterator =
typename T::iterator;
729 for (iterator
I = Values.begin(),
E = Values.end();
I !=
E; ++
I) {
738 if (!isa<Instruction>(V))
744 if (std::distance(FirstUse, BEnd) < std::distance(It, BEnd))
754 BasicBlock *HexagonCommonGEP::recalculatePlacement(GepNode *Node,
755 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
767 if (Node->Flags & GepNode::Used) {
770 NodeToUsesMap::iterator UF = Uses.find(Node);
771 assert(UF != Uses.end() &&
"Used node with no use information");
772 UseSet &Us = UF->second;
773 for (UseSet::iterator
I = Us.begin(),
E = Us.end();
I !=
E; ++
I) {
775 User *R = U->getUser();
776 if (!isa<Instruction>(R))
779 ? cast<PHINode>(R)->getIncomingBlock(*U)
785 NodeChildrenMap::iterator CF = NCM.find(Node);
786 if (CF != NCM.end()) {
787 NodeVect &Cs = CF->second;
788 for (NodeVect::iterator
I = Cs.begin(),
E = Cs.end();
I !=
E; ++
I) {
790 NodeToValueMap::iterator LF = Loc.find(CN);
796 Bs.push_back(LF->second);
805 if (IdxI && !DT->dominates(IdxI->
getParent(), DomB))
821 BasicBlock *HexagonCommonGEP::recalculatePlacementRec(GepNode *Node,
822 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
826 NodeChildrenMap::iterator CF = NCM.find(Node);
827 if (CF != NCM.end()) {
828 NodeVect &Cs = CF->second;
829 for (NodeVect::iterator
I = Cs.begin(),
E = Cs.end();
I !=
E; ++
I)
830 recalculatePlacementRec(*
I, NCM, Loc);
832 BasicBlock *LB = recalculatePlacement(Node, NCM, Loc);
837 bool HexagonCommonGEP::isInvariantIn(
Value *Val,
Loop *L) {
838 if (isa<Constant>(Val) || isa<Argument>(Val))
844 return DT->properlyDominates(DefB, HdrB);
847 bool HexagonCommonGEP::isInvariantIn(GepNode *Node,
Loop *L) {
848 if (Node->Flags & GepNode::Root)
849 if (!isInvariantIn(Node->BaseVal, L))
851 return isInvariantIn(Node->Idx, L);
858 if (PDT->dominates(B, HB))
860 if (LB && DT->dominates(B, LB))
876 BasicBlock *HexagonCommonGEP::adjustForInvariance(GepNode *Node,
877 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
882 if (Node->Flags & GepNode::Root) {
883 if (
Instruction *PIn = dyn_cast<Instruction>(Node->BaseVal))
884 Bs.push_back(PIn->getParent());
886 Bs.push_back(Loc[Node->Parent]);
888 if (
Instruction *IIn = dyn_cast<Instruction>(Node->Idx))
889 Bs.push_back(IIn->getParent());
900 BasicBlock *LocB = cast_or_null<BasicBlock>(Loc[Node]);
902 Loop *Lp = LI->getLoopFor(LocB);
904 if (!isInvariantIn(Node, Lp) || !isInMainPath(LocB, Lp))
907 if (!NewLoc || !DT->dominates(TopB, NewLoc))
916 NodeChildrenMap::iterator CF = NCM.find(Node);
917 if (CF != NCM.end()) {
918 NodeVect &Cs = CF->second;
919 for (NodeVect::iterator
I = Cs.begin(),
E = Cs.end();
I !=
E; ++
I)
920 adjustForInvariance(*
I, NCM, Loc);
927 struct LocationAsBlock {
928 LocationAsBlock(
const NodeToValueMap &L) : Map(L) {}
930 const NodeToValueMap ⤅
936 for (NodeToValueMap::const_iterator
I = Loc.Map.begin(),
E = Loc.Map.end();
938 OS <<
I->first <<
" -> ";
940 OS << B->
getName() <<
'(' << B <<
')';
947 return isa<ConstantInt>(N->Idx);
952 void HexagonCommonGEP::separateChainForNode(GepNode *Node,
Use *U,
953 NodeToValueMap &Loc) {
954 User *R = U->getUser();
955 LLVM_DEBUG(
dbgs() <<
"Separating chain for node (" << Node <<
") user: " << *R
960 GepNode *
C =
nullptr, *NewNode =
nullptr;
961 while (
is_constant(N) && !(N->Flags & GepNode::Root)) {
963 GepNode *NewN =
new (*Mem) GepNode(N);
964 Nodes.push_back(NewN);
969 NewN->Flags &= ~GepNode::Used;
979 NodeToUsesMap::iterator UF = Uses.find(Node);
981 UseSet &Us = UF->second;
983 for (UseSet::iterator
I = Us.begin();
I != Us.end(); ) {
984 User *S = (*I)->getUser();
985 UseSet::iterator Nx = std::next(
I);
993 Node->Flags &= ~GepNode::Used;
998 NewNode->Flags |= GepNode::Used;
999 LLVM_DEBUG(
dbgs() <<
"new node: " << NewNode <<
" " << *NewNode <<
'\n');
1001 Uses[NewNode] = NewUs;
1004 void HexagonCommonGEP::separateConstantChains(GepNode *Node,
1005 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
1010 LLVM_DEBUG(
dbgs() <<
"Separating constant chains for node: " << Node <<
'\n');
1016 if (!(N->Flags & GepNode::Used))
1018 NodeToUsesMap::iterator UF = Uses.find(N);
1019 assert(UF != Uses.end());
1020 UseSet &Us = UF->second;
1023 for (UseSet::iterator J = Us.begin(),
F = Us.end(); J !=
F; ++J) {
1025 User *R = U->getUser();
1029 if (
LoadInst *Ld = dyn_cast<LoadInst>(R)) {
1031 if (&Ld->getOperandUse(PtrX) == U)
1033 }
else if (
StoreInst *St = dyn_cast<StoreInst>(R)) {
1035 if (&St->getOperandUse(PtrX) == U)
1044 FNs.insert(std::make_pair(N, LSs));
1049 for (NodeToUsesMap::iterator
I = FNs.begin(),
E = FNs.end();
I !=
E; ++
I) {
1050 GepNode *N =
I->first;
1051 UseSet &Us =
I->second;
1052 for (UseSet::iterator J = Us.begin(),
F = Us.end(); J !=
F; ++J)
1053 separateChainForNode(N, *J, Loc);
1057 void HexagonCommonGEP::computeNodePlacement(NodeToValueMap &Loc) {
1060 NodeChildrenMap NCM;
1066 for (NodeVect::iterator
I = Roots.begin(),
E = Roots.end();
I !=
E; ++
I)
1067 recalculatePlacementRec(*
I, NCM, Loc);
1069 LLVM_DEBUG(
dbgs() <<
"Initial node placement:\n" << LocationAsBlock(Loc));
1072 for (NodeVect::iterator
I = Roots.begin(),
E = Roots.end();
I !=
E; ++
I)
1073 adjustForInvariance(*
I, NCM, Loc);
1075 LLVM_DEBUG(
dbgs() <<
"Node placement after adjustment for invariance:\n" 1076 << LocationAsBlock(Loc));
1079 for (NodeVect::iterator
I = Roots.begin(),
E = Roots.end();
I !=
E; ++
I)
1080 separateConstantChains(*
I, NCM, Loc);
1088 LLVM_DEBUG(
dbgs() <<
"Final node placement:\n" << LocationAsBlock(Loc));
1096 unsigned Num = NA.size();
1097 GepNode *
RN = NA[0];
1098 assert((RN->Flags & GepNode::Root) &&
"Creating GEP for non-root");
1101 Value *Input = RN->BaseVal;
1109 if (!NA[nax]->PTy->isPointerTy()) {
1116 while (++nax <= Num) {
1117 GepNode *N = NA[nax-1];
1118 IdxList[IdxC++] = N->Idx;
1123 if (NextTy != NA[nax]->PTy)
1134 }
while (nax <= Num);
1140 void HexagonCommonGEP::getAllUsersForNode(GepNode *Node, ValueVect &Values,
1141 NodeChildrenMap &NCM) {
1143 Work.push_back(Node);
1145 while (!Work.empty()) {
1146 NodeVect::iterator First = Work.begin();
1147 GepNode *N = *First;
1149 if (N->Flags & GepNode::Used) {
1150 NodeToUsesMap::iterator UF = Uses.find(N);
1151 assert(UF != Uses.end() &&
"No use information for used node");
1152 UseSet &Us = UF->second;
1153 for (UseSet::iterator
I = Us.begin(),
E = Us.end();
I !=
E; ++
I)
1154 Values.push_back((*I)->getUser());
1156 NodeChildrenMap::iterator CF = NCM.find(N);
1157 if (CF != NCM.end()) {
1158 NodeVect &Cs = CF->second;
1159 Work.insert(Work.end(), Cs.begin(), Cs.end());
1164 void HexagonCommonGEP::materialize(NodeToValueMap &Loc) {
1165 LLVM_DEBUG(
dbgs() <<
"Nodes before materialization:\n" << Nodes <<
'\n');
1166 NodeChildrenMap NCM;
1172 while (!Roots.empty()) {
1173 NodeVect::iterator First = Roots.begin();
1174 GepNode *Root = *First, *Last = *First;
1183 bool LastUsed =
false;
1184 unsigned LastCN = 0;
1187 Value *LocV = Loc[Last];
1193 LastUsed = (Last->Flags & GepNode::Used);
1196 NodeChildrenMap::iterator CF = NCM.find(Last);
1197 LastCN = (CF != NCM.end()) ? CF->second.size() : 0;
1200 GepNode *Child = CF->second.front();
1201 BasicBlock *ChildB = cast_or_null<BasicBlock>(Loc[Child]);
1202 if (ChildB !=
nullptr && LastB != ChildB)
1208 if (LastUsed || LastCN > 0) {
1210 getAllUsersForNode(Root, Urs, NCM);
1212 if (FirstUse != LastB->
end())
1213 InsertAt = FirstUse;
1217 Value *NewInst = fabricateGEP(NA, InsertAt, LastB);
1222 NodeVect &Cs = NCM[Last];
1223 for (NodeVect::iterator
I = Cs.begin(),
E = Cs.end();
I !=
E; ++
I) {
1225 CN->Flags &= ~GepNode::Internal;
1226 CN->Flags |= GepNode::Root;
1227 CN->BaseVal = NewInst;
1228 Roots.push_back(CN);
1235 NodeToUsesMap::iterator UF = Uses.find(Last);
1236 assert(UF != Uses.end() &&
"No use information found");
1237 UseSet &Us = UF->second;
1238 for (UseSet::iterator
I = Us.begin(),
E = Us.end();
I !=
E; ++
I) {
1246 void HexagonCommonGEP::removeDeadCode() {
1248 BO.push_back(&Fn->front());
1250 for (
unsigned i = 0; i < BO.size(); ++i) {
1252 for (
auto DTN : children<DomTreeNode*>(DT->getNode(B)))
1253 BO.push_back(DTN->getBlock());
1256 for (
unsigned i = BO.size(); i > 0; --i) {
1263 for (reverse_iterator
I = IL.rbegin(),
E = IL.rend();
I !=
E; ++
I)
1265 for (ValueVect::iterator
I = Ins.begin(),
E = Ins.end();
I !=
E; ++
I) {
1274 if (skipFunction(F))
1280 if (isa<InvokeInst>(
I) || isa<LandingPadInst>(
I))
1284 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1285 PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
1286 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1300 computeNodePlacement(Loc);
1304 #ifdef EXPENSIVE_CHECKS 1314 return new HexagonCommonGEP();
void AddPointer(const void *Ptr)
Add* - Add various data types to Bit data.
SymbolTableList< Instruction >::iterator eraseFromParent()
This method unlinks 'this' from the containing basic block and deletes it.
const_iterator end(StringRef path)
Get end iterator over path.
Value * getPointerOperand()
AnalysisUsage & addPreserved()
Add the specified Pass class to the set of analyses preserved by this pass.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
const_iterator begin(StringRef path, Style style=Style::native)
Get begin iterator over path.
This class represents lattice values for constants.
static BasicBlock::iterator first_use_of_in_block(T &Values, BasicBlock *B)
static void nodes_for_root(GepNode *Root, NodeChildrenMap &NCM, NodeSet &Nodes)
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value *> IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
static bool is_empty(const BasicBlock *B)
static cl::opt< bool > OptEnableInv("commgep-inv", cl::init(true), cl::Hidden, cl::ZeroOrMore)
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B) const
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B...
An instruction for reading from memory.
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 defines the Use class.
unsigned ComputeHash() const
ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used to lookup the node in the F...
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
static void invert_find_roots(const NodeVect &Nodes, NodeChildrenMap &NCM, NodeVect &Roots)
iterator begin()
Instruction iterator methods.
FunctionPass * createHexagonCommonGEP()
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
Class to represent struct types.
A Use represents the edge between a Value definition and its users.
void setIsInBounds(bool b=true)
Set or clear the inbounds flag on this GEP instruction.
zlib-gnu style compression
BlockT * getHeader() const
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
int64_t getSExtValue() const
Get sign extended value.
Type * getType() const
All values are typed, get the type of this value.
bool isInBounds() const
Determine whether the GEP has the inbounds flag.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
const APInt & getValue() const
Return the constant as an APInt value reference.
An instruction for storing to memory.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
static cl::opt< bool > OptEnableConst("commgep-const", cl::init(true), cl::Hidden, cl::ZeroOrMore)
Type * getScalarType() const
If this is a vector type, return the element type, otherwise return 'this'.
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
an instruction for type-safe pointer arithmetic to access elements of arrays and structs ...
static bool runOnFunction(Function &F, bool PostInlining)
initializer< Ty > init(const Ty &Val)
Type * next_type(Type *Ty, Value *Idx)
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
LLVM Basic Block Representation.
The instances of the Type class are immutable: once they are created, they are never changed...
static unsigned getPointerOperandIndex()
This is an important class for using LLVM in a threaded context.
DomTreeNodeBase * getIDom() const
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file contains the declarations for the subclasses of Constant, which represent the different fla...
bool isPointerTy() const
True if this is an instance of PointerType.
static unsigned node_hash(GepNode *N)
Represent the analysis usage information of a pass.
FunctionPass class - This class is used to implement most global optimizations.
self_iterator getIterator()
static BasicBlock * preheader(DominatorTree *DT, Loop *L)
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(adl_begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
static cl::opt< bool > OptSpeculate("commgep-speculate", cl::init(true), cl::Hidden, cl::ZeroOrMore)
DomTreeNodeBase< NodeT > * getNode(const NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE, "Assign register bank of generic virtual registers", false, false) RegBankSelect
SetVector< SUnit * >::const_iterator iterator
const InstListType & getInstList() const
Return the underlying instruction list container.
Iterator for intrusive lists based on ilist_node.
GepNode(const GepNode *N)
This is the shared class of boolean and integer constants.
void initializeHexagonCommonGEPPass(PassRegistry &)
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
static Constant * get(Type *Ty, uint64_t V, bool isSigned=false)
If Ty is a vector type, return a Constant with a splat of the given value.
A BumpPtrAllocator that allows only elements of a specific type to be allocated.
static BasicBlock * nearest_common_dominator(DominatorTree *DT, T &Blocks)
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static NodePair node_pair(GepNode *N1, GepNode *N2)
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition...
InstListType::iterator iterator
Instruction iterators...
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
static void clear(coro::Shape &Shape)
LoopT * getParentLoop() const
static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq, NodePairSet &Ne)
static IntegerType * getInt32Ty(LLVMContext &C)
Represents a single loop in the control flow graph.
StringRef getName() const
Return a constant reference to the value's name.
user_iterator_impl< User > user_iterator
bool verifyFunction(const Function &F, raw_ostream *OS=nullptr)
Check a function for errors, useful for use when debugging a pass.
LLVM_NODISCARD std::enable_if<!is_simple_type< Y >::value, typename cast_retty< X, const Y >::ret_type >::type dyn_cast(const Y &Val)
raw_ostream & operator<<(raw_ostream &OS, const APInt &I)
INITIALIZE_PASS_BEGIN(HexagonCommonGEP, "hcommgep", "Hexagon Common GEP", false, false) INITIALIZE_PASS_END(HexagonCommonGEP
static unsigned getPointerOperandIndex()
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
user_iterator user_begin()
bool isInstructionTriviallyDead(Instruction *I, const TargetLibraryInfo *TLI=nullptr)
Return true if the result produced by the instruction is not used, and the instruction has no side ef...
LLVM Value Representation.
static const Function * getParent(const Value *V)
This class implements an extremely fast bulk output stream that can only output to a stream...
The legacy pass manager's analysis pass to compute loop information.
StringRef - Represent a constant reference to a string, i.e.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
Legacy analysis pass which computes a DominatorTree.
#define LLVM_ATTRIBUTE_UNUSED
static BasicBlock * nearest_common_dominatee(DominatorTree *DT, T &Blocks)
base_list_type::reverse_iterator reverse_iterator
void dump_node_container(raw_ostream &OS, const NodeContainer &S)
static const NodeSet * node_class(GepNode *N, NodeSymRel &Rel)
bool isStructTy() const
True if this is an instance of StructType.
const BasicBlock * getParent() const
A NodeSet contains a set of SUnit DAG nodes with additional information that assigns a priority to th...
StringRef getStructName() const