10 #define DEBUG_TYPE "commgep"
69 typedef std::set<GepNode*>
NodeSet;
70 typedef std::map<GepNode*,Value*> NodeToValueMap;
71 typedef std::vector<GepNode*> NodeVect;
72 typedef std::map<GepNode*,NodeVect> NodeChildrenMap;
73 typedef std::set<Use*> UseSet;
74 typedef std::map<GepNode*,UseSet> NodeToUsesMap;
79 NodeOrdering() =
default;
81 void insert(
const GepNode *
N) { Map.insert(std::make_pair(N, ++LastNum)); }
82 void clear() { Map.clear(); }
84 bool operator()(
const GepNode *N1,
const GepNode *N2)
const {
85 auto F1 = Map.find(N1), F2 = Map.find(N2);
86 assert(F1 != Map.end() && F2 != Map.end());
87 return F1->second < F2->second;
91 std::map<const GepNode *, unsigned> Map;
103 bool runOnFunction(
Function &
F)
override;
104 StringRef getPassName()
const override {
return "Hexagon Common GEP"; }
117 typedef std::map<Value*,GepNode*> ValueToNodeMap;
118 typedef std::vector<Value*> ValueVect;
119 typedef std::map<GepNode*,ValueVect> NodeToValuesMap;
121 void getBlockTraversalOrder(
BasicBlock *Root, ValueVect &Order);
127 BasicBlock *recalculatePlacement(GepNode *Node, NodeChildrenMap &NCM,
128 NodeToValueMap &Loc);
129 BasicBlock *recalculatePlacementRec(GepNode *Node, NodeChildrenMap &NCM,
130 NodeToValueMap &Loc);
132 bool isInvariantIn(GepNode *Node,
Loop *
L);
134 BasicBlock *adjustForInvariance(GepNode *Node, NodeChildrenMap &NCM,
135 NodeToValueMap &Loc);
136 void separateChainForNode(GepNode *Node,
Use *U, NodeToValueMap &Loc);
137 void separateConstantChains(GepNode *Node, NodeChildrenMap &NCM,
138 NodeToValueMap &Loc);
139 void computeNodePlacement(NodeToValueMap &Loc);
143 void getAllUsersForNode(GepNode *Node, ValueVect &Values,
144 NodeChildrenMap &NCM);
145 void materialize(NodeToValueMap &Loc);
147 void removeDeadCode();
201 if (
auto *PTy = dyn_cast<PointerType>(Ty))
202 return PTy->getElementType();
205 Type *NexTy = cast<SequentialType>(Ty)->getElementType();
210 assert(CI &&
"Struct type with non-constant index");
212 Type *NextTy = cast<StructType>(Ty)->getElementType(i);
219 if (GN.
Flags & GepNode::Root) {
223 if (GN.
Flags & GepNode::Internal) {
229 if (GN.
Flags & GepNode::Used) {
235 if (GN.
Flags & GepNode::Root)
238 OS <<
"Parent:" << GN.
Parent;
242 OS << CI->getValue().getSExtValue();
246 OS <<
"<anon> =" << *GN.
Idx;
254 OS <<
"<anon-struct>:" << *STy;
262 template <
typename NodeContainer>
264 typedef typename NodeContainer::const_iterator const_iterator;
265 for (const_iterator
I = S.begin(),
E = S.end();
I !=
E; ++
I)
266 OS << *
I <<
' ' << **
I <<
'\n';
279 typedef NodeToUsesMap::const_iterator const_iterator;
280 for (const_iterator
I = M.begin(),
E = M.end();
I !=
E; ++
I) {
281 const UseSet &Us =
I->second;
282 OS <<
I->first <<
" -> #" << Us.size() <<
'{';
283 for (UseSet::const_iterator J = Us.begin(),
F = Us.end(); J !=
F; ++J) {
284 User *R = (*J)->getUser();
288 OS <<
" <?>(" << *R <<
')';
298 return NS.find(N) != NS.end();
311 void HexagonCommonGEP::getBlockTraversalOrder(
BasicBlock *Root,
317 Order.push_back(Root);
320 typedef GTN::ChildIteratorType Iter;
321 for (Iter
I = GTN::child_begin(DTN),
E = GTN::child_end(DTN);
I !=
E; ++
I)
322 getBlockTraversalOrder((*I)->getBlock(), Order);
336 ValueToNodeMap &NM) {
337 DEBUG(
dbgs() <<
"Visiting GEP: " << *GepI <<
'\n');
338 GepNode *N =
new (*Mem) GepNode;
340 ValueToNodeMap::iterator
F = NM.find(PtrOp);
343 N->Flags |= GepNode::Root;
348 N->Parent = F->second;
360 if (isa<GetElementPtrInst>(*UI)) {
362 if (isHandledGepForm(UserG))
365 Us.insert(&UI.getUse());
373 Type *PtrTy = cast<PointerType>(PtrOp->
getType())->getElementType();
377 GepNode *Nx =
new (*Mem) GepNode;
379 Nx->Flags |= GepNode::Internal;
391 PN->Flags |= GepNode::Used;
392 Uses[PN].insert(Us.begin(), Us.end());
397 NM.insert(std::make_pair(GepI, PN));
400 void HexagonCommonGEP::collect() {
403 getBlockTraversalOrder(&Fn->front(), BO);
409 for (ValueVect::iterator
I = BO.begin(),
E = BO.end();
I !=
E; ++
I) {
412 if (!isa<GetElementPtrInst>(J))
415 if (isHandledGepForm(GepI))
416 processGepInst(GepI, NM);
420 DEBUG(
dbgs() <<
"Gep nodes after initial collection:\n" << Nodes);
425 typedef NodeVect::const_iterator const_iterator;
426 for (const_iterator I = Nodes.begin(),
E = Nodes.end(); I !=
E; ++
I) {
428 if (N->Flags & GepNode::Root) {
432 GepNode *PN = N->Parent;
433 NCM[PN].push_back(N);
440 Work.push_back(Root);
443 while (!Work.empty()) {
444 NodeVect::iterator First = Work.begin();
447 NodeChildrenMap::iterator CF = NCM.find(N);
448 if (CF != NCM.end()) {
449 Work.insert(Work.end(), CF->second.begin(), CF->second.end());
450 Nodes.insert(CF->second.begin(), CF->second.end());
457 typedef std::set<NodeSet> NodeSymRel;
458 typedef std::pair<GepNode*,GepNode*> NodePair;
459 typedef std::set<NodePair> NodePairSet;
463 static const NodeSet *
node_class(GepNode *N, NodeSymRel &Rel) {
464 for (NodeSymRel::iterator I = Rel.begin(),
E = Rel.end(); I !=
E; ++
I)
474 uintptr_t P1 = uintptr_t(N1), P2 = uintptr_t(N2);
476 return std::make_pair(N1, N2);
477 return std::make_pair(N2, N1);
488 static 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 bool Root2 = N2->Flags & GepNode::Root;
509 if (Root1 != Root2 || (Root1 && N1->BaseVal != N2->BaseVal)) {
516 if (Root1 ||
node_eq(N1->Parent, N2->Parent, Eq, Ne)) {
523 void HexagonCommonGEP::common() {
528 typedef std::map<unsigned,NodeSet> NodeSetMap;
531 for (NodeVect::iterator I = Nodes.begin(),
E = Nodes.end(); I !=
E; ++
I) {
534 MaybeEq[
H].insert(N);
541 for (NodeSetMap::iterator I = MaybeEq.begin(),
E = MaybeEq.end();
543 NodeSet &S = I->second;
544 for (NodeSet::iterator NI = S.begin(),
NE = S.end(); NI !=
NE; ++NI) {
554 for (NodeSet::iterator NJ = std::next(NI); NJ !=
NE; ++NJ)
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 (NodeSymRel::iterator I = EqRel.begin(),
E = EqRel.end(); I !=
E; ++
I) {
576 const NodeSet &S = *
I;
577 for (NodeSet::const_iterator J = S.begin(), F = S.end(); J !=
F; ++J) {
587 typedef std::map<const NodeSet*,GepNode*> ProjMap;
589 for (NodeSymRel::iterator I = EqRel.begin(),
E = EqRel.end(); I !=
E; ++
I) {
590 const NodeSet &S = *
I;
591 GepNode *
Min = *std::min_element(S.begin(), S.end(),
NodeOrder);
592 std::pair<ProjMap::iterator,bool>
Ins = PM.insert(std::make_pair(&S, Min));
594 assert(Ins.second &&
"Cannot add minimal element");
598 UseSet &MinUs = Uses[Min];
599 for (NodeSet::iterator J = S.begin(), F = S.end(); J !=
F; ++J) {
604 if (NF & GepNode::Used)
605 MinUs.insert(Uses[N].
begin(), Uses[N].
end());
612 assert((Min->Flags & Flags) == Min->Flags);
620 for (NodeVect::iterator I = Nodes.begin(),
E = Nodes.end(); I !=
E; ++
I) {
622 if (N->Flags & GepNode::Root)
627 ProjMap::iterator F = PM.find(PC);
631 GepNode *Rep = F->second;
635 DEBUG(
dbgs() <<
"Gep nodes after commoning:\n" << Nodes);
639 for (NodeVect::iterator I = Nodes.begin(),
E = Nodes.end(); I !=
E; ++
I) {
644 ProjMap::iterator F = PM.find(PC);
652 NodeVect::iterator NewE =
remove_if(Nodes, in_set(Erase));
653 Nodes.resize(std::distance(Nodes.begin(), NewE));
655 DEBUG(
dbgs() <<
"Gep nodes after post-commoning cleanup:\n" << Nodes);
658 template <
typename T>
661 dbgs() <<
"NCD of {";
662 for (
typename T::iterator I = Blocks.begin(),
E = Blocks.end();
673 typename T::iterator I = Blocks.begin(),
E = Blocks.end();
687 template <
typename T>
691 typename T::iterator I = Blocks.begin(),
E = Blocks.end();
693 while (I !=
E && !*I)
713 template <
typename T>
716 typedef typename T::iterator iterator;
717 for (iterator I = Values.begin(),
E = Values.end(); I !=
E; ++
I) {
726 if (!isa<Instruction>(V))
732 if (std::distance(FirstUse, BEnd) < std::distance(It, BEnd))
742 BasicBlock *HexagonCommonGEP::recalculatePlacement(GepNode *Node,
743 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
744 DEBUG(
dbgs() <<
"Loc for node:" << Node <<
'\n');
755 if (Node->Flags & GepNode::Used) {
758 NodeToUsesMap::iterator UF = Uses.find(Node);
759 assert(UF != Uses.end() &&
"Used node with no use information");
760 UseSet &Us = UF->second;
761 for (UseSet::iterator I = Us.begin(),
E = Us.end(); I !=
E; ++
I) {
763 User *R = U->getUser();
764 if (!isa<Instruction>(R))
767 ? cast<PHINode>(R)->getIncomingBlock(*U)
773 NodeChildrenMap::iterator CF = NCM.find(Node);
774 if (CF != NCM.end()) {
775 NodeVect &Cs = CF->second;
776 for (NodeVect::iterator I = Cs.begin(),
E = Cs.end(); I !=
E; ++
I) {
778 NodeToValueMap::iterator LF = Loc.find(CN);
784 Bs.push_back(LF->second);
793 if (IdxI && !DT->dominates(IdxI->
getParent(), DomB))
809 BasicBlock *HexagonCommonGEP::recalculatePlacementRec(GepNode *Node,
810 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
811 DEBUG(
dbgs() <<
"LocRec begin for node:" << Node <<
'\n');
814 NodeChildrenMap::iterator CF = NCM.find(Node);
815 if (CF != NCM.end()) {
816 NodeVect &Cs = CF->second;
817 for (NodeVect::iterator I = Cs.begin(),
E = Cs.end(); I !=
E; ++
I)
818 recalculatePlacementRec(*I, NCM, Loc);
820 BasicBlock *LB = recalculatePlacement(Node, NCM, Loc);
821 DEBUG(
dbgs() <<
"LocRec end for node:" << Node <<
'\n');
825 bool HexagonCommonGEP::isInvariantIn(
Value *Val,
Loop *
L) {
826 if (isa<Constant>(Val) || isa<Argument>(Val))
832 return DT->properlyDominates(DefB, HdrB);
835 bool HexagonCommonGEP::isInvariantIn(GepNode *Node,
Loop *L) {
836 if (Node->Flags & GepNode::Root)
837 if (!isInvariantIn(Node->BaseVal, L))
839 return isInvariantIn(Node->Idx, L);
846 if (PDT->dominates(B, HB))
848 if (LB && DT->dominates(B, LB))
861 return DN->
getIDom()->getBlock();
864 BasicBlock *HexagonCommonGEP::adjustForInvariance(GepNode *Node,
865 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
870 if (Node->Flags & GepNode::Root) {
871 if (
Instruction *PIn = dyn_cast<Instruction>(Node->BaseVal))
872 Bs.push_back(PIn->getParent());
874 Bs.push_back(Loc[Node->Parent]);
876 if (
Instruction *IIn = dyn_cast<Instruction>(Node->Idx))
877 Bs.push_back(IIn->getParent());
888 BasicBlock *LocB = cast_or_null<BasicBlock>(Loc[Node]);
890 Loop *Lp = LI->getLoopFor(LocB);
892 if (!isInvariantIn(Node, Lp) || !isInMainPath(LocB, Lp))
895 if (!NewLoc || !DT->dominates(TopB, NewLoc))
904 NodeChildrenMap::iterator CF = NCM.find(Node);
905 if (CF != NCM.end()) {
906 NodeVect &Cs = CF->second;
907 for (NodeVect::iterator I = Cs.begin(),
E = Cs.end(); I !=
E; ++
I)
908 adjustForInvariance(*I, NCM, Loc);
915 struct LocationAsBlock {
916 LocationAsBlock(
const NodeToValueMap &L) : Map(L) {}
918 const NodeToValueMap ⤅
924 for (NodeToValueMap::const_iterator I = Loc.Map.begin(),
E = Loc.Map.end();
926 OS << I->first <<
" -> ";
928 OS << B->
getName() <<
'(' << B <<
')';
934 inline bool is_constant(GepNode *N) {
935 return isa<ConstantInt>(N->Idx);
940 void HexagonCommonGEP::separateChainForNode(GepNode *Node,
Use *U,
941 NodeToValueMap &Loc) {
942 User *R = U->getUser();
943 DEBUG(
dbgs() <<
"Separating chain for node (" << Node <<
") user: "
948 GepNode *C =
nullptr, *NewNode =
nullptr;
949 while (is_constant(N) && !(N->Flags & GepNode::Root)) {
951 GepNode *NewN =
new (*Mem) GepNode(N);
952 Nodes.push_back(NewN);
957 NewN->Flags &= ~GepNode::Used;
967 NodeToUsesMap::iterator UF = Uses.find(Node);
969 UseSet &Us = UF->second;
971 for (UseSet::iterator I = Us.begin(); I != Us.end(); ) {
972 User *S = (*I)->getUser();
973 UseSet::iterator Nx = std::next(I);
981 Node->Flags &= ~GepNode::Used;
986 NewNode->Flags |= GepNode::Used;
987 DEBUG(
dbgs() <<
"new node: " << NewNode <<
" " << *NewNode <<
'\n');
989 Uses[NewNode] = NewUs;
992 void HexagonCommonGEP::separateConstantChains(GepNode *Node,
993 NodeChildrenMap &NCM, NodeToValueMap &Loc) {
998 DEBUG(
dbgs() <<
"Separating constant chains for node: " << Node <<
'\n');
1002 for (NodeSet::iterator I = Ns.begin(),
E = Ns.end(); I !=
E; ++
I) {
1004 if (!(N->Flags & GepNode::Used))
1006 NodeToUsesMap::iterator UF = Uses.find(N);
1007 assert(UF != Uses.end());
1008 UseSet &Us = UF->second;
1011 for (UseSet::iterator J = Us.begin(), F = Us.end(); J !=
F; ++J) {
1013 User *R = U->getUser();
1017 if (
LoadInst *Ld = dyn_cast<LoadInst>(R)) {
1019 if (&Ld->getOperandUse(PtrX) == U)
1021 }
else if (
StoreInst *St = dyn_cast<StoreInst>(R)) {
1023 if (&St->getOperandUse(PtrX) == U)
1032 FNs.insert(std::make_pair(N, LSs));
1035 DEBUG(
dbgs() <<
"Nodes with foldable users:\n" << FNs);
1037 for (NodeToUsesMap::iterator I = FNs.begin(),
E = FNs.end(); I !=
E; ++
I) {
1038 GepNode *N = I->first;
1039 UseSet &Us = I->second;
1040 for (UseSet::iterator J = Us.begin(), F = Us.end(); J !=
F; ++J)
1041 separateChainForNode(N, *J, Loc);
1045 void HexagonCommonGEP::computeNodePlacement(NodeToValueMap &Loc) {
1048 NodeChildrenMap NCM;
1054 for (NodeVect::iterator I = Roots.begin(),
E = Roots.end(); I !=
E; ++
I)
1055 recalculatePlacementRec(*I, NCM, Loc);
1057 DEBUG(
dbgs() <<
"Initial node placement:\n" << LocationAsBlock(Loc));
1060 for (NodeVect::iterator I = Roots.begin(),
E = Roots.end(); I !=
E; ++
I)
1061 adjustForInvariance(*I, NCM, Loc);
1063 DEBUG(
dbgs() <<
"Node placement after adjustment for invariance:\n"
1064 << LocationAsBlock(Loc));
1067 for (NodeVect::iterator I = Roots.begin(),
E = Roots.end(); I !=
E; ++
I)
1068 separateConstantChains(*I, NCM, Loc);
1070 DEBUG(
dbgs() <<
"Node use information:\n" << Uses);
1076 DEBUG(
dbgs() <<
"Final node placement:\n" << LocationAsBlock(Loc));
1082 <<
" for nodes:\n" << NA);
1083 unsigned Num = NA.size();
1084 GepNode *
RN = NA[0];
1085 assert((RN->Flags & GepNode::Root) &&
"Creating GEP for non-root");
1087 Value *NewInst =
nullptr;
1088 Value *Input = RN->BaseVal;
1096 if (!NA[nax]->PTy->isPointerTy()) {
1103 while (++nax <= Num) {
1104 GepNode *N = NA[nax-1];
1105 IdxList[IdxC++] = N->Idx;
1110 if (NextTy != NA[nax]->PTy)
1118 DEBUG(
dbgs() <<
"new GEP: " << *NewInst <<
'\n');
1120 }
while (nax <= Num);
1126 void HexagonCommonGEP::getAllUsersForNode(GepNode *Node, ValueVect &Values,
1127 NodeChildrenMap &NCM) {
1129 Work.push_back(Node);
1131 while (!Work.empty()) {
1132 NodeVect::iterator First = Work.begin();
1133 GepNode *N = *First;
1135 if (N->Flags & GepNode::Used) {
1136 NodeToUsesMap::iterator UF = Uses.find(N);
1137 assert(UF != Uses.end() &&
"No use information for used node");
1138 UseSet &Us = UF->second;
1139 for (UseSet::iterator I = Us.begin(),
E = Us.end(); I !=
E; ++
I)
1140 Values.push_back((*I)->getUser());
1142 NodeChildrenMap::iterator CF = NCM.find(N);
1143 if (CF != NCM.end()) {
1144 NodeVect &Cs = CF->second;
1145 Work.insert(Work.end(), Cs.begin(), Cs.end());
1150 void HexagonCommonGEP::materialize(NodeToValueMap &Loc) {
1151 DEBUG(
dbgs() <<
"Nodes before materialization:\n" << Nodes <<
'\n');
1152 NodeChildrenMap NCM;
1158 while (!Roots.empty()) {
1159 NodeVect::iterator First = Roots.begin();
1160 GepNode *Root = *First, *
Last = *First;
1169 bool LastUsed =
false;
1170 unsigned LastCN = 0;
1173 Value *LocV = Loc[Last];
1179 LastUsed = (Last->Flags & GepNode::Used);
1182 NodeChildrenMap::iterator CF = NCM.find(Last);
1183 LastCN = (CF != NCM.end()) ? CF->second.size() : 0;
1186 GepNode *Child = CF->second.front();
1187 BasicBlock *ChildB = cast_or_null<BasicBlock>(Loc[Child]);
1188 if (ChildB !=
nullptr && LastB != ChildB)
1194 if (LastUsed || LastCN > 0) {
1196 getAllUsersForNode(Root, Urs, NCM);
1198 if (FirstUse != LastB->
end())
1199 InsertAt = FirstUse;
1203 Value *NewInst = fabricateGEP(NA, InsertAt, LastB);
1208 NodeVect &Cs = NCM[Last];
1209 for (NodeVect::iterator I = Cs.begin(),
E = Cs.end(); I !=
E; ++
I) {
1211 CN->Flags &= ~GepNode::Internal;
1212 CN->Flags |= GepNode::Root;
1213 CN->BaseVal = NewInst;
1214 Roots.push_back(CN);
1221 NodeToUsesMap::iterator UF = Uses.find(Last);
1222 assert(UF != Uses.end() &&
"No use information found");
1223 UseSet &Us = UF->second;
1224 for (UseSet::iterator I = Us.begin(),
E = Us.end(); I !=
E; ++
I) {
1232 void HexagonCommonGEP::removeDeadCode() {
1234 BO.push_back(&Fn->front());
1236 for (
unsigned i = 0;
i < BO.size(); ++
i) {
1240 typedef GTN::ChildIteratorType Iter;
1241 for (Iter I = GTN::child_begin(N),
E = GTN::child_end(N); I !=
E; ++
I)
1242 BO.push_back((*I)->getBlock());
1245 for (
unsigned i = BO.size();
i > 0; --
i) {
1250 for (reverse_iterator I = IL.rbegin(),
E = IL.rend(); I !=
E; ++
I)
1252 for (ValueVect::iterator I = Ins.begin(),
E = Ins.end(); I !=
E; ++
I) {
1260 bool HexagonCommonGEP::runOnFunction(
Function &F) {
1261 if (skipFunction(F))
1267 if (isa<InvokeInst>(I) || isa<LandingPadInst>(
I))
1271 DT = &getAnalysis<DominatorTreeWrapperPass>().getDomTree();
1272 PDT = &getAnalysis<PostDominatorTreeWrapperPass>().getPostDomTree();
1273 LI = &getAnalysis<LoopInfoWrapperPass>().getLoopInfo();
1287 computeNodePlacement(Loc);
1291 #ifdef EXPENSIVE_CHECKS
1301 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.
static PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function. ...
auto remove_if(R &&Range, UnaryPredicate P) -> decltype(std::begin(Range))
Provide wrappers to std::remove_if which take ranges instead of having to pass begin/end explicitly...
static BasicBlock::iterator first_use_of_in_block(T &Values, BasicBlock *B)
static void nodes_for_root(GepNode *Root, NodeChildrenMap &NCM, NodeSet &Nodes)
virtual void getAnalysisUsage(AnalysisUsage &) const
getAnalysisUsage - This function should be overriden by passes that need analysis information to do t...
static bool is_empty(const BasicBlock *B)
static cl::opt< bool > OptEnableInv("commgep-inv", cl::init(true), cl::Hidden, cl::ZeroOrMore)
const_iterator begin(StringRef path)
Get begin iterator over path.
LoopT * getParentLoop() const
An instruction for reading from memory.
This defines the Use class.
BlockT * getHeader() const
This file defines the MallocAllocator and BumpPtrAllocator interfaces.
static void invert_find_roots(const NodeVect &Nodes, NodeChildrenMap &NCM, NodeVect &Roots)
StringRef getName() const
Return a constant reference to the value's name.
BlockT * getLoopLatch() const
If there is a single latch block for this loop, return it.
iterator begin()
Instruction iterator methods.
FunctionPass * createHexagonCommonGEP()
DomTreeNodeBase< NodeT > * getIDom() const
AnalysisUsage & addRequired()
#define INITIALIZE_PASS_DEPENDENCY(depName)
struct fuzzer::@269 Flags
const APInt & getValue() const
Return the constant as an APInt value reference.
Class to represent struct types.
A Use represents the edge between a Value definition and its users.
bool Eq(const uint8_t *Data, size_t Size, const char *Str)
bool isLiteral() const
Return true if this type is uniqued by structural equivalence, false if it is a struct definition...
user_iterator_impl< User > user_iterator
Base class for the actual dominator tree node.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory)...
static GCRegistry::Add< OcamlGC > B("ocaml","ocaml 3.10-compatible GC")
An instruction for storing to memory.
Concrete subclass of DominatorTreeBase that is used to compute a normal dominator tree...
Type * getScalarType() const LLVM_READONLY
If this is a vector type, return the element type, otherwise return 'this'.
static GCRegistry::Add< CoreCLRGC > E("coreclr","CoreCLR-compatible GC")
static cl::opt< bool > OptEnableConst("commgep-const", cl::init(true), cl::Hidden, cl::ZeroOrMore)
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 ...
initializer< Ty > init(const Ty &Val)
Type * next_type(Type *Ty, Value *Idx)
BlockT * getLoopPreheader() const
If there is a preheader for this loop, return it.
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.
int64_t getSExtValue() const
Get sign extended value.
This file contains the declarations for the subclasses of Constant, which represent the different fla...
static unsigned node_hash(GepNode *N)
Represent the analysis usage information of a pass.
Greedy Register Allocator
const InstListType & getInstList() const
Return the underlying instruction list container.
#define LLVM_ATTRIBUTE_UNUSED
INITIALIZE_PASS_END(RegBankSelect, DEBUG_TYPE,"Assign register bank of generic virtual registers", false, false) RegBankSelect
FunctionPass class - This class is used to implement most global optimizations.
NodeT * findNearestCommonDominator(NodeT *A, NodeT *B)
findNearestCommonDominator - Find nearest common dominator basic block for basic block A and B...
self_iterator getIterator()
static BasicBlock * preheader(DominatorTree *DT, Loop *L)
static cl::opt< bool > OptSpeculate("commgep-speculate", cl::init(true), cl::Hidden, cl::ZeroOrMore)
bool isPointerTy() const
True if this is an instance of PointerType.
static GetElementPtrInst * Create(Type *PointeeType, Value *Ptr, ArrayRef< Value * > IdxList, const Twine &NameStr="", Instruction *InsertBefore=nullptr)
bool dominates(const Instruction *Def, const Use &U) const
Return true if Def dominates a use in User.
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 &)
Type * getType() const
All values are typed, get the type of this value.
StringRef getStructName() const
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)
static GCRegistry::Add< ShadowStackGC > C("shadow-stack","Very portable GC for uncooperative code generators")
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
static NodePair node_pair(GepNode *N1, GepNode *N2)
std::set< NodeId > NodeSet
PostDominatorTree Class - Concrete subclass of DominatorTree that is used to compute the post-dominat...
static void clear(coro::Shape &Shape)
bool isStructTy() const
True if this is an instance of StructType.
static bool node_eq(GepNode *N1, GepNode *N2, NodePairSet &Eq, NodePairSet &Ne)
static IntegerType * getInt32Ty(LLVMContext &C)
unsigned ComputeHash() const
ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used to lookup the node in the F...
Represents a single loop in the control flow graph.
TerminatorInst * getTerminator()
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
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.
DomTreeNodeBase< NodeT > * getNode(NodeT *BB) const
getNode - return the (Post)DominatorTree node for the specified basic block.
static GCRegistry::Add< ErlangGC > A("erlang","erlang-compatible garbage collector")
static BasicBlock * nearest_common_dominatee(DominatorTree *DT, T &Blocks)
base_list_type::reverse_iterator reverse_iterator
const BasicBlock * getParent() const
InstListType::iterator iterator
Instruction iterators...
void dump_node_container(raw_ostream &OS, const NodeContainer &S)
static const NodeSet * node_class(GepNode *N, NodeSymRel &Rel)