CFLGraph.h 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667
  1. //===- CFLGraph.h - Abstract stratified sets implementation. -----*- C++-*-===//
  2. //
  3. // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4. // See https://llvm.org/LICENSE.txt for license information.
  5. // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6. //
  7. //===----------------------------------------------------------------------===//
  8. //
  9. /// \file
  10. /// This file defines CFLGraph, an auxiliary data structure used by CFL-based
  11. /// alias analysis.
  12. //
  13. //===----------------------------------------------------------------------===//
  14. #ifndef LLVM_LIB_ANALYSIS_CFLGRAPH_H
  15. #define LLVM_LIB_ANALYSIS_CFLGRAPH_H
  16. #include "AliasAnalysisSummary.h"
  17. #include "llvm/ADT/APInt.h"
  18. #include "llvm/ADT/DenseMap.h"
  19. #include "llvm/ADT/SmallVector.h"
  20. #include "llvm/ADT/iterator_range.h"
  21. #include "llvm/Analysis/MemoryBuiltins.h"
  22. #include "llvm/Analysis/TargetLibraryInfo.h"
  23. #include "llvm/IR/Argument.h"
  24. #include "llvm/IR/BasicBlock.h"
  25. #include "llvm/IR/Constants.h"
  26. #include "llvm/IR/DataLayout.h"
  27. #include "llvm/IR/Function.h"
  28. #include "llvm/IR/GlobalValue.h"
  29. #include "llvm/IR/InstVisitor.h"
  30. #include "llvm/IR/InstrTypes.h"
  31. #include "llvm/IR/Instruction.h"
  32. #include "llvm/IR/Instructions.h"
  33. #include "llvm/IR/Operator.h"
  34. #include "llvm/IR/Type.h"
  35. #include "llvm/IR/Value.h"
  36. #include "llvm/Support/Casting.h"
  37. #include "llvm/Support/ErrorHandling.h"
  38. #include <cassert>
  39. #include <cstdint>
  40. #include <vector>
  41. namespace llvm {
  42. namespace cflaa {
  43. /// The Program Expression Graph (PEG) of CFL analysis
  44. /// CFLGraph is auxiliary data structure used by CFL-based alias analysis to
  45. /// describe flow-insensitive pointer-related behaviors. Given an LLVM function,
  46. /// the main purpose of this graph is to abstract away unrelated facts and
  47. /// translate the rest into a form that can be easily digested by CFL analyses.
  48. /// Each Node in the graph is an InstantiatedValue, and each edge represent a
  49. /// pointer assignment between InstantiatedValue. Pointer
  50. /// references/dereferences are not explicitly stored in the graph: we
  51. /// implicitly assume that for each node (X, I) it has a dereference edge to (X,
  52. /// I+1) and a reference edge to (X, I-1).
  53. class CFLGraph {
  54. public:
  55. using Node = InstantiatedValue;
  56. struct Edge {
  57. Node Other;
  58. int64_t Offset;
  59. };
  60. using EdgeList = std::vector<Edge>;
  61. struct NodeInfo {
  62. EdgeList Edges, ReverseEdges;
  63. AliasAttrs Attr;
  64. };
  65. class ValueInfo {
  66. std::vector<NodeInfo> Levels;
  67. public:
  68. bool addNodeToLevel(unsigned Level) {
  69. auto NumLevels = Levels.size();
  70. if (NumLevels > Level)
  71. return false;
  72. Levels.resize(Level + 1);
  73. return true;
  74. }
  75. NodeInfo &getNodeInfoAtLevel(unsigned Level) {
  76. assert(Level < Levels.size());
  77. return Levels[Level];
  78. }
  79. const NodeInfo &getNodeInfoAtLevel(unsigned Level) const {
  80. assert(Level < Levels.size());
  81. return Levels[Level];
  82. }
  83. unsigned getNumLevels() const { return Levels.size(); }
  84. };
  85. private:
  86. using ValueMap = DenseMap<Value *, ValueInfo>;
  87. ValueMap ValueImpls;
  88. NodeInfo *getNode(Node N) {
  89. auto Itr = ValueImpls.find(N.Val);
  90. if (Itr == ValueImpls.end() || Itr->second.getNumLevels() <= N.DerefLevel)
  91. return nullptr;
  92. return &Itr->second.getNodeInfoAtLevel(N.DerefLevel);
  93. }
  94. public:
  95. using const_value_iterator = ValueMap::const_iterator;
  96. bool addNode(Node N, AliasAttrs Attr = AliasAttrs()) {
  97. assert(N.Val != nullptr);
  98. auto &ValInfo = ValueImpls[N.Val];
  99. auto Changed = ValInfo.addNodeToLevel(N.DerefLevel);
  100. ValInfo.getNodeInfoAtLevel(N.DerefLevel).Attr |= Attr;
  101. return Changed;
  102. }
  103. void addAttr(Node N, AliasAttrs Attr) {
  104. auto *Info = getNode(N);
  105. assert(Info != nullptr);
  106. Info->Attr |= Attr;
  107. }
  108. void addEdge(Node From, Node To, int64_t Offset = 0) {
  109. auto *FromInfo = getNode(From);
  110. assert(FromInfo != nullptr);
  111. auto *ToInfo = getNode(To);
  112. assert(ToInfo != nullptr);
  113. FromInfo->Edges.push_back(Edge{To, Offset});
  114. ToInfo->ReverseEdges.push_back(Edge{From, Offset});
  115. }
  116. const NodeInfo *getNode(Node N) const {
  117. auto Itr = ValueImpls.find(N.Val);
  118. if (Itr == ValueImpls.end() || Itr->second.getNumLevels() <= N.DerefLevel)
  119. return nullptr;
  120. return &Itr->second.getNodeInfoAtLevel(N.DerefLevel);
  121. }
  122. AliasAttrs attrFor(Node N) const {
  123. auto *Info = getNode(N);
  124. assert(Info != nullptr);
  125. return Info->Attr;
  126. }
  127. iterator_range<const_value_iterator> value_mappings() const {
  128. return make_range<const_value_iterator>(ValueImpls.begin(),
  129. ValueImpls.end());
  130. }
  131. };
  132. /// A builder class used to create CFLGraph instance from a given function
  133. /// The CFL-AA that uses this builder must provide its own type as a template
  134. /// argument. This is necessary for interprocedural processing: CFLGraphBuilder
  135. /// needs a way of obtaining the summary of other functions when callinsts are
  136. /// encountered.
  137. /// As a result, we expect the said CFL-AA to expose a getAliasSummary() public
  138. /// member function that takes a Function& and returns the corresponding summary
  139. /// as a const AliasSummary*.
  140. template <typename CFLAA> class CFLGraphBuilder {
  141. // Input of the builder
  142. CFLAA &Analysis;
  143. const TargetLibraryInfo &TLI;
  144. // Output of the builder
  145. CFLGraph Graph;
  146. SmallVector<Value *, 4> ReturnedValues;
  147. // Helper class
  148. /// Gets the edges our graph should have, based on an Instruction*
  149. class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
  150. CFLAA &AA;
  151. const DataLayout &DL;
  152. const TargetLibraryInfo &TLI;
  153. CFLGraph &Graph;
  154. SmallVectorImpl<Value *> &ReturnValues;
  155. static bool hasUsefulEdges(ConstantExpr *CE) {
  156. // ConstantExpr doesn't have terminators, invokes, or fences, so only
  157. // needs to check for compares.
  158. return CE->getOpcode() != Instruction::ICmp &&
  159. CE->getOpcode() != Instruction::FCmp;
  160. }
  161. // Returns possible functions called by CS into the given SmallVectorImpl.
  162. // Returns true if targets found, false otherwise.
  163. static bool getPossibleTargets(CallBase &Call,
  164. SmallVectorImpl<Function *> &Output) {
  165. if (auto *Fn = Call.getCalledFunction()) {
  166. Output.push_back(Fn);
  167. return true;
  168. }
  169. // TODO: If the call is indirect, we might be able to enumerate all
  170. // potential targets of the call and return them, rather than just
  171. // failing.
  172. return false;
  173. }
  174. void addNode(Value *Val, AliasAttrs Attr = AliasAttrs()) {
  175. assert(Val != nullptr && Val->getType()->isPointerTy());
  176. if (auto GVal = dyn_cast<GlobalValue>(Val)) {
  177. if (Graph.addNode(InstantiatedValue{GVal, 0},
  178. getGlobalOrArgAttrFromValue(*GVal)))
  179. Graph.addNode(InstantiatedValue{GVal, 1}, getAttrUnknown());
  180. } else if (auto CExpr = dyn_cast<ConstantExpr>(Val)) {
  181. if (hasUsefulEdges(CExpr)) {
  182. if (Graph.addNode(InstantiatedValue{CExpr, 0}))
  183. visitConstantExpr(CExpr);
  184. }
  185. } else
  186. Graph.addNode(InstantiatedValue{Val, 0}, Attr);
  187. }
  188. void addAssignEdge(Value *From, Value *To, int64_t Offset = 0) {
  189. assert(From != nullptr && To != nullptr);
  190. if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
  191. return;
  192. addNode(From);
  193. if (To != From) {
  194. addNode(To);
  195. Graph.addEdge(InstantiatedValue{From, 0}, InstantiatedValue{To, 0},
  196. Offset);
  197. }
  198. }
  199. void addDerefEdge(Value *From, Value *To, bool IsRead) {
  200. assert(From != nullptr && To != nullptr);
  201. // FIXME: This is subtly broken, due to how we model some instructions
  202. // (e.g. extractvalue, extractelement) as loads. Since those take
  203. // non-pointer operands, we'll entirely skip adding edges for those.
  204. //
  205. // addAssignEdge seems to have a similar issue with insertvalue, etc.
  206. if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
  207. return;
  208. addNode(From);
  209. addNode(To);
  210. if (IsRead) {
  211. Graph.addNode(InstantiatedValue{From, 1});
  212. Graph.addEdge(InstantiatedValue{From, 1}, InstantiatedValue{To, 0});
  213. } else {
  214. Graph.addNode(InstantiatedValue{To, 1});
  215. Graph.addEdge(InstantiatedValue{From, 0}, InstantiatedValue{To, 1});
  216. }
  217. }
  218. void addLoadEdge(Value *From, Value *To) { addDerefEdge(From, To, true); }
  219. void addStoreEdge(Value *From, Value *To) { addDerefEdge(From, To, false); }
  220. public:
  221. GetEdgesVisitor(CFLGraphBuilder &Builder, const DataLayout &DL)
  222. : AA(Builder.Analysis), DL(DL), TLI(Builder.TLI), Graph(Builder.Graph),
  223. ReturnValues(Builder.ReturnedValues) {}
  224. void visitInstruction(Instruction &) {
  225. llvm_unreachable("Unsupported instruction encountered");
  226. }
  227. void visitReturnInst(ReturnInst &Inst) {
  228. if (auto RetVal = Inst.getReturnValue()) {
  229. if (RetVal->getType()->isPointerTy()) {
  230. addNode(RetVal);
  231. ReturnValues.push_back(RetVal);
  232. }
  233. }
  234. }
  235. void visitPtrToIntInst(PtrToIntInst &Inst) {
  236. auto *Ptr = Inst.getOperand(0);
  237. addNode(Ptr, getAttrEscaped());
  238. }
  239. void visitIntToPtrInst(IntToPtrInst &Inst) {
  240. auto *Ptr = &Inst;
  241. addNode(Ptr, getAttrUnknown());
  242. }
  243. void visitCastInst(CastInst &Inst) {
  244. auto *Src = Inst.getOperand(0);
  245. addAssignEdge(Src, &Inst);
  246. }
  247. void visitFreezeInst(FreezeInst &Inst) {
  248. // Accessing freeze(ptr) is equivalent to accessing ptr.
  249. // The former raises UB iff latter raises UB.
  250. auto *Src = Inst.getOperand(0);
  251. addAssignEdge(Src, &Inst);
  252. }
  253. void visitBinaryOperator(BinaryOperator &Inst) {
  254. auto *Op1 = Inst.getOperand(0);
  255. auto *Op2 = Inst.getOperand(1);
  256. addAssignEdge(Op1, &Inst);
  257. addAssignEdge(Op2, &Inst);
  258. }
  259. void visitUnaryOperator(UnaryOperator &Inst) {
  260. auto *Src = Inst.getOperand(0);
  261. addAssignEdge(Src, &Inst);
  262. }
  263. void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
  264. auto *Ptr = Inst.getPointerOperand();
  265. auto *Val = Inst.getNewValOperand();
  266. addStoreEdge(Val, Ptr);
  267. }
  268. void visitAtomicRMWInst(AtomicRMWInst &Inst) {
  269. auto *Ptr = Inst.getPointerOperand();
  270. auto *Val = Inst.getValOperand();
  271. addStoreEdge(Val, Ptr);
  272. }
  273. void visitPHINode(PHINode &Inst) {
  274. for (Value *Val : Inst.incoming_values())
  275. addAssignEdge(Val, &Inst);
  276. }
  277. void visitGEP(GEPOperator &GEPOp) {
  278. uint64_t Offset = UnknownOffset;
  279. APInt APOffset(DL.getPointerSizeInBits(GEPOp.getPointerAddressSpace()),
  280. 0);
  281. if (GEPOp.accumulateConstantOffset(DL, APOffset))
  282. Offset = APOffset.getSExtValue();
  283. auto *Op = GEPOp.getPointerOperand();
  284. addAssignEdge(Op, &GEPOp, Offset);
  285. }
  286. void visitGetElementPtrInst(GetElementPtrInst &Inst) {
  287. auto *GEPOp = cast<GEPOperator>(&Inst);
  288. visitGEP(*GEPOp);
  289. }
  290. void visitSelectInst(SelectInst &Inst) {
  291. // Condition is not processed here (The actual statement producing
  292. // the condition result is processed elsewhere). For select, the
  293. // condition is evaluated, but not loaded, stored, or assigned
  294. // simply as a result of being the condition of a select.
  295. auto *TrueVal = Inst.getTrueValue();
  296. auto *FalseVal = Inst.getFalseValue();
  297. addAssignEdge(TrueVal, &Inst);
  298. addAssignEdge(FalseVal, &Inst);
  299. }
  300. void visitAllocaInst(AllocaInst &Inst) { addNode(&Inst); }
  301. void visitLoadInst(LoadInst &Inst) {
  302. auto *Ptr = Inst.getPointerOperand();
  303. auto *Val = &Inst;
  304. addLoadEdge(Ptr, Val);
  305. }
  306. void visitStoreInst(StoreInst &Inst) {
  307. auto *Ptr = Inst.getPointerOperand();
  308. auto *Val = Inst.getValueOperand();
  309. addStoreEdge(Val, Ptr);
  310. }
  311. void visitVAArgInst(VAArgInst &Inst) {
  312. // We can't fully model va_arg here. For *Ptr = Inst.getOperand(0), it
  313. // does
  314. // two things:
  315. // 1. Loads a value from *((T*)*Ptr).
  316. // 2. Increments (stores to) *Ptr by some target-specific amount.
  317. // For now, we'll handle this like a landingpad instruction (by placing
  318. // the
  319. // result in its own group, and having that group alias externals).
  320. if (Inst.getType()->isPointerTy())
  321. addNode(&Inst, getAttrUnknown());
  322. }
  323. static bool isFunctionExternal(Function *Fn) {
  324. return !Fn->hasExactDefinition();
  325. }
  326. bool tryInterproceduralAnalysis(CallBase &Call,
  327. const SmallVectorImpl<Function *> &Fns) {
  328. assert(Fns.size() > 0);
  329. if (Call.arg_size() > MaxSupportedArgsInSummary)
  330. return false;
  331. // Exit early if we'll fail anyway
  332. for (auto *Fn : Fns) {
  333. if (isFunctionExternal(Fn) || Fn->isVarArg())
  334. return false;
  335. // Fail if the caller does not provide enough arguments
  336. assert(Fn->arg_size() <= Call.arg_size());
  337. if (!AA.getAliasSummary(*Fn))
  338. return false;
  339. }
  340. for (auto *Fn : Fns) {
  341. auto Summary = AA.getAliasSummary(*Fn);
  342. assert(Summary != nullptr);
  343. auto &RetParamRelations = Summary->RetParamRelations;
  344. for (auto &Relation : RetParamRelations) {
  345. auto IRelation = instantiateExternalRelation(Relation, Call);
  346. if (IRelation.hasValue()) {
  347. Graph.addNode(IRelation->From);
  348. Graph.addNode(IRelation->To);
  349. Graph.addEdge(IRelation->From, IRelation->To);
  350. }
  351. }
  352. auto &RetParamAttributes = Summary->RetParamAttributes;
  353. for (auto &Attribute : RetParamAttributes) {
  354. auto IAttr = instantiateExternalAttribute(Attribute, Call);
  355. if (IAttr.hasValue())
  356. Graph.addNode(IAttr->IValue, IAttr->Attr);
  357. }
  358. }
  359. return true;
  360. }
  361. void visitCallBase(CallBase &Call) {
  362. // Make sure all arguments and return value are added to the graph first
  363. for (Value *V : Call.args())
  364. if (V->getType()->isPointerTy())
  365. addNode(V);
  366. if (Call.getType()->isPointerTy())
  367. addNode(&Call);
  368. // Check if Inst is a call to a library function that
  369. // allocates/deallocates on the heap. Those kinds of functions do not
  370. // introduce any aliases.
  371. // TODO: address other common library functions such as realloc(),
  372. // strdup(), etc.
  373. if (isMallocOrCallocLikeFn(&Call, &TLI) || isFreeCall(&Call, &TLI))
  374. return;
  375. // TODO: Add support for noalias args/all the other fun function
  376. // attributes that we can tack on.
  377. SmallVector<Function *, 4> Targets;
  378. if (getPossibleTargets(Call, Targets))
  379. if (tryInterproceduralAnalysis(Call, Targets))
  380. return;
  381. // Because the function is opaque, we need to note that anything
  382. // could have happened to the arguments (unless the function is marked
  383. // readonly or readnone), and that the result could alias just about
  384. // anything, too (unless the result is marked noalias).
  385. if (!Call.onlyReadsMemory())
  386. for (Value *V : Call.args()) {
  387. if (V->getType()->isPointerTy()) {
  388. // The argument itself escapes.
  389. Graph.addAttr(InstantiatedValue{V, 0}, getAttrEscaped());
  390. // The fate of argument memory is unknown. Note that since
  391. // AliasAttrs is transitive with respect to dereference, we only
  392. // need to specify it for the first-level memory.
  393. Graph.addNode(InstantiatedValue{V, 1}, getAttrUnknown());
  394. }
  395. }
  396. if (Call.getType()->isPointerTy()) {
  397. auto *Fn = Call.getCalledFunction();
  398. if (Fn == nullptr || !Fn->returnDoesNotAlias())
  399. // No need to call addNode() since we've added Inst at the
  400. // beginning of this function and we know it is not a global.
  401. Graph.addAttr(InstantiatedValue{&Call, 0}, getAttrUnknown());
  402. }
  403. }
  404. /// Because vectors/aggregates are immutable and unaddressable, there's
  405. /// nothing we can do to coax a value out of them, other than calling
  406. /// Extract{Element,Value}. We can effectively treat them as pointers to
  407. /// arbitrary memory locations we can store in and load from.
  408. void visitExtractElementInst(ExtractElementInst &Inst) {
  409. auto *Ptr = Inst.getVectorOperand();
  410. auto *Val = &Inst;
  411. addLoadEdge(Ptr, Val);
  412. }
  413. void visitInsertElementInst(InsertElementInst &Inst) {
  414. auto *Vec = Inst.getOperand(0);
  415. auto *Val = Inst.getOperand(1);
  416. addAssignEdge(Vec, &Inst);
  417. addStoreEdge(Val, &Inst);
  418. }
  419. void visitLandingPadInst(LandingPadInst &Inst) {
  420. // Exceptions come from "nowhere", from our analysis' perspective.
  421. // So we place the instruction its own group, noting that said group may
  422. // alias externals
  423. if (Inst.getType()->isPointerTy())
  424. addNode(&Inst, getAttrUnknown());
  425. }
  426. void visitInsertValueInst(InsertValueInst &Inst) {
  427. auto *Agg = Inst.getOperand(0);
  428. auto *Val = Inst.getOperand(1);
  429. addAssignEdge(Agg, &Inst);
  430. addStoreEdge(Val, &Inst);
  431. }
  432. void visitExtractValueInst(ExtractValueInst &Inst) {
  433. auto *Ptr = Inst.getAggregateOperand();
  434. addLoadEdge(Ptr, &Inst);
  435. }
  436. void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
  437. auto *From1 = Inst.getOperand(0);
  438. auto *From2 = Inst.getOperand(1);
  439. addAssignEdge(From1, &Inst);
  440. addAssignEdge(From2, &Inst);
  441. }
  442. void visitConstantExpr(ConstantExpr *CE) {
  443. switch (CE->getOpcode()) {
  444. case Instruction::GetElementPtr: {
  445. auto GEPOp = cast<GEPOperator>(CE);
  446. visitGEP(*GEPOp);
  447. break;
  448. }
  449. case Instruction::PtrToInt: {
  450. addNode(CE->getOperand(0), getAttrEscaped());
  451. break;
  452. }
  453. case Instruction::IntToPtr: {
  454. addNode(CE, getAttrUnknown());
  455. break;
  456. }
  457. case Instruction::BitCast:
  458. case Instruction::AddrSpaceCast:
  459. case Instruction::Trunc:
  460. case Instruction::ZExt:
  461. case Instruction::SExt:
  462. case Instruction::FPExt:
  463. case Instruction::FPTrunc:
  464. case Instruction::UIToFP:
  465. case Instruction::SIToFP:
  466. case Instruction::FPToUI:
  467. case Instruction::FPToSI: {
  468. addAssignEdge(CE->getOperand(0), CE);
  469. break;
  470. }
  471. case Instruction::Select: {
  472. addAssignEdge(CE->getOperand(1), CE);
  473. addAssignEdge(CE->getOperand(2), CE);
  474. break;
  475. }
  476. case Instruction::InsertElement:
  477. case Instruction::InsertValue: {
  478. addAssignEdge(CE->getOperand(0), CE);
  479. addStoreEdge(CE->getOperand(1), CE);
  480. break;
  481. }
  482. case Instruction::ExtractElement:
  483. case Instruction::ExtractValue: {
  484. addLoadEdge(CE->getOperand(0), CE);
  485. break;
  486. }
  487. case Instruction::Add:
  488. case Instruction::FAdd:
  489. case Instruction::Sub:
  490. case Instruction::FSub:
  491. case Instruction::Mul:
  492. case Instruction::FMul:
  493. case Instruction::UDiv:
  494. case Instruction::SDiv:
  495. case Instruction::FDiv:
  496. case Instruction::URem:
  497. case Instruction::SRem:
  498. case Instruction::FRem:
  499. case Instruction::And:
  500. case Instruction::Or:
  501. case Instruction::Xor:
  502. case Instruction::Shl:
  503. case Instruction::LShr:
  504. case Instruction::AShr:
  505. case Instruction::ICmp:
  506. case Instruction::FCmp:
  507. case Instruction::ShuffleVector: {
  508. addAssignEdge(CE->getOperand(0), CE);
  509. addAssignEdge(CE->getOperand(1), CE);
  510. break;
  511. }
  512. case Instruction::FNeg: {
  513. addAssignEdge(CE->getOperand(0), CE);
  514. break;
  515. }
  516. default:
  517. llvm_unreachable("Unknown instruction type encountered!");
  518. }
  519. }
  520. };
  521. // Helper functions
  522. // Determines whether or not we an instruction is useless to us (e.g.
  523. // FenceInst)
  524. static bool hasUsefulEdges(Instruction *Inst) {
  525. bool IsNonInvokeRetTerminator = Inst->isTerminator() &&
  526. !isa<InvokeInst>(Inst) &&
  527. !isa<ReturnInst>(Inst);
  528. return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) &&
  529. !IsNonInvokeRetTerminator;
  530. }
  531. void addArgumentToGraph(Argument &Arg) {
  532. if (Arg.getType()->isPointerTy()) {
  533. Graph.addNode(InstantiatedValue{&Arg, 0},
  534. getGlobalOrArgAttrFromValue(Arg));
  535. // Pointees of a formal parameter is known to the caller
  536. Graph.addNode(InstantiatedValue{&Arg, 1}, getAttrCaller());
  537. }
  538. }
  539. // Given an Instruction, this will add it to the graph, along with any
  540. // Instructions that are potentially only available from said Instruction
  541. // For example, given the following line:
  542. // %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
  543. // addInstructionToGraph would add both the `load` and `getelementptr`
  544. // instructions to the graph appropriately.
  545. void addInstructionToGraph(GetEdgesVisitor &Visitor, Instruction &Inst) {
  546. if (!hasUsefulEdges(&Inst))
  547. return;
  548. Visitor.visit(Inst);
  549. }
  550. // Builds the graph needed for constructing the StratifiedSets for the given
  551. // function
  552. void buildGraphFrom(Function &Fn) {
  553. GetEdgesVisitor Visitor(*this, Fn.getParent()->getDataLayout());
  554. for (auto &Bb : Fn.getBasicBlockList())
  555. for (auto &Inst : Bb.getInstList())
  556. addInstructionToGraph(Visitor, Inst);
  557. for (auto &Arg : Fn.args())
  558. addArgumentToGraph(Arg);
  559. }
  560. public:
  561. CFLGraphBuilder(CFLAA &Analysis, const TargetLibraryInfo &TLI, Function &Fn)
  562. : Analysis(Analysis), TLI(TLI) {
  563. buildGraphFrom(Fn);
  564. }
  565. const CFLGraph &getCFLGraph() const { return Graph; }
  566. const SmallVector<Value *, 4> &getReturnValues() const {
  567. return ReturnedValues;
  568. }
  569. };
  570. } // end namespace cflaa
  571. } // end namespace llvm
  572. #endif // LLVM_LIB_ANALYSIS_CFLGRAPH_H