blob: 5783c5bc9bdd5ca9e4a7e8c6c90788706baa42a1 [file] [log] [blame]
Eugene Zelenko530851c2017-08-11 21:30:02 +00001//===- CFLGraph.h - Abstract stratified sets implementation. -----*- C++-*-===//
George Burgess IV1ca8aff2016-07-06 00:36:12 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
George Burgess IV1ca8aff2016-07-06 00:36:12 +00006//
7//===----------------------------------------------------------------------===//
Eugene Zelenko530851c2017-08-11 21:30:02 +00008//
George Burgess IV1ca8aff2016-07-06 00:36:12 +00009/// \file
10/// This file defines CFLGraph, an auxiliary data structure used by CFL-based
11/// alias analysis.
Eugene Zelenko530851c2017-08-11 21:30:02 +000012//
George Burgess IV1ca8aff2016-07-06 00:36:12 +000013//===----------------------------------------------------------------------===//
14
Eugene Zelenko530851c2017-08-11 21:30:02 +000015#ifndef LLVM_LIB_ANALYSIS_CFLGRAPH_H
16#define LLVM_LIB_ANALYSIS_CFLGRAPH_H
George Burgess IV1ca8aff2016-07-06 00:36:12 +000017
George Burgess IVe1919962016-07-06 00:47:21 +000018#include "AliasAnalysisSummary.h"
Eugene Zelenko530851c2017-08-11 21:30:02 +000019#include "llvm/ADT/APInt.h"
20#include "llvm/ADT/DenseMap.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/iterator_range.h"
George Burgess IVc294d0d2016-07-09 02:54:42 +000023#include "llvm/Analysis/MemoryBuiltins.h"
Eugene Zelenko530851c2017-08-11 21:30:02 +000024#include "llvm/Analysis/TargetLibraryInfo.h"
25#include "llvm/IR/Argument.h"
26#include "llvm/IR/BasicBlock.h"
Eugene Zelenko530851c2017-08-11 21:30:02 +000027#include "llvm/IR/Constants.h"
28#include "llvm/IR/DataLayout.h"
29#include "llvm/IR/Function.h"
30#include "llvm/IR/GlobalValue.h"
George Burgess IVc294d0d2016-07-09 02:54:42 +000031#include "llvm/IR/InstVisitor.h"
Eugene Zelenko530851c2017-08-11 21:30:02 +000032#include "llvm/IR/InstrTypes.h"
33#include "llvm/IR/Instruction.h"
George Burgess IVc294d0d2016-07-09 02:54:42 +000034#include "llvm/IR/Instructions.h"
Eugene Zelenko530851c2017-08-11 21:30:02 +000035#include "llvm/IR/Operator.h"
36#include "llvm/IR/Type.h"
37#include "llvm/IR/Value.h"
38#include "llvm/Support/Casting.h"
39#include "llvm/Support/ErrorHandling.h"
40#include <cassert>
41#include <cstdint>
42#include <vector>
George Burgess IV1ca8aff2016-07-06 00:36:12 +000043
44namespace llvm {
George Burgess IV1ca8aff2016-07-06 00:36:12 +000045namespace cflaa {
George Burgess IV1ca8aff2016-07-06 00:36:12 +000046
Adrian Prantl5f8f34e42018-05-01 15:54:18 +000047/// The Program Expression Graph (PEG) of CFL analysis
George Burgess IV1ca8aff2016-07-06 00:36:12 +000048/// CFLGraph is auxiliary data structure used by CFL-based alias analysis to
49/// describe flow-insensitive pointer-related behaviors. Given an LLVM function,
50/// the main purpose of this graph is to abstract away unrelated facts and
51/// translate the rest into a form that can be easily digested by CFL analyses.
George Burgess IVde1be712016-07-11 22:59:09 +000052/// Each Node in the graph is an InstantiatedValue, and each edge represent a
53/// pointer assignment between InstantiatedValue. Pointer
54/// references/dereferences are not explicitly stored in the graph: we
55/// implicitly assume that for each node (X, I) it has a dereference edge to (X,
56/// I+1) and a reference edge to (X, I-1).
George Burgess IV1ca8aff2016-07-06 00:36:12 +000057class CFLGraph {
George Burgess IVde1be712016-07-11 22:59:09 +000058public:
Eugene Zelenko530851c2017-08-11 21:30:02 +000059 using Node = InstantiatedValue;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000060
61 struct Edge {
George Burgess IV1ca8aff2016-07-06 00:36:12 +000062 Node Other;
George Burgess IVc6526172018-05-17 21:56:39 +000063 int64_t Offset;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000064 };
65
Eugene Zelenko530851c2017-08-11 21:30:02 +000066 using EdgeList = std::vector<Edge>;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000067
68 struct NodeInfo {
George Burgess IV6d30aa02016-07-15 19:53:25 +000069 EdgeList Edges, ReverseEdges;
George Burgess IVe1919962016-07-06 00:47:21 +000070 AliasAttrs Attr;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000071 };
72
George Burgess IVde1be712016-07-11 22:59:09 +000073 class ValueInfo {
74 std::vector<NodeInfo> Levels;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000075
George Burgess IVde1be712016-07-11 22:59:09 +000076 public:
77 bool addNodeToLevel(unsigned Level) {
78 auto NumLevels = Levels.size();
79 if (NumLevels > Level)
80 return false;
81 Levels.resize(Level + 1);
82 return true;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000083 }
George Burgess IVde1be712016-07-11 22:59:09 +000084
85 NodeInfo &getNodeInfoAtLevel(unsigned Level) {
86 assert(Level < Levels.size());
87 return Levels[Level];
88 }
89 const NodeInfo &getNodeInfoAtLevel(unsigned Level) const {
90 assert(Level < Levels.size());
91 return Levels[Level];
92 }
93
94 unsigned getNumLevels() const { return Levels.size(); }
95 };
96
97private:
Eugene Zelenko530851c2017-08-11 21:30:02 +000098 using ValueMap = DenseMap<Value *, ValueInfo>;
99
George Burgess IVde1be712016-07-11 22:59:09 +0000100 ValueMap ValueImpls;
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000101
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000102 NodeInfo *getNode(Node N) {
George Burgess IVde1be712016-07-11 22:59:09 +0000103 auto Itr = ValueImpls.find(N.Val);
104 if (Itr == ValueImpls.end() || Itr->second.getNumLevels() <= N.DerefLevel)
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000105 return nullptr;
George Burgess IVde1be712016-07-11 22:59:09 +0000106 return &Itr->second.getNodeInfoAtLevel(N.DerefLevel);
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000107 }
108
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000109public:
Eugene Zelenko530851c2017-08-11 21:30:02 +0000110 using const_value_iterator = ValueMap::const_iterator;
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000111
George Burgess IVde1be712016-07-11 22:59:09 +0000112 bool addNode(Node N, AliasAttrs Attr = AliasAttrs()) {
113 assert(N.Val != nullptr);
114 auto &ValInfo = ValueImpls[N.Val];
115 auto Changed = ValInfo.addNodeToLevel(N.DerefLevel);
116 ValInfo.getNodeInfoAtLevel(N.DerefLevel).Attr |= Attr;
117 return Changed;
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000118 }
119
George Burgess IVe1919962016-07-06 00:47:21 +0000120 void addAttr(Node N, AliasAttrs Attr) {
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000121 auto *Info = getNode(N);
122 assert(Info != nullptr);
123 Info->Attr |= Attr;
124 }
125
George Burgess IVc6526172018-05-17 21:56:39 +0000126 void addEdge(Node From, Node To, int64_t Offset = 0) {
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000127 auto *FromInfo = getNode(From);
128 assert(FromInfo != nullptr);
George Burgess IV6d30aa02016-07-15 19:53:25 +0000129 auto *ToInfo = getNode(To);
130 assert(ToInfo != nullptr);
131
George Burgess IV6febd832016-07-20 22:53:30 +0000132 FromInfo->Edges.push_back(Edge{To, Offset});
133 ToInfo->ReverseEdges.push_back(Edge{From, Offset});
George Burgess IV6d30aa02016-07-15 19:53:25 +0000134 }
135
136 const NodeInfo *getNode(Node N) const {
137 auto Itr = ValueImpls.find(N.Val);
138 if (Itr == ValueImpls.end() || Itr->second.getNumLevels() <= N.DerefLevel)
139 return nullptr;
140 return &Itr->second.getNodeInfoAtLevel(N.DerefLevel);
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000141 }
142
George Burgess IVe1919962016-07-06 00:47:21 +0000143 AliasAttrs attrFor(Node N) const {
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000144 auto *Info = getNode(N);
145 assert(Info != nullptr);
146 return Info->Attr;
147 }
148
George Burgess IVde1be712016-07-11 22:59:09 +0000149 iterator_range<const_value_iterator> value_mappings() const {
150 return make_range<const_value_iterator>(ValueImpls.begin(),
151 ValueImpls.end());
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000152 }
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000153};
George Burgess IVc294d0d2016-07-09 02:54:42 +0000154
Adrian Prantl5f8f34e42018-05-01 15:54:18 +0000155///A builder class used to create CFLGraph instance from a given function
George Burgess IVc294d0d2016-07-09 02:54:42 +0000156/// The CFL-AA that uses this builder must provide its own type as a template
157/// argument. This is necessary for interprocedural processing: CFLGraphBuilder
158/// needs a way of obtaining the summary of other functions when callinsts are
159/// encountered.
160/// As a result, we expect the said CFL-AA to expose a getAliasSummary() public
161/// member function that takes a Function& and returns the corresponding summary
162/// as a const AliasSummary*.
163template <typename CFLAA> class CFLGraphBuilder {
164 // Input of the builder
165 CFLAA &Analysis;
166 const TargetLibraryInfo &TLI;
167
168 // Output of the builder
169 CFLGraph Graph;
170 SmallVector<Value *, 4> ReturnedValues;
171
George Burgess IVc294d0d2016-07-09 02:54:42 +0000172 // Helper class
173 /// Gets the edges our graph should have, based on an Instruction*
174 class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
175 CFLAA &AA;
George Burgess IV6febd832016-07-20 22:53:30 +0000176 const DataLayout &DL;
George Burgess IVc294d0d2016-07-09 02:54:42 +0000177 const TargetLibraryInfo &TLI;
178
179 CFLGraph &Graph;
180 SmallVectorImpl<Value *> &ReturnValues;
George Burgess IVc294d0d2016-07-09 02:54:42 +0000181
182 static bool hasUsefulEdges(ConstantExpr *CE) {
183 // ConstantExpr doesn't have terminators, invokes, or fences, so only
184 // needs
185 // to check for compares.
186 return CE->getOpcode() != Instruction::ICmp &&
187 CE->getOpcode() != Instruction::FCmp;
188 }
189
190 // Returns possible functions called by CS into the given SmallVectorImpl.
191 // Returns true if targets found, false otherwise.
Chandler Carruth9beadff2019-02-11 09:25:41 +0000192 static bool getPossibleTargets(CallBase &Call,
George Burgess IVc294d0d2016-07-09 02:54:42 +0000193 SmallVectorImpl<Function *> &Output) {
Chandler Carruth9beadff2019-02-11 09:25:41 +0000194 if (auto *Fn = Call.getCalledFunction()) {
George Burgess IVc294d0d2016-07-09 02:54:42 +0000195 Output.push_back(Fn);
196 return true;
197 }
198
199 // TODO: If the call is indirect, we might be able to enumerate all
200 // potential
201 // targets of the call and return them, rather than just failing.
202 return false;
203 }
204
George Burgess IVde1be712016-07-11 22:59:09 +0000205 void addNode(Value *Val, AliasAttrs Attr = AliasAttrs()) {
206 assert(Val != nullptr && Val->getType()->isPointerTy());
207 if (auto GVal = dyn_cast<GlobalValue>(Val)) {
208 if (Graph.addNode(InstantiatedValue{GVal, 0},
209 getGlobalOrArgAttrFromValue(*GVal)))
210 Graph.addNode(InstantiatedValue{GVal, 1}, getAttrUnknown());
211 } else if (auto CExpr = dyn_cast<ConstantExpr>(Val)) {
212 if (hasUsefulEdges(CExpr)) {
213 if (Graph.addNode(InstantiatedValue{CExpr, 0}))
214 visitConstantExpr(CExpr);
215 }
216 } else
217 Graph.addNode(InstantiatedValue{Val, 0}, Attr);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000218 }
219
George Burgess IVc6526172018-05-17 21:56:39 +0000220 void addAssignEdge(Value *From, Value *To, int64_t Offset = 0) {
George Burgess IVc294d0d2016-07-09 02:54:42 +0000221 assert(From != nullptr && To != nullptr);
222 if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
223 return;
224 addNode(From);
George Burgess IVde1be712016-07-11 22:59:09 +0000225 if (To != From) {
George Burgess IVc294d0d2016-07-09 02:54:42 +0000226 addNode(To);
George Burgess IVde1be712016-07-11 22:59:09 +0000227 Graph.addEdge(InstantiatedValue{From, 0}, InstantiatedValue{To, 0},
228 Offset);
229 }
230 }
231
George Burgess IV6d30aa02016-07-15 19:53:25 +0000232 void addDerefEdge(Value *From, Value *To, bool IsRead) {
George Burgess IVde1be712016-07-11 22:59:09 +0000233 assert(From != nullptr && To != nullptr);
George Burgess IV0a7b9892017-05-31 02:35:26 +0000234 // FIXME: This is subtly broken, due to how we model some instructions
235 // (e.g. extractvalue, extractelement) as loads. Since those take
236 // non-pointer operands, we'll entirely skip adding edges for those.
237 //
238 // addAssignEdge seems to have a similar issue with insertvalue, etc.
George Burgess IVde1be712016-07-11 22:59:09 +0000239 if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
240 return;
241 addNode(From);
242 addNode(To);
George Burgess IV6d30aa02016-07-15 19:53:25 +0000243 if (IsRead) {
244 Graph.addNode(InstantiatedValue{From, 1});
245 Graph.addEdge(InstantiatedValue{From, 1}, InstantiatedValue{To, 0});
246 } else {
247 Graph.addNode(InstantiatedValue{To, 1});
248 Graph.addEdge(InstantiatedValue{From, 0}, InstantiatedValue{To, 1});
249 }
George Burgess IVc294d0d2016-07-09 02:54:42 +0000250 }
251
George Burgess IV6d30aa02016-07-15 19:53:25 +0000252 void addLoadEdge(Value *From, Value *To) { addDerefEdge(From, To, true); }
253 void addStoreEdge(Value *From, Value *To) { addDerefEdge(From, To, false); }
254
George Burgess IVc294d0d2016-07-09 02:54:42 +0000255 public:
George Burgess IV6febd832016-07-20 22:53:30 +0000256 GetEdgesVisitor(CFLGraphBuilder &Builder, const DataLayout &DL)
257 : AA(Builder.Analysis), DL(DL), TLI(Builder.TLI), Graph(Builder.Graph),
George Burgess IVde1be712016-07-11 22:59:09 +0000258 ReturnValues(Builder.ReturnedValues) {}
George Burgess IVc294d0d2016-07-09 02:54:42 +0000259
260 void visitInstruction(Instruction &) {
261 llvm_unreachable("Unsupported instruction encountered");
262 }
263
264 void visitReturnInst(ReturnInst &Inst) {
265 if (auto RetVal = Inst.getReturnValue()) {
266 if (RetVal->getType()->isPointerTy()) {
267 addNode(RetVal);
268 ReturnValues.push_back(RetVal);
269 }
270 }
271 }
272
273 void visitPtrToIntInst(PtrToIntInst &Inst) {
274 auto *Ptr = Inst.getOperand(0);
George Burgess IVde1be712016-07-11 22:59:09 +0000275 addNode(Ptr, getAttrEscaped());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000276 }
277
278 void visitIntToPtrInst(IntToPtrInst &Inst) {
279 auto *Ptr = &Inst;
George Burgess IVde1be712016-07-11 22:59:09 +0000280 addNode(Ptr, getAttrUnknown());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000281 }
282
283 void visitCastInst(CastInst &Inst) {
284 auto *Src = Inst.getOperand(0);
George Burgess IVde1be712016-07-11 22:59:09 +0000285 addAssignEdge(Src, &Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000286 }
287
288 void visitBinaryOperator(BinaryOperator &Inst) {
289 auto *Op1 = Inst.getOperand(0);
290 auto *Op2 = Inst.getOperand(1);
George Burgess IVde1be712016-07-11 22:59:09 +0000291 addAssignEdge(Op1, &Inst);
292 addAssignEdge(Op2, &Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000293 }
294
295 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
296 auto *Ptr = Inst.getPointerOperand();
297 auto *Val = Inst.getNewValOperand();
George Burgess IV6d30aa02016-07-15 19:53:25 +0000298 addStoreEdge(Val, Ptr);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000299 }
300
301 void visitAtomicRMWInst(AtomicRMWInst &Inst) {
302 auto *Ptr = Inst.getPointerOperand();
303 auto *Val = Inst.getValOperand();
George Burgess IV6d30aa02016-07-15 19:53:25 +0000304 addStoreEdge(Val, Ptr);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000305 }
306
307 void visitPHINode(PHINode &Inst) {
308 for (Value *Val : Inst.incoming_values())
George Burgess IVde1be712016-07-11 22:59:09 +0000309 addAssignEdge(Val, &Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000310 }
311
George Burgess IV6febd832016-07-20 22:53:30 +0000312 void visitGEP(GEPOperator &GEPOp) {
George Burgess IVc6526172018-05-17 21:56:39 +0000313 uint64_t Offset = UnknownOffset;
George Burgess IV6febd832016-07-20 22:53:30 +0000314 APInt APOffset(DL.getPointerSizeInBits(GEPOp.getPointerAddressSpace()),
315 0);
316 if (GEPOp.accumulateConstantOffset(DL, APOffset))
317 Offset = APOffset.getSExtValue();
318
319 auto *Op = GEPOp.getPointerOperand();
320 addAssignEdge(Op, &GEPOp, Offset);
321 }
322
George Burgess IVc294d0d2016-07-09 02:54:42 +0000323 void visitGetElementPtrInst(GetElementPtrInst &Inst) {
George Burgess IV6febd832016-07-20 22:53:30 +0000324 auto *GEPOp = cast<GEPOperator>(&Inst);
325 visitGEP(*GEPOp);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000326 }
327
328 void visitSelectInst(SelectInst &Inst) {
329 // Condition is not processed here (The actual statement producing
330 // the condition result is processed elsewhere). For select, the
331 // condition is evaluated, but not loaded, stored, or assigned
332 // simply as a result of being the condition of a select.
333
334 auto *TrueVal = Inst.getTrueValue();
335 auto *FalseVal = Inst.getFalseValue();
George Burgess IVde1be712016-07-11 22:59:09 +0000336 addAssignEdge(TrueVal, &Inst);
337 addAssignEdge(FalseVal, &Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000338 }
339
George Burgess IVde1be712016-07-11 22:59:09 +0000340 void visitAllocaInst(AllocaInst &Inst) { addNode(&Inst); }
George Burgess IVc294d0d2016-07-09 02:54:42 +0000341
342 void visitLoadInst(LoadInst &Inst) {
343 auto *Ptr = Inst.getPointerOperand();
344 auto *Val = &Inst;
George Burgess IV6d30aa02016-07-15 19:53:25 +0000345 addLoadEdge(Ptr, Val);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000346 }
347
348 void visitStoreInst(StoreInst &Inst) {
349 auto *Ptr = Inst.getPointerOperand();
350 auto *Val = Inst.getValueOperand();
George Burgess IV6d30aa02016-07-15 19:53:25 +0000351 addStoreEdge(Val, Ptr);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000352 }
353
354 void visitVAArgInst(VAArgInst &Inst) {
355 // We can't fully model va_arg here. For *Ptr = Inst.getOperand(0), it
356 // does
357 // two things:
358 // 1. Loads a value from *((T*)*Ptr).
359 // 2. Increments (stores to) *Ptr by some target-specific amount.
360 // For now, we'll handle this like a landingpad instruction (by placing
361 // the
362 // result in its own group, and having that group alias externals).
George Burgess IV0a9cbd42016-07-29 01:23:45 +0000363 if (Inst.getType()->isPointerTy())
364 addNode(&Inst, getAttrUnknown());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000365 }
366
367 static bool isFunctionExternal(Function *Fn) {
368 return !Fn->hasExactDefinition();
369 }
370
Chandler Carruth9beadff2019-02-11 09:25:41 +0000371 bool tryInterproceduralAnalysis(CallBase &Call,
George Burgess IVc294d0d2016-07-09 02:54:42 +0000372 const SmallVectorImpl<Function *> &Fns) {
373 assert(Fns.size() > 0);
374
Chandler Carruth9beadff2019-02-11 09:25:41 +0000375 if (Call.arg_size() > MaxSupportedArgsInSummary)
George Burgess IVc294d0d2016-07-09 02:54:42 +0000376 return false;
377
378 // Exit early if we'll fail anyway
379 for (auto *Fn : Fns) {
380 if (isFunctionExternal(Fn) || Fn->isVarArg())
381 return false;
382 // Fail if the caller does not provide enough arguments
Chandler Carruth9beadff2019-02-11 09:25:41 +0000383 assert(Fn->arg_size() <= Call.arg_size());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000384 if (!AA.getAliasSummary(*Fn))
385 return false;
386 }
387
388 for (auto *Fn : Fns) {
389 auto Summary = AA.getAliasSummary(*Fn);
390 assert(Summary != nullptr);
391
392 auto &RetParamRelations = Summary->RetParamRelations;
393 for (auto &Relation : RetParamRelations) {
Chandler Carruth9beadff2019-02-11 09:25:41 +0000394 auto IRelation = instantiateExternalRelation(Relation, Call);
George Burgess IVde1be712016-07-11 22:59:09 +0000395 if (IRelation.hasValue()) {
396 Graph.addNode(IRelation->From);
397 Graph.addNode(IRelation->To);
George Burgess IVc6526172018-05-17 21:56:39 +0000398 Graph.addEdge(IRelation->From, IRelation->To);
George Burgess IVde1be712016-07-11 22:59:09 +0000399 }
George Burgess IVc294d0d2016-07-09 02:54:42 +0000400 }
401
402 auto &RetParamAttributes = Summary->RetParamAttributes;
403 for (auto &Attribute : RetParamAttributes) {
Chandler Carruth9beadff2019-02-11 09:25:41 +0000404 auto IAttr = instantiateExternalAttribute(Attribute, Call);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000405 if (IAttr.hasValue())
George Burgess IVde1be712016-07-11 22:59:09 +0000406 Graph.addNode(IAttr->IValue, IAttr->Attr);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000407 }
408 }
409
410 return true;
411 }
412
Chandler Carruth9beadff2019-02-11 09:25:41 +0000413 void visitCallBase(CallBase &Call) {
George Burgess IVc294d0d2016-07-09 02:54:42 +0000414 // Make sure all arguments and return value are added to the graph first
Chandler Carruth9beadff2019-02-11 09:25:41 +0000415 for (Value *V : Call.args())
George Burgess IVde1be712016-07-11 22:59:09 +0000416 if (V->getType()->isPointerTy())
417 addNode(V);
Chandler Carruth9beadff2019-02-11 09:25:41 +0000418 if (Call.getType()->isPointerTy())
419 addNode(&Call);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000420
421 // Check if Inst is a call to a library function that
George Burgess IVe8168182018-05-26 02:17:43 +0000422 // allocates/deallocates on the heap. Those kinds of functions do not
423 // introduce any aliases.
George Burgess IVc294d0d2016-07-09 02:54:42 +0000424 // TODO: address other common library functions such as realloc(),
George Burgess IVe8168182018-05-26 02:17:43 +0000425 // strdup(), etc.
Chandler Carruth9beadff2019-02-11 09:25:41 +0000426 if (isMallocOrCallocLikeFn(&Call, &TLI) || isFreeCall(&Call, &TLI))
George Burgess IVc294d0d2016-07-09 02:54:42 +0000427 return;
428
429 // TODO: Add support for noalias args/all the other fun function
George Burgess IVe8168182018-05-26 02:17:43 +0000430 // attributes that we can tack on.
George Burgess IVc294d0d2016-07-09 02:54:42 +0000431 SmallVector<Function *, 4> Targets;
Chandler Carruth9beadff2019-02-11 09:25:41 +0000432 if (getPossibleTargets(Call, Targets))
433 if (tryInterproceduralAnalysis(Call, Targets))
George Burgess IVc294d0d2016-07-09 02:54:42 +0000434 return;
435
436 // Because the function is opaque, we need to note that anything
437 // could have happened to the arguments (unless the function is marked
438 // readonly or readnone), and that the result could alias just about
439 // anything, too (unless the result is marked noalias).
Chandler Carruth9beadff2019-02-11 09:25:41 +0000440 if (!Call.onlyReadsMemory())
441 for (Value *V : Call.args()) {
George Burgess IVc294d0d2016-07-09 02:54:42 +0000442 if (V->getType()->isPointerTy()) {
443 // The argument itself escapes.
George Burgess IVde1be712016-07-11 22:59:09 +0000444 Graph.addAttr(InstantiatedValue{V, 0}, getAttrEscaped());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000445 // The fate of argument memory is unknown. Note that since
George Burgess IVde1be712016-07-11 22:59:09 +0000446 // AliasAttrs is transitive with respect to dereference, we only
447 // need to specify it for the first-level memory.
448 Graph.addNode(InstantiatedValue{V, 1}, getAttrUnknown());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000449 }
450 }
451
Chandler Carruth9beadff2019-02-11 09:25:41 +0000452 if (Call.getType()->isPointerTy()) {
453 auto *Fn = Call.getCalledFunction();
Reid Klecknera0b45f42017-05-03 18:17:31 +0000454 if (Fn == nullptr || !Fn->returnDoesNotAlias())
George Burgess IVde1be712016-07-11 22:59:09 +0000455 // No need to call addNode() since we've added Inst at the
George Burgess IVc294d0d2016-07-09 02:54:42 +0000456 // beginning of this function and we know it is not a global.
Chandler Carruth9beadff2019-02-11 09:25:41 +0000457 Graph.addAttr(InstantiatedValue{&Call, 0}, getAttrUnknown());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000458 }
459 }
460
461 /// Because vectors/aggregates are immutable and unaddressable, there's
462 /// nothing we can do to coax a value out of them, other than calling
463 /// Extract{Element,Value}. We can effectively treat them as pointers to
464 /// arbitrary memory locations we can store in and load from.
465 void visitExtractElementInst(ExtractElementInst &Inst) {
466 auto *Ptr = Inst.getVectorOperand();
467 auto *Val = &Inst;
George Burgess IV6d30aa02016-07-15 19:53:25 +0000468 addLoadEdge(Ptr, Val);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000469 }
470
471 void visitInsertElementInst(InsertElementInst &Inst) {
472 auto *Vec = Inst.getOperand(0);
473 auto *Val = Inst.getOperand(1);
George Burgess IVde1be712016-07-11 22:59:09 +0000474 addAssignEdge(Vec, &Inst);
George Burgess IV6d30aa02016-07-15 19:53:25 +0000475 addStoreEdge(Val, &Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000476 }
477
478 void visitLandingPadInst(LandingPadInst &Inst) {
479 // Exceptions come from "nowhere", from our analysis' perspective.
480 // So we place the instruction its own group, noting that said group may
481 // alias externals
George Burgess IV0a9cbd42016-07-29 01:23:45 +0000482 if (Inst.getType()->isPointerTy())
483 addNode(&Inst, getAttrUnknown());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000484 }
485
486 void visitInsertValueInst(InsertValueInst &Inst) {
487 auto *Agg = Inst.getOperand(0);
488 auto *Val = Inst.getOperand(1);
George Burgess IVde1be712016-07-11 22:59:09 +0000489 addAssignEdge(Agg, &Inst);
George Burgess IV6d30aa02016-07-15 19:53:25 +0000490 addStoreEdge(Val, &Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000491 }
492
493 void visitExtractValueInst(ExtractValueInst &Inst) {
494 auto *Ptr = Inst.getAggregateOperand();
George Burgess IV6d30aa02016-07-15 19:53:25 +0000495 addLoadEdge(Ptr, &Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000496 }
497
498 void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
499 auto *From1 = Inst.getOperand(0);
500 auto *From2 = Inst.getOperand(1);
George Burgess IVde1be712016-07-11 22:59:09 +0000501 addAssignEdge(From1, &Inst);
502 addAssignEdge(From2, &Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000503 }
504
505 void visitConstantExpr(ConstantExpr *CE) {
506 switch (CE->getOpcode()) {
George Burgess IV6febd832016-07-20 22:53:30 +0000507 case Instruction::GetElementPtr: {
508 auto GEPOp = cast<GEPOperator>(CE);
509 visitGEP(*GEPOp);
510 break;
511 }
David Bolvansky8d693602018-05-01 21:35:32 +0000512
George Burgess IV6febd832016-07-20 22:53:30 +0000513 case Instruction::PtrToInt: {
David Bolvansky8d693602018-05-01 21:35:32 +0000514 addNode(CE->getOperand(0), getAttrEscaped());
George Burgess IV6febd832016-07-20 22:53:30 +0000515 break;
516 }
David Bolvansky8d693602018-05-01 21:35:32 +0000517
518 case Instruction::IntToPtr: {
George Burgess IV6febd832016-07-20 22:53:30 +0000519 addNode(CE, getAttrUnknown());
520 break;
David Bolvansky8d693602018-05-01 21:35:32 +0000521 }
Eugene Zelenko530851c2017-08-11 21:30:02 +0000522
George Burgess IV6febd832016-07-20 22:53:30 +0000523 case Instruction::BitCast:
524 case Instruction::AddrSpaceCast:
525 case Instruction::Trunc:
526 case Instruction::ZExt:
527 case Instruction::SExt:
528 case Instruction::FPExt:
529 case Instruction::FPTrunc:
530 case Instruction::UIToFP:
531 case Instruction::SIToFP:
532 case Instruction::FPToUI:
533 case Instruction::FPToSI: {
David Bolvansky8d693602018-05-01 21:35:32 +0000534 addAssignEdge(CE->getOperand(0), CE);
George Burgess IV6febd832016-07-20 22:53:30 +0000535 break;
536 }
David Bolvansky8d693602018-05-01 21:35:32 +0000537
David Bolvansky10c218d2018-05-10 11:47:36 +0000538 case Instruction::Select: {
539 addAssignEdge(CE->getOperand(1), CE);
540 addAssignEdge(CE->getOperand(2), CE);
541 break;
542 }
543
David Bolvansky8d693602018-05-01 21:35:32 +0000544 case Instruction::InsertElement:
George Burgess IV6febd832016-07-20 22:53:30 +0000545 case Instruction::InsertValue: {
David Bolvansky8d693602018-05-01 21:35:32 +0000546 addAssignEdge(CE->getOperand(0), CE);
547 addStoreEdge(CE->getOperand(1), CE);
George Burgess IV6febd832016-07-20 22:53:30 +0000548 break;
549 }
David Bolvansky8d693602018-05-01 21:35:32 +0000550
551 case Instruction::ExtractElement:
George Burgess IV6febd832016-07-20 22:53:30 +0000552 case Instruction::ExtractValue: {
David Bolvansky8d693602018-05-01 21:35:32 +0000553 addLoadEdge(CE->getOperand(0), CE);
George Burgess IV0a7b9892017-05-31 02:35:26 +0000554 break;
George Burgess IV6febd832016-07-20 22:53:30 +0000555 }
David Bolvansky8d693602018-05-01 21:35:32 +0000556
George Burgess IV6febd832016-07-20 22:53:30 +0000557 case Instruction::Add:
558 case Instruction::Sub:
559 case Instruction::FSub:
560 case Instruction::Mul:
561 case Instruction::FMul:
562 case Instruction::UDiv:
563 case Instruction::SDiv:
564 case Instruction::FDiv:
565 case Instruction::URem:
566 case Instruction::SRem:
567 case Instruction::FRem:
568 case Instruction::And:
569 case Instruction::Or:
570 case Instruction::Xor:
571 case Instruction::Shl:
572 case Instruction::LShr:
573 case Instruction::AShr:
574 case Instruction::ICmp:
Eugene Zelenko530851c2017-08-11 21:30:02 +0000575 case Instruction::FCmp:
David Bolvansky8d693602018-05-01 21:35:32 +0000576 case Instruction::ShuffleVector: {
George Burgess IV6febd832016-07-20 22:53:30 +0000577 addAssignEdge(CE->getOperand(0), CE);
578 addAssignEdge(CE->getOperand(1), CE);
579 break;
David Bolvansky8d693602018-05-01 21:35:32 +0000580 }
Eugene Zelenko530851c2017-08-11 21:30:02 +0000581
George Burgess IVc294d0d2016-07-09 02:54:42 +0000582 default:
583 llvm_unreachable("Unknown instruction type encountered!");
George Burgess IVc294d0d2016-07-09 02:54:42 +0000584 }
585 }
586 };
587
588 // Helper functions
589
590 // Determines whether or not we an instruction is useless to us (e.g.
591 // FenceInst)
592 static bool hasUsefulEdges(Instruction *Inst) {
Chandler Carruth9ae926b2018-08-26 09:51:22 +0000593 bool IsNonInvokeRetTerminator = Inst->isTerminator() &&
George Burgess IVc294d0d2016-07-09 02:54:42 +0000594 !isa<InvokeInst>(Inst) &&
595 !isa<ReturnInst>(Inst);
596 return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) &&
597 !IsNonInvokeRetTerminator;
598 }
599
600 void addArgumentToGraph(Argument &Arg) {
601 if (Arg.getType()->isPointerTy()) {
George Burgess IVde1be712016-07-11 22:59:09 +0000602 Graph.addNode(InstantiatedValue{&Arg, 0},
603 getGlobalOrArgAttrFromValue(Arg));
George Burgess IVc294d0d2016-07-09 02:54:42 +0000604 // Pointees of a formal parameter is known to the caller
George Burgess IVde1be712016-07-11 22:59:09 +0000605 Graph.addNode(InstantiatedValue{&Arg, 1}, getAttrCaller());
George Burgess IVc294d0d2016-07-09 02:54:42 +0000606 }
607 }
608
609 // Given an Instruction, this will add it to the graph, along with any
610 // Instructions that are potentially only available from said Instruction
611 // For example, given the following line:
612 // %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
613 // addInstructionToGraph would add both the `load` and `getelementptr`
614 // instructions to the graph appropriately.
George Burgess IVde1be712016-07-11 22:59:09 +0000615 void addInstructionToGraph(GetEdgesVisitor &Visitor, Instruction &Inst) {
George Burgess IVc294d0d2016-07-09 02:54:42 +0000616 if (!hasUsefulEdges(&Inst))
617 return;
618
George Burgess IVde1be712016-07-11 22:59:09 +0000619 Visitor.visit(Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000620 }
621
622 // Builds the graph needed for constructing the StratifiedSets for the given
623 // function
624 void buildGraphFrom(Function &Fn) {
George Burgess IV6febd832016-07-20 22:53:30 +0000625 GetEdgesVisitor Visitor(*this, Fn.getParent()->getDataLayout());
George Burgess IVde1be712016-07-11 22:59:09 +0000626
George Burgess IVc294d0d2016-07-09 02:54:42 +0000627 for (auto &Bb : Fn.getBasicBlockList())
628 for (auto &Inst : Bb.getInstList())
George Burgess IVde1be712016-07-11 22:59:09 +0000629 addInstructionToGraph(Visitor, Inst);
George Burgess IVc294d0d2016-07-09 02:54:42 +0000630
631 for (auto &Arg : Fn.args())
632 addArgumentToGraph(Arg);
633 }
634
635public:
636 CFLGraphBuilder(CFLAA &Analysis, const TargetLibraryInfo &TLI, Function &Fn)
637 : Analysis(Analysis), TLI(TLI) {
638 buildGraphFrom(Fn);
639 }
640
641 const CFLGraph &getCFLGraph() const { return Graph; }
642 const SmallVector<Value *, 4> &getReturnValues() const {
643 return ReturnedValues;
644 }
George Burgess IVc294d0d2016-07-09 02:54:42 +0000645};
George Burgess IV1ca8aff2016-07-06 00:36:12 +0000646
Eugene Zelenko530851c2017-08-11 21:30:02 +0000647} // end namespace cflaa
648} // end namespace llvm
649
650#endif // LLVM_LIB_ANALYSIS_CFLGRAPH_H