blob: b00c78a90f2d84cf265bf3226ea7cc05c3974a0e [file] [log] [blame]
Hal Finkel7529c552014-09-02 21:43:13 +00001//===- CFLAliasAnalysis.cpp - CFL-Based Alias Analysis Implementation ------==//
2//
3// The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// This file implements a CFL-based context-insensitive alias analysis
11// algorithm. It does not depend on types. The algorithm is a mixture of the one
12// described in "Demand-driven alias analysis for C" by Xin Zheng and Radu
13// Rugina, and "Fast algorithms for Dyck-CFL-reachability with applications to
14// Alias Analysis" by Zhang Q, Lyu M R, Yuan H, and Su Z. -- to summarize the
15// papers, we build a graph of the uses of a variable, where each node is a
16// memory location, and each edge is an action that happened on that memory
Chad Rosier38c6ad22015-06-19 17:32:57 +000017// location. The "actions" can be one of Dereference, Reference, or Assign.
Hal Finkel7529c552014-09-02 21:43:13 +000018//
19// Two variables are considered as aliasing iff you can reach one value's node
20// from the other value's node and the language formed by concatenating all of
21// the edge labels (actions) conforms to a context-free grammar.
22//
23// Because this algorithm requires a graph search on each query, we execute the
24// algorithm outlined in "Fast algorithms..." (mentioned above)
25// in order to transform the graph into sets of variables that may alias in
George Burgess IV77351ba32016-01-28 00:54:01 +000026// ~nlogn time (n = number of variables), which makes queries take constant
Hal Finkel7529c552014-09-02 21:43:13 +000027// time.
28//===----------------------------------------------------------------------===//
29
George Burgess IV77351ba32016-01-28 00:54:01 +000030// N.B. AliasAnalysis as a whole is phrased as a FunctionPass at the moment, and
31// CFLAA is interprocedural. This is *technically* A Bad Thing, because
32// FunctionPasses are only allowed to inspect the Function that they're being
33// run on. Realistically, this likely isn't a problem until we allow
34// FunctionPasses to run concurrently.
35
Chandler Carruth8b046a42015-08-14 02:42:20 +000036#include "llvm/Analysis/CFLAliasAnalysis.h"
Hal Finkel7529c552014-09-02 21:43:13 +000037#include "StratifiedSets.h"
Hal Finkel7529c552014-09-02 21:43:13 +000038#include "llvm/ADT/DenseMap.h"
Hal Finkel7529c552014-09-02 21:43:13 +000039#include "llvm/ADT/None.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000040#include "llvm/ADT/Optional.h"
George Burgess IV18b83fe2016-06-01 18:39:54 +000041#include "llvm/Analysis/MemoryBuiltins.h"
42#include "llvm/Analysis/TargetLibraryInfo.h"
Hal Finkel7529c552014-09-02 21:43:13 +000043#include "llvm/IR/Constants.h"
44#include "llvm/IR/Function.h"
Hal Finkel7529c552014-09-02 21:43:13 +000045#include "llvm/IR/InstVisitor.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000046#include "llvm/IR/Instructions.h"
Hal Finkel7529c552014-09-02 21:43:13 +000047#include "llvm/Pass.h"
Hal Finkel7d7087c2014-09-02 22:13:00 +000048#include "llvm/Support/Compiler.h"
George Burgess IV33305e72015-02-12 03:07:07 +000049#include "llvm/Support/Debug.h"
Hal Finkel7529c552014-09-02 21:43:13 +000050#include "llvm/Support/ErrorHandling.h"
Benjamin Kramer799003b2015-03-23 19:32:43 +000051#include "llvm/Support/raw_ostream.h"
Hal Finkel7529c552014-09-02 21:43:13 +000052#include <algorithm>
53#include <cassert>
Benjamin Kramer799003b2015-03-23 19:32:43 +000054#include <memory>
Hal Finkel7529c552014-09-02 21:43:13 +000055#include <tuple>
56
57using namespace llvm;
58
George Burgess IV33305e72015-02-12 03:07:07 +000059#define DEBUG_TYPE "cfl-aa"
60
George Burgess IV18b83fe2016-06-01 18:39:54 +000061CFLAAResult::CFLAAResult(const TargetLibraryInfo &TLI)
62 : AAResultBase(), TLI(TLI) {}
63CFLAAResult::CFLAAResult(CFLAAResult &&Arg)
64 : AAResultBase(std::move(Arg)), TLI(Arg.TLI) {}
Chandler Carruth342c6712016-02-20 03:52:02 +000065CFLAAResult::~CFLAAResult() {}
Chandler Carruth8b046a42015-08-14 02:42:20 +000066
George Burgess IV1f99da52016-06-23 18:55:23 +000067/// We use InterfaceValue to describe parameters/return value, as well as
68/// potential memory locations that are pointed to by parameters/return value,
69/// of a function.
70/// Index is an integer which represents a single parameter or a return value.
71/// When the index is 0, it refers to the return value. Non-zero index i refers
72/// to the i-th parameter.
73/// DerefLevel indicates the number of dereferences one must perform on the
74/// parameter/return value to get this InterfaceValue.
75struct InterfaceValue {
76 unsigned Index;
77 unsigned DerefLevel;
78};
79
80bool operator==(InterfaceValue lhs, InterfaceValue rhs) {
81 return lhs.Index == rhs.Index && lhs.DerefLevel == rhs.DerefLevel;
82}
83bool operator!=(InterfaceValue lhs, InterfaceValue rhs) {
84 return !(lhs == rhs);
85}
86
87/// We use ExternalRelation to describe an externally visible aliasing relations
George Burgess IV87b2e412016-06-20 23:10:56 +000088/// between parameters/return value of a function.
George Burgess IV87b2e412016-06-20 23:10:56 +000089struct ExternalRelation {
George Burgess IV1f99da52016-06-23 18:55:23 +000090 InterfaceValue From, To;
George Burgess IV87b2e412016-06-20 23:10:56 +000091};
Chandler Carruth8b046a42015-08-14 02:42:20 +000092
George Burgess IVa3d62be2016-06-24 01:00:03 +000093/// We use ExternalAttribute to describe an externally visible StratifiedAttrs
94/// for parameters/return value.
95struct ExternalAttribute {
96 InterfaceValue IValue;
97 StratifiedAttrs Attr;
98};
99
George Burgess IV87b2e412016-06-20 23:10:56 +0000100/// Information we have about a function and would like to keep around.
101class CFLAAResult::FunctionInfo {
102 StratifiedSets<Value *> Sets;
103
104 // RetParamRelations is a collection of ExternalRelations.
105 SmallVector<ExternalRelation, 8> RetParamRelations;
106
George Burgess IVa3d62be2016-06-24 01:00:03 +0000107 // RetParamAttributes is a collection of ExternalAttributes.
108 SmallVector<ExternalAttribute, 8> RetParamAttributes;
109
George Burgess IV87b2e412016-06-20 23:10:56 +0000110public:
111 FunctionInfo(Function &Fn, const SmallVectorImpl<Value *> &RetVals,
112 StratifiedSets<Value *> S);
113
114 const StratifiedSets<Value *> &getStratifiedSets() const { return Sets; }
115 const SmallVectorImpl<ExternalRelation> &getRetParamRelations() const {
116 return RetParamRelations;
117 }
George Burgess IVa3d62be2016-06-24 01:00:03 +0000118 const SmallVectorImpl<ExternalAttribute> &getRetParamAttributes() const {
119 return RetParamAttributes;
120 }
Chandler Carruth8b046a42015-08-14 02:42:20 +0000121};
122
George Burgess IVcae581d2016-04-13 23:27:37 +0000123/// Try to go from a Value* to a Function*. Never returns nullptr.
Hal Finkel7529c552014-09-02 21:43:13 +0000124static Optional<Function *> parentFunctionOfValue(Value *);
125
George Burgess IVcae581d2016-04-13 23:27:37 +0000126/// Returns possible functions called by the Inst* into the given
127/// SmallVectorImpl. Returns true if targets found, false otherwise. This is
128/// templated so we can use it with CallInsts and InvokeInsts.
George Burgess IV24eb0da2016-06-14 18:12:28 +0000129static bool getPossibleTargets(CallSite, SmallVectorImpl<Function *> &);
Hal Finkel7529c552014-09-02 21:43:13 +0000130
Hal Finkel1ae325f2014-09-02 23:50:01 +0000131const StratifiedIndex StratifiedLink::SetSentinel =
George Burgess IV11d509d2015-03-15 00:52:21 +0000132 std::numeric_limits<StratifiedIndex>::max();
Hal Finkel1ae325f2014-09-02 23:50:01 +0000133
Hal Finkel7529c552014-09-02 21:43:13 +0000134namespace {
George Burgess IVcae581d2016-04-13 23:27:37 +0000135/// StratifiedInfo Attribute things.
Hal Finkel7d7087c2014-09-02 22:13:00 +0000136LLVM_CONSTEXPR unsigned MaxStratifiedAttrIndex = NumStratifiedAttrs;
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000137LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0;
138LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1;
139LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000140LLVM_CONSTEXPR unsigned AttrCallerIndex = 3;
141LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4;
Hal Finkel7d7087c2014-09-02 22:13:00 +0000142LLVM_CONSTEXPR unsigned AttrLastArgIndex = MaxStratifiedAttrIndex;
143LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
Hal Finkel7529c552014-09-02 21:43:13 +0000144
George Burgess IVa3d62be2016-06-24 01:00:03 +0000145LLVM_CONSTEXPR StratifiedAttrs AttrNone = 0;
146LLVM_CONSTEXPR StratifiedAttrs AttrEscaped = 1 << AttrEscapedIndex;
147LLVM_CONSTEXPR StratifiedAttrs AttrUnknown = 1 << AttrUnknownIndex;
148LLVM_CONSTEXPR StratifiedAttrs AttrGlobal = 1 << AttrGlobalIndex;
149LLVM_CONSTEXPR StratifiedAttrs AttrCaller = 1 << AttrCallerIndex;
150LLVM_CONSTEXPR StratifiedAttrs ExternalAttrMask =
151 (1 << AttrEscapedIndex) | (1 << AttrUnknownIndex) | (1 << AttrGlobalIndex);
Hal Finkel7529c552014-09-02 21:43:13 +0000152
George Burgess IV87b2e412016-06-20 23:10:56 +0000153/// The maximum number of arguments we can put into a summary.
154LLVM_CONSTEXPR unsigned MaxSupportedArgsInSummary = 50;
155
George Burgess IVcae581d2016-04-13 23:27:37 +0000156/// StratifiedSets call for knowledge of "direction", so this is how we
157/// represent that locally.
Hal Finkel7529c552014-09-02 21:43:13 +0000158enum class Level { Same, Above, Below };
159
George Burgess IVcae581d2016-04-13 23:27:37 +0000160/// Edges can be one of four "weights" -- each weight must have an inverse
161/// weight (Assign has Assign; Reference has Dereference).
Hal Finkel7529c552014-09-02 21:43:13 +0000162enum class EdgeType {
George Burgess IVcae581d2016-04-13 23:27:37 +0000163 /// The weight assigned when assigning from or to a value. For example, in:
164 /// %b = getelementptr %a, 0
165 /// ...The relationships are %b assign %a, and %a assign %b. This used to be
166 /// two edges, but having a distinction bought us nothing.
Hal Finkel7529c552014-09-02 21:43:13 +0000167 Assign,
168
George Burgess IVcae581d2016-04-13 23:27:37 +0000169 /// The edge used when we have an edge going from some handle to a Value.
170 /// Examples of this include:
171 /// %b = load %a (%b Dereference %a)
172 /// %b = extractelement %a, 0 (%a Dereference %b)
Hal Finkel7529c552014-09-02 21:43:13 +0000173 Dereference,
174
George Burgess IVcae581d2016-04-13 23:27:37 +0000175 /// The edge used when our edge goes from a value to a handle that may have
176 /// contained it at some point. Examples:
177 /// %b = load %a (%a Reference %b)
178 /// %b = extractelement %a, 0 (%b Reference %a)
Hal Finkel7529c552014-09-02 21:43:13 +0000179 Reference
180};
181
George Burgess IV24eb0da2016-06-14 18:12:28 +0000182/// The Program Expression Graph (PEG) of CFL analysis
183class CFLGraph {
184 typedef Value *Node;
Hal Finkel7529c552014-09-02 21:43:13 +0000185
George Burgess IV24eb0da2016-06-14 18:12:28 +0000186 struct Edge {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000187 EdgeType Type;
188 Node Other;
189 };
Hal Finkel7529c552014-09-02 21:43:13 +0000190
George Burgess IV24eb0da2016-06-14 18:12:28 +0000191 typedef std::vector<Edge> EdgeList;
George Burgess IV259d9012016-06-15 20:43:41 +0000192
193 struct NodeInfo {
194 EdgeList Edges;
195 StratifiedAttrs Attr;
196 };
197
198 typedef DenseMap<Node, NodeInfo> NodeMap;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000199 NodeMap NodeImpls;
Hal Finkel7529c552014-09-02 21:43:13 +0000200
George Burgess IV24eb0da2016-06-14 18:12:28 +0000201 // Gets the inverse of a given EdgeType.
202 static EdgeType flipWeight(EdgeType Initial) {
203 switch (Initial) {
204 case EdgeType::Assign:
205 return EdgeType::Assign;
206 case EdgeType::Dereference:
207 return EdgeType::Reference;
208 case EdgeType::Reference:
209 return EdgeType::Dereference;
210 }
211 llvm_unreachable("Incomplete coverage of EdgeType enum");
212 }
Hal Finkel7529c552014-09-02 21:43:13 +0000213
George Burgess IV259d9012016-06-15 20:43:41 +0000214 const NodeInfo *getNode(Node N) const {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000215 auto Itr = NodeImpls.find(N);
216 if (Itr == NodeImpls.end())
217 return nullptr;
218 return &Itr->second;
219 }
George Burgess IV259d9012016-06-15 20:43:41 +0000220 NodeInfo *getNode(Node N) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000221 auto Itr = NodeImpls.find(N);
222 if (Itr == NodeImpls.end())
223 return nullptr;
224 return &Itr->second;
225 }
226
227 static Node nodeDeref(const NodeMap::value_type &P) { return P.first; }
228 typedef std::pointer_to_unary_function<const NodeMap::value_type &, Node>
229 NodeDerefFun;
230
231public:
232 typedef EdgeList::const_iterator const_edge_iterator;
233 typedef mapped_iterator<NodeMap::const_iterator, NodeDerefFun>
234 const_node_iterator;
235
236 bool addNode(Node N) {
George Burgess IV259d9012016-06-15 20:43:41 +0000237 return NodeImpls.insert(std::make_pair(N, NodeInfo{EdgeList(), AttrNone}))
238 .second;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000239 }
240
George Burgess IV259d9012016-06-15 20:43:41 +0000241 void addAttr(Node N, StratifiedAttrs Attr) {
242 auto *Info = getNode(N);
243 assert(Info != nullptr);
244 Info->Attr |= Attr;
245 }
George Burgess IV24eb0da2016-06-14 18:12:28 +0000246
George Burgess IV259d9012016-06-15 20:43:41 +0000247 void addEdge(Node From, Node To, EdgeType Type) {
248 auto *FromInfo = getNode(From);
249 assert(FromInfo != nullptr);
250 auto *ToInfo = getNode(To);
251 assert(ToInfo != nullptr);
252
253 FromInfo->Edges.push_back(Edge{Type, To});
254 ToInfo->Edges.push_back(Edge{flipWeight(Type), From});
255 }
256
257 StratifiedAttrs attrFor(Node N) const {
258 auto *Info = getNode(N);
259 assert(Info != nullptr);
260 return Info->Attr;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000261 }
262
263 iterator_range<const_edge_iterator> edgesFor(Node N) const {
George Burgess IV259d9012016-06-15 20:43:41 +0000264 auto *Info = getNode(N);
265 assert(Info != nullptr);
266 auto &Edges = Info->Edges;
267 return make_range(Edges.begin(), Edges.end());
George Burgess IV24eb0da2016-06-14 18:12:28 +0000268 }
269
270 iterator_range<const_node_iterator> nodes() const {
271 return make_range<const_node_iterator>(
272 map_iterator(NodeImpls.begin(), NodeDerefFun(nodeDeref)),
273 map_iterator(NodeImpls.end(), NodeDerefFun(nodeDeref)));
274 }
275
276 bool empty() const { return NodeImpls.empty(); }
277 std::size_t size() const { return NodeImpls.size(); }
Hal Finkel7529c552014-09-02 21:43:13 +0000278};
279
George Burgess IVa3d62be2016-06-24 01:00:03 +0000280// This is the result of instantiating InterfaceValue at a particular callsite
281struct InterprocNode {
282 Value *Val;
283 unsigned DerefLevel;
284};
285
George Burgess IV1f99da52016-06-23 18:55:23 +0000286// Interprocedural assignment edges that CFLGraph may not easily model
287struct InterprocEdge {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000288 InterprocNode From, To;
289};
George Burgess IV1f99da52016-06-23 18:55:23 +0000290
George Burgess IVa3d62be2016-06-24 01:00:03 +0000291// Interprocedural attribute tagging that CFLGraph may not easily model
292struct InterprocAttr {
293 InterprocNode Node;
294 StratifiedAttrs Attr;
George Burgess IV1f99da52016-06-23 18:55:23 +0000295};
296
George Burgess IVcae581d2016-04-13 23:27:37 +0000297/// Gets the edges our graph should have, based on an Instruction*
Hal Finkel7529c552014-09-02 21:43:13 +0000298class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
Chandler Carruth7b560d42015-09-09 17:55:00 +0000299 CFLAAResult &AA;
George Burgess IV18b83fe2016-06-01 18:39:54 +0000300 const TargetLibraryInfo &TLI;
Hal Finkel7529c552014-09-02 21:43:13 +0000301
George Burgess IV24eb0da2016-06-14 18:12:28 +0000302 CFLGraph &Graph;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000303 SmallVectorImpl<Value *> &ReturnValues;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000304 SmallPtrSetImpl<Value *> &Externals;
305 SmallPtrSetImpl<Value *> &Escapes;
George Burgess IV1f99da52016-06-23 18:55:23 +0000306 SmallVectorImpl<InterprocEdge> &InterprocEdges;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000307 SmallVectorImpl<InterprocAttr> &InterprocAttrs;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000308
309 static bool hasUsefulEdges(ConstantExpr *CE) {
310 // ConstantExpr doesn't have terminators, invokes, or fences, so only needs
311 // to check for compares.
312 return CE->getOpcode() != Instruction::ICmp &&
313 CE->getOpcode() != Instruction::FCmp;
314 }
315
316 void addNode(Value *Val) {
317 if (!Graph.addNode(Val))
318 return;
319
320 if (isa<GlobalValue>(Val))
321 Externals.insert(Val);
322 else if (auto CExpr = dyn_cast<ConstantExpr>(Val))
323 if (hasUsefulEdges(CExpr))
324 visitConstantExpr(CExpr);
325 }
326
George Burgess IV259d9012016-06-15 20:43:41 +0000327 void addNodeWithAttr(Value *Val, StratifiedAttrs Attr) {
328 addNode(Val);
329 Graph.addAttr(Val, Attr);
330 }
331
332 void addEdge(Value *From, Value *To, EdgeType Type) {
333 if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
334 return;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000335 addNode(From);
336 if (To != From)
337 addNode(To);
George Burgess IV259d9012016-06-15 20:43:41 +0000338 Graph.addEdge(From, To, Type);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000339 }
340
Hal Finkel7529c552014-09-02 21:43:13 +0000341public:
George Burgess IV24eb0da2016-06-14 18:12:28 +0000342 GetEdgesVisitor(CFLAAResult &AA, const TargetLibraryInfo &TLI,
George Burgess IVa3d62be2016-06-24 01:00:03 +0000343 CFLGraph &Graph, SmallVectorImpl<Value *> &ReturnValues,
344 SmallPtrSetImpl<Value *> &Externals,
George Burgess IV1f99da52016-06-23 18:55:23 +0000345 SmallPtrSetImpl<Value *> &Escapes,
George Burgess IVa3d62be2016-06-24 01:00:03 +0000346 SmallVectorImpl<InterprocEdge> &InterprocEdges,
347 SmallVectorImpl<InterprocAttr> &InterprocAttrs)
348 : AA(AA), TLI(TLI), Graph(Graph), ReturnValues(ReturnValues),
349 Externals(Externals), Escapes(Escapes), InterprocEdges(InterprocEdges),
350 InterprocAttrs(InterprocAttrs) {}
Hal Finkel7529c552014-09-02 21:43:13 +0000351
352 void visitInstruction(Instruction &) {
353 llvm_unreachable("Unsupported instruction encountered");
354 }
355
George Burgess IVa3d62be2016-06-24 01:00:03 +0000356 void visitReturnInst(ReturnInst &Inst) {
357 if (auto RetVal = Inst.getReturnValue()) {
358 if (RetVal->getType()->isPointerTy()) {
359 addNode(RetVal);
360 ReturnValues.push_back(RetVal);
361 }
362 }
363 }
364
George Burgess IVb54a8d622015-03-10 02:40:06 +0000365 void visitPtrToIntInst(PtrToIntInst &Inst) {
366 auto *Ptr = Inst.getOperand(0);
George Burgess IV259d9012016-06-15 20:43:41 +0000367 addNodeWithAttr(Ptr, AttrEscaped);
George Burgess IVb54a8d622015-03-10 02:40:06 +0000368 }
369
370 void visitIntToPtrInst(IntToPtrInst &Inst) {
371 auto *Ptr = &Inst;
George Burgess IV259d9012016-06-15 20:43:41 +0000372 addNodeWithAttr(Ptr, AttrUnknown);
George Burgess IVb54a8d622015-03-10 02:40:06 +0000373 }
374
Hal Finkel7529c552014-09-02 21:43:13 +0000375 void visitCastInst(CastInst &Inst) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000376 auto *Src = Inst.getOperand(0);
George Burgess IV259d9012016-06-15 20:43:41 +0000377 addEdge(Src, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000378 }
379
380 void visitBinaryOperator(BinaryOperator &Inst) {
381 auto *Op1 = Inst.getOperand(0);
382 auto *Op2 = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000383 addEdge(Op1, &Inst, EdgeType::Assign);
384 addEdge(Op2, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000385 }
386
387 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
388 auto *Ptr = Inst.getPointerOperand();
389 auto *Val = Inst.getNewValOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000390 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000391 }
392
393 void visitAtomicRMWInst(AtomicRMWInst &Inst) {
394 auto *Ptr = Inst.getPointerOperand();
395 auto *Val = Inst.getValOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000396 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000397 }
398
399 void visitPHINode(PHINode &Inst) {
George Burgess IV77351ba32016-01-28 00:54:01 +0000400 for (Value *Val : Inst.incoming_values())
George Burgess IV259d9012016-06-15 20:43:41 +0000401 addEdge(Val, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000402 }
403
404 void visitGetElementPtrInst(GetElementPtrInst &Inst) {
405 auto *Op = Inst.getPointerOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000406 addEdge(Op, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000407 }
408
409 void visitSelectInst(SelectInst &Inst) {
Daniel Berlin16f7a522015-01-26 17:31:17 +0000410 // Condition is not processed here (The actual statement producing
411 // the condition result is processed elsewhere). For select, the
412 // condition is evaluated, but not loaded, stored, or assigned
413 // simply as a result of being the condition of a select.
414
Hal Finkel7529c552014-09-02 21:43:13 +0000415 auto *TrueVal = Inst.getTrueValue();
Hal Finkel7529c552014-09-02 21:43:13 +0000416 auto *FalseVal = Inst.getFalseValue();
George Burgess IV259d9012016-06-15 20:43:41 +0000417 addEdge(TrueVal, &Inst, EdgeType::Assign);
418 addEdge(FalseVal, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000419 }
420
George Burgess IV24eb0da2016-06-14 18:12:28 +0000421 void visitAllocaInst(AllocaInst &Inst) { Graph.addNode(&Inst); }
Hal Finkel7529c552014-09-02 21:43:13 +0000422
423 void visitLoadInst(LoadInst &Inst) {
424 auto *Ptr = Inst.getPointerOperand();
425 auto *Val = &Inst;
George Burgess IV259d9012016-06-15 20:43:41 +0000426 addEdge(Val, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000427 }
428
429 void visitStoreInst(StoreInst &Inst) {
430 auto *Ptr = Inst.getPointerOperand();
431 auto *Val = Inst.getValueOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000432 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000433 }
434
Hal Finkeldb5f86a2014-10-14 20:51:26 +0000435 void visitVAArgInst(VAArgInst &Inst) {
436 // We can't fully model va_arg here. For *Ptr = Inst.getOperand(0), it does
437 // two things:
438 // 1. Loads a value from *((T*)*Ptr).
439 // 2. Increments (stores to) *Ptr by some target-specific amount.
440 // For now, we'll handle this like a landingpad instruction (by placing the
441 // result in its own group, and having that group alias externals).
George Burgess IV259d9012016-06-15 20:43:41 +0000442 addNodeWithAttr(&Inst, AttrUnknown);
Hal Finkeldb5f86a2014-10-14 20:51:26 +0000443 }
444
Hal Finkel7529c552014-09-02 21:43:13 +0000445 static bool isFunctionExternal(Function *Fn) {
George Burgess IV9fdbfe12016-06-21 01:42:47 +0000446 return !Fn->hasExactDefinition();
Hal Finkel7529c552014-09-02 21:43:13 +0000447 }
448
George Burgess IV87b2e412016-06-20 23:10:56 +0000449 bool tryInterproceduralAnalysis(CallSite CS,
450 const SmallVectorImpl<Function *> &Fns) {
Hal Finkel7529c552014-09-02 21:43:13 +0000451 assert(Fns.size() > 0);
452
George Burgess IV87b2e412016-06-20 23:10:56 +0000453 if (CS.arg_size() > MaxSupportedArgsInSummary)
Hal Finkel7529c552014-09-02 21:43:13 +0000454 return false;
455
456 // Exit early if we'll fail anyway
457 for (auto *Fn : Fns) {
458 if (isFunctionExternal(Fn) || Fn->isVarArg())
459 return false;
George Burgess IV87b2e412016-06-20 23:10:56 +0000460 // Fail if the caller does not provide enough arguments
461 assert(Fn->arg_size() <= CS.arg_size());
Hal Finkel7529c552014-09-02 21:43:13 +0000462 auto &MaybeInfo = AA.ensureCached(Fn);
463 if (!MaybeInfo.hasValue())
464 return false;
465 }
466
George Burgess IVa3d62be2016-06-24 01:00:03 +0000467 auto InstantiateInterfaceIndex = [&CS](unsigned Index) {
468 auto Value =
469 (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
470 return Value->getType()->isPointerTy() ? Value : nullptr;
471 };
472
Hal Finkel7529c552014-09-02 21:43:13 +0000473 for (auto *Fn : Fns) {
George Burgess IV87b2e412016-06-20 23:10:56 +0000474 auto &FnInfo = AA.ensureCached(Fn);
475 assert(FnInfo.hasValue());
Hal Finkel7529c552014-09-02 21:43:13 +0000476
George Burgess IV87b2e412016-06-20 23:10:56 +0000477 auto &RetParamRelations = FnInfo->getRetParamRelations();
478 for (auto &Relation : RetParamRelations) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000479 auto FromVal = InstantiateInterfaceIndex(Relation.From.Index);
480 auto ToVal = InstantiateInterfaceIndex(Relation.To.Index);
481 if (FromVal && ToVal) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000482 auto FromLevel = Relation.From.DerefLevel;
483 auto ToLevel = Relation.To.DerefLevel;
484 InterprocEdges.push_back(
George Burgess IVa3d62be2016-06-24 01:00:03 +0000485 InterprocEdge{InterprocNode{FromVal, FromLevel},
486 InterprocNode{ToVal, ToLevel}});
487 }
488 }
489
490 auto &RetParamAttributes = FnInfo->getRetParamAttributes();
491 for (auto &Attribute : RetParamAttributes) {
492 if (auto Val = InstantiateInterfaceIndex(Attribute.IValue.Index)) {
493 InterprocAttrs.push_back(InterprocAttr{
494 InterprocNode{Val, Attribute.IValue.DerefLevel}, Attribute.Attr});
George Burgess IV1f99da52016-06-23 18:55:23 +0000495 }
Hal Finkel7529c552014-09-02 21:43:13 +0000496 }
George Burgess IV259d9012016-06-15 20:43:41 +0000497 }
George Burgess IV24eb0da2016-06-14 18:12:28 +0000498
Hal Finkel7529c552014-09-02 21:43:13 +0000499 return true;
500 }
501
George Burgess IV24eb0da2016-06-14 18:12:28 +0000502 void visitCallSite(CallSite CS) {
503 auto Inst = CS.getInstruction();
504
505 // Make sure all arguments and return value are added to the graph first
506 for (Value *V : CS.args())
507 addNode(V);
George Burgess IV87b2e412016-06-20 23:10:56 +0000508 if (Inst->getType()->isPointerTy())
George Burgess IV24eb0da2016-06-14 18:12:28 +0000509 addNode(Inst);
510
George Burgess IV18b83fe2016-06-01 18:39:54 +0000511 // Check if Inst is a call to a library function that allocates/deallocates
512 // on the heap. Those kinds of functions do not introduce any aliases.
513 // TODO: address other common library functions such as realloc(), strdup(),
514 // etc.
George Burgess IV24eb0da2016-06-14 18:12:28 +0000515 if (isMallocLikeFn(Inst, &TLI) || isCallocLikeFn(Inst, &TLI) ||
516 isFreeCall(Inst, &TLI))
George Burgess IV18b83fe2016-06-01 18:39:54 +0000517 return;
George Burgess IV18b83fe2016-06-01 18:39:54 +0000518
George Burgess IV68b36e02015-08-28 00:16:18 +0000519 // TODO: Add support for noalias args/all the other fun function attributes
520 // that we can tack on.
Hal Finkel7529c552014-09-02 21:43:13 +0000521 SmallVector<Function *, 4> Targets;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000522 if (getPossibleTargets(CS, Targets))
George Burgess IV87b2e412016-06-20 23:10:56 +0000523 if (tryInterproceduralAnalysis(CS, Targets))
Hal Finkel7529c552014-09-02 21:43:13 +0000524 return;
Hal Finkel7529c552014-09-02 21:43:13 +0000525
George Burgess IV68b36e02015-08-28 00:16:18 +0000526 // Because the function is opaque, we need to note that anything
George Burgess IV24eb0da2016-06-14 18:12:28 +0000527 // could have happened to the arguments (unless the function is marked
528 // readonly or readnone), and that the result could alias just about
529 // anything, too (unless the result is marked noalias).
530 if (!CS.onlyReadsMemory())
531 for (Value *V : CS.args()) {
George Burgess IV259d9012016-06-15 20:43:41 +0000532 if (V->getType()->isPointerTy())
533 Escapes.insert(V);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000534 }
535
George Burgess IV87b2e412016-06-20 23:10:56 +0000536 if (Inst->getType()->isPointerTy()) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000537 auto *Fn = CS.getCalledFunction();
538 if (Fn == nullptr || !Fn->doesNotAlias(0))
George Burgess IV259d9012016-06-15 20:43:41 +0000539 Graph.addAttr(Inst, AttrUnknown);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000540 }
Hal Finkel7529c552014-09-02 21:43:13 +0000541 }
542
George Burgess IVcae581d2016-04-13 23:27:37 +0000543 /// Because vectors/aggregates are immutable and unaddressable, there's
544 /// nothing we can do to coax a value out of them, other than calling
545 /// Extract{Element,Value}. We can effectively treat them as pointers to
546 /// arbitrary memory locations we can store in and load from.
Hal Finkel7529c552014-09-02 21:43:13 +0000547 void visitExtractElementInst(ExtractElementInst &Inst) {
548 auto *Ptr = Inst.getVectorOperand();
549 auto *Val = &Inst;
George Burgess IV259d9012016-06-15 20:43:41 +0000550 addEdge(Val, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000551 }
552
553 void visitInsertElementInst(InsertElementInst &Inst) {
554 auto *Vec = Inst.getOperand(0);
555 auto *Val = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000556 addEdge(Vec, &Inst, EdgeType::Assign);
557 addEdge(&Inst, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000558 }
559
560 void visitLandingPadInst(LandingPadInst &Inst) {
561 // Exceptions come from "nowhere", from our analysis' perspective.
562 // So we place the instruction its own group, noting that said group may
563 // alias externals
George Burgess IV259d9012016-06-15 20:43:41 +0000564 addNodeWithAttr(&Inst, AttrUnknown);
Hal Finkel7529c552014-09-02 21:43:13 +0000565 }
566
567 void visitInsertValueInst(InsertValueInst &Inst) {
568 auto *Agg = Inst.getOperand(0);
569 auto *Val = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000570 addEdge(Agg, &Inst, EdgeType::Assign);
571 addEdge(&Inst, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000572 }
573
574 void visitExtractValueInst(ExtractValueInst &Inst) {
575 auto *Ptr = Inst.getAggregateOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000576 addEdge(&Inst, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000577 }
578
579 void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
580 auto *From1 = Inst.getOperand(0);
581 auto *From2 = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000582 addEdge(From1, &Inst, EdgeType::Assign);
583 addEdge(From2, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000584 }
Pete Cooper36642532015-06-12 16:13:54 +0000585
586 void visitConstantExpr(ConstantExpr *CE) {
587 switch (CE->getOpcode()) {
588 default:
589 llvm_unreachable("Unknown instruction type encountered!");
590// Build the switch statement using the Instruction.def file.
591#define HANDLE_INST(NUM, OPCODE, CLASS) \
592 case Instruction::OPCODE: \
593 visit##OPCODE(*(CLASS *)CE); \
594 break;
595#include "llvm/IR/Instruction.def"
596 }
597 }
Hal Finkel7529c552014-09-02 21:43:13 +0000598};
599
George Burgess IVe17756e2016-06-14 18:02:27 +0000600class CFLGraphBuilder {
601 // Input of the builder
602 CFLAAResult &Analysis;
603 const TargetLibraryInfo &TLI;
604
605 // Output of the builder
606 CFLGraph Graph;
607 SmallVector<Value *, 4> ReturnedValues;
608
609 // Auxiliary structures used by the builder
George Burgess IV24eb0da2016-06-14 18:12:28 +0000610 SmallPtrSet<Value *, 8> ExternalValues;
611 SmallPtrSet<Value *, 8> EscapedValues;
George Burgess IV1f99da52016-06-23 18:55:23 +0000612 SmallVector<InterprocEdge, 8> InterprocEdges;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000613 SmallVector<InterprocAttr, 8> InterprocAttrs;
George Burgess IVe17756e2016-06-14 18:02:27 +0000614
615 // Helper functions
616
617 // Determines whether or not we an instruction is useless to us (e.g.
618 // FenceInst)
619 static bool hasUsefulEdges(Instruction *Inst) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000620 bool IsNonInvokeRetTerminator = isa<TerminatorInst>(Inst) &&
621 !isa<InvokeInst>(Inst) &&
622 !isa<ReturnInst>(Inst);
George Burgess IVe17756e2016-06-14 18:02:27 +0000623 return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) &&
George Burgess IVa3d62be2016-06-24 01:00:03 +0000624 !IsNonInvokeRetTerminator;
George Burgess IVe17756e2016-06-14 18:02:27 +0000625 }
626
George Burgess IV24eb0da2016-06-14 18:12:28 +0000627 void addArgumentToGraph(Argument &Arg) {
George Burgess IV259d9012016-06-15 20:43:41 +0000628 if (Arg.getType()->isPointerTy()) {
629 Graph.addNode(&Arg);
630 ExternalValues.insert(&Arg);
631 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000632 }
633
634 // Given an Instruction, this will add it to the graph, along with any
635 // Instructions that are potentially only available from said Instruction
636 // For example, given the following line:
637 // %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
638 // addInstructionToGraph would add both the `load` and `getelementptr`
639 // instructions to the graph appropriately.
640 void addInstructionToGraph(Instruction &Inst) {
George Burgess IVe17756e2016-06-14 18:02:27 +0000641 if (!hasUsefulEdges(&Inst))
642 return;
643
George Burgess IVa3d62be2016-06-24 01:00:03 +0000644 GetEdgesVisitor(Analysis, TLI, Graph, ReturnedValues, ExternalValues,
645 EscapedValues, InterprocEdges, InterprocAttrs)
George Burgess IV24eb0da2016-06-14 18:12:28 +0000646 .visit(Inst);
647 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000648
George Burgess IV24eb0da2016-06-14 18:12:28 +0000649 // Builds the graph needed for constructing the StratifiedSets for the given
650 // function
651 void buildGraphFrom(Function &Fn) {
652 for (auto &Bb : Fn.getBasicBlockList())
653 for (auto &Inst : Bb.getInstList())
654 addInstructionToGraph(Inst);
George Burgess IVe17756e2016-06-14 18:02:27 +0000655
George Burgess IV24eb0da2016-06-14 18:12:28 +0000656 for (auto &Arg : Fn.args())
657 addArgumentToGraph(Arg);
George Burgess IVe17756e2016-06-14 18:02:27 +0000658 }
659
660public:
661 CFLGraphBuilder(CFLAAResult &Analysis, const TargetLibraryInfo &TLI,
662 Function &Fn)
663 : Analysis(Analysis), TLI(TLI) {
664 buildGraphFrom(Fn);
665 }
666
George Burgess IV87b2e412016-06-20 23:10:56 +0000667 const CFLGraph &getCFLGraph() const { return Graph; }
668 const SmallVector<Value *, 4> &getReturnValues() const {
669 return ReturnedValues;
George Burgess IVe17756e2016-06-14 18:02:27 +0000670 }
George Burgess IV87b2e412016-06-20 23:10:56 +0000671 const SmallPtrSet<Value *, 8> &getExternalValues() const {
672 return ExternalValues;
673 }
674 const SmallPtrSet<Value *, 8> &getEscapedValues() const {
675 return EscapedValues;
676 }
George Burgess IV1f99da52016-06-23 18:55:23 +0000677 const SmallVector<InterprocEdge, 8> &getInterprocEdges() const {
678 return InterprocEdges;
679 }
George Burgess IVa3d62be2016-06-24 01:00:03 +0000680 const SmallVector<InterprocAttr, 8> &getInterprocAttrs() const {
681 return InterprocAttrs;
682 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000683};
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000684}
Hal Finkel7529c552014-09-02 21:43:13 +0000685
Hal Finkel7529c552014-09-02 21:43:13 +0000686//===----------------------------------------------------------------------===//
687// Function declarations that require types defined in the namespace above
688//===----------------------------------------------------------------------===//
689
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000690/// Given a StratifiedAttrs, returns true if it marks the corresponding values
691/// as globals or arguments
692static bool isGlobalOrArgAttr(StratifiedAttrs Attr);
Hal Finkel7529c552014-09-02 21:43:13 +0000693
George Burgess IV652ec4f2016-06-09 23:15:04 +0000694/// Given a StratifiedAttrs, returns true if the corresponding values come from
695/// an unknown source (such as opaque memory or an integer cast)
696static bool isUnknownAttr(StratifiedAttrs Attr);
697
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000698/// Given an argument number, returns the appropriate StratifiedAttr to set.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000699static StratifiedAttrs argNumberToAttr(unsigned ArgNum);
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000700
701/// Given a Value, potentially return which StratifiedAttr it maps to.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000702static Optional<StratifiedAttrs> valueToAttr(Value *Val);
Hal Finkel7529c552014-09-02 21:43:13 +0000703
George Burgess IVcae581d2016-04-13 23:27:37 +0000704/// Gets the "Level" that one should travel in StratifiedSets
705/// given an EdgeType.
Hal Finkel7529c552014-09-02 21:43:13 +0000706static Level directionOfEdgeType(EdgeType);
707
George Burgess IVcae581d2016-04-13 23:27:37 +0000708/// Determines whether it would be pointless to add the given Value to our sets.
George Burgess IVab03af22015-03-10 02:58:15 +0000709static bool canSkipAddingToSets(Value *Val);
710
Hal Finkel7529c552014-09-02 21:43:13 +0000711static Optional<Function *> parentFunctionOfValue(Value *Val) {
712 if (auto *Inst = dyn_cast<Instruction>(Val)) {
713 auto *Bb = Inst->getParent();
714 return Bb->getParent();
715 }
716
717 if (auto *Arg = dyn_cast<Argument>(Val))
718 return Arg->getParent();
George Burgess IV77351ba32016-01-28 00:54:01 +0000719 return None;
Hal Finkel7529c552014-09-02 21:43:13 +0000720}
721
George Burgess IV24eb0da2016-06-14 18:12:28 +0000722static bool getPossibleTargets(CallSite CS,
Hal Finkel7529c552014-09-02 21:43:13 +0000723 SmallVectorImpl<Function *> &Output) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000724 if (auto *Fn = CS.getCalledFunction()) {
Hal Finkel7529c552014-09-02 21:43:13 +0000725 Output.push_back(Fn);
726 return true;
727 }
728
729 // TODO: If the call is indirect, we might be able to enumerate all potential
730 // targets of the call and return them, rather than just failing.
731 return false;
732}
733
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000734static bool isGlobalOrArgAttr(StratifiedAttrs Attr) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000735 return Attr.reset(AttrEscapedIndex)
736 .reset(AttrUnknownIndex)
737 .reset(AttrCallerIndex)
738 .any();
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000739}
740
George Burgess IV652ec4f2016-06-09 23:15:04 +0000741static bool isUnknownAttr(StratifiedAttrs Attr) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000742 return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
George Burgess IV652ec4f2016-06-09 23:15:04 +0000743}
744
George Burgess IVa3d62be2016-06-24 01:00:03 +0000745static Optional<StratifiedAttrs> valueToAttr(Value *Val) {
Hal Finkel7529c552014-09-02 21:43:13 +0000746 if (isa<GlobalValue>(Val))
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000747 return AttrGlobal;
Hal Finkel7529c552014-09-02 21:43:13 +0000748
749 if (auto *Arg = dyn_cast<Argument>(Val))
Daniel Berlin16f7a522015-01-26 17:31:17 +0000750 // Only pointer arguments should have the argument attribute,
751 // because things can't escape through scalars without us seeing a
752 // cast, and thus, interaction with them doesn't matter.
753 if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000754 return argNumberToAttr(Arg->getArgNo());
George Burgess IV77351ba32016-01-28 00:54:01 +0000755 return None;
Hal Finkel7529c552014-09-02 21:43:13 +0000756}
757
George Burgess IVa3d62be2016-06-24 01:00:03 +0000758static StratifiedAttrs argNumberToAttr(unsigned ArgNum) {
George Burgess IV3c898c22015-01-21 16:37:21 +0000759 if (ArgNum >= AttrMaxNumArgs)
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000760 return AttrUnknown;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000761 return StratifiedAttrs(1 << (ArgNum + AttrFirstArgIndex));
Hal Finkel7529c552014-09-02 21:43:13 +0000762}
763
Hal Finkel7529c552014-09-02 21:43:13 +0000764static Level directionOfEdgeType(EdgeType Weight) {
765 switch (Weight) {
766 case EdgeType::Reference:
767 return Level::Above;
768 case EdgeType::Dereference:
769 return Level::Below;
770 case EdgeType::Assign:
771 return Level::Same;
772 }
773 llvm_unreachable("Incomplete switch coverage");
774}
775
George Burgess IVab03af22015-03-10 02:58:15 +0000776static bool canSkipAddingToSets(Value *Val) {
777 // Constants can share instances, which may falsely unify multiple
778 // sets, e.g. in
779 // store i32* null, i32** %ptr1
780 // store i32* null, i32** %ptr2
781 // clearly ptr1 and ptr2 should not be unified into the same set, so
782 // we should filter out the (potentially shared) instance to
783 // i32* null.
784 if (isa<Constant>(Val)) {
George Burgess IVab03af22015-03-10 02:58:15 +0000785 // TODO: Because all of these things are constant, we can determine whether
786 // the data is *actually* mutable at graph building time. This will probably
787 // come for free/cheap with offset awareness.
Duncan P. N. Exon Smith1de3c7e2016-04-05 21:10:45 +0000788 bool CanStoreMutableData = isa<GlobalValue>(Val) ||
789 isa<ConstantExpr>(Val) ||
790 isa<ConstantAggregate>(Val);
George Burgess IVab03af22015-03-10 02:58:15 +0000791 return !CanStoreMutableData;
792 }
793
794 return false;
Hal Finkel7529c552014-09-02 21:43:13 +0000795}
796
George Burgess IV87b2e412016-06-20 23:10:56 +0000797CFLAAResult::FunctionInfo::FunctionInfo(Function &Fn,
798 const SmallVectorImpl<Value *> &RetVals,
799 StratifiedSets<Value *> S)
800 : Sets(std::move(S)) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000801 // Historically, an arbitrary upper-bound of 50 args was selected. We may want
802 // to remove this if it doesn't really matter in practice.
803 if (Fn.arg_size() > MaxSupportedArgsInSummary)
804 return;
George Burgess IV87b2e412016-06-20 23:10:56 +0000805
George Burgess IV1f99da52016-06-23 18:55:23 +0000806 DenseMap<StratifiedIndex, InterfaceValue> InterfaceMap;
George Burgess IV87b2e412016-06-20 23:10:56 +0000807
George Burgess IV1f99da52016-06-23 18:55:23 +0000808 // Our intention here is to record all InterfaceValues that share the same
809 // StratifiedIndex in RetParamRelations. For each valid InterfaceValue, we
810 // have its StratifiedIndex scanned here and check if the index is presented
811 // in InterfaceMap: if it is not, we add the correspondence to the map;
812 // otherwise, an aliasing relation is found and we add it to
813 // RetParamRelations.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000814
George Burgess IVd14d05a2016-06-23 20:59:13 +0000815 auto AddToRetParamRelations = [&](unsigned InterfaceIndex,
816 StratifiedIndex SetIndex) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000817 unsigned Level = 0;
818 while (true) {
819 InterfaceValue CurrValue{InterfaceIndex, Level};
George Burgess IV87b2e412016-06-20 23:10:56 +0000820
George Burgess IV1f99da52016-06-23 18:55:23 +0000821 auto Itr = InterfaceMap.find(SetIndex);
822 if (Itr != InterfaceMap.end()) {
823 if (CurrValue != Itr->second)
824 RetParamRelations.push_back(ExternalRelation{CurrValue, Itr->second});
825 break;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000826 }
George Burgess IV87b2e412016-06-20 23:10:56 +0000827
George Burgess IV1f99da52016-06-23 18:55:23 +0000828 auto &Link = Sets.getLink(SetIndex);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000829 InterfaceMap.insert(std::make_pair(SetIndex, CurrValue));
830 auto ExternalAttrs = Link.Attrs & ExternalAttrMask;
831 if (ExternalAttrs.any())
832 RetParamAttributes.push_back(
833 ExternalAttribute{CurrValue, ExternalAttrs});
834
George Burgess IV1f99da52016-06-23 18:55:23 +0000835 if (!Link.hasBelow())
836 break;
George Burgess IV87b2e412016-06-20 23:10:56 +0000837
George Burgess IV1f99da52016-06-23 18:55:23 +0000838 ++Level;
839 SetIndex = Link.Below;
George Burgess IV87b2e412016-06-20 23:10:56 +0000840 }
George Burgess IV1f99da52016-06-23 18:55:23 +0000841 };
842
843 // Populate RetParamRelations for return values
844 for (auto *RetVal : RetVals) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000845 assert(RetVal != nullptr);
846 assert(RetVal->getType()->isPointerTy());
George Burgess IV1f99da52016-06-23 18:55:23 +0000847 auto RetInfo = Sets.find(RetVal);
848 if (RetInfo.hasValue())
849 AddToRetParamRelations(0, RetInfo->Index);
850 }
851
852 // Populate RetParamRelations for parameters
853 unsigned I = 0;
854 for (auto &Param : Fn.args()) {
855 if (Param.getType()->isPointerTy()) {
856 auto ParamInfo = Sets.find(&Param);
857 if (ParamInfo.hasValue())
858 AddToRetParamRelations(I + 1, ParamInfo->Index);
859 }
860 ++I;
George Burgess IV87b2e412016-06-20 23:10:56 +0000861 }
862}
863
Chandler Carruth8b046a42015-08-14 02:42:20 +0000864// Builds the graph + StratifiedSets for a function.
Chandler Carruth7b560d42015-09-09 17:55:00 +0000865CFLAAResult::FunctionInfo CFLAAResult::buildSetsFrom(Function *Fn) {
George Burgess IVe17756e2016-06-14 18:02:27 +0000866 CFLGraphBuilder GraphBuilder(*this, TLI, *Fn);
867 StratifiedSetsBuilder<Value *> SetBuilder;
Hal Finkel7529c552014-09-02 21:43:13 +0000868
George Burgess IVe17756e2016-06-14 18:02:27 +0000869 auto &Graph = GraphBuilder.getCFLGraph();
George Burgess IVdc96feb2016-06-13 19:21:18 +0000870 SmallVector<Value *, 16> Worklist;
George Burgess IVdc96feb2016-06-13 19:21:18 +0000871 for (auto Node : Graph.nodes())
872 Worklist.push_back(Node);
873
874 while (!Worklist.empty()) {
875 auto *CurValue = Worklist.pop_back_val();
George Burgess IVe17756e2016-06-14 18:02:27 +0000876 SetBuilder.add(CurValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000877 if (canSkipAddingToSets(CurValue))
878 continue;
879
George Burgess IV259d9012016-06-15 20:43:41 +0000880 auto Attr = Graph.attrFor(CurValue);
881 SetBuilder.noteAttributes(CurValue, Attr);
882
George Burgess IVdc96feb2016-06-13 19:21:18 +0000883 for (const auto &Edge : Graph.edgesFor(CurValue)) {
884 auto Label = Edge.Type;
885 auto *OtherValue = Edge.Other;
886
887 if (canSkipAddingToSets(OtherValue))
Hal Finkel7529c552014-09-02 21:43:13 +0000888 continue;
889
George Burgess IVdc96feb2016-06-13 19:21:18 +0000890 bool Added;
891 switch (directionOfEdgeType(Label)) {
892 case Level::Above:
George Burgess IVe17756e2016-06-14 18:02:27 +0000893 Added = SetBuilder.addAbove(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000894 break;
895 case Level::Below:
George Burgess IVe17756e2016-06-14 18:02:27 +0000896 Added = SetBuilder.addBelow(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000897 break;
898 case Level::Same:
George Burgess IVe17756e2016-06-14 18:02:27 +0000899 Added = SetBuilder.addWith(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000900 break;
Hal Finkel7529c552014-09-02 21:43:13 +0000901 }
George Burgess IVdc96feb2016-06-13 19:21:18 +0000902
George Burgess IVdc96feb2016-06-13 19:21:18 +0000903 if (Added)
904 Worklist.push_back(OtherValue);
Hal Finkel7529c552014-09-02 21:43:13 +0000905 }
906 }
907
George Burgess IV652ec4f2016-06-09 23:15:04 +0000908 // Special handling for globals and arguments
George Burgess IV24eb0da2016-06-14 18:12:28 +0000909 for (auto *External : GraphBuilder.getExternalValues()) {
910 SetBuilder.add(External);
911 auto Attr = valueToAttr(External);
George Burgess IV652ec4f2016-06-09 23:15:04 +0000912 if (Attr.hasValue()) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000913 SetBuilder.noteAttributes(External, *Attr);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000914 if (*Attr == AttrGlobal)
915 SetBuilder.addAttributesBelow(External, 1, AttrUnknown);
916 else
917 SetBuilder.addAttributesBelow(External, 1, AttrCaller);
George Burgess IV652ec4f2016-06-09 23:15:04 +0000918 }
George Burgess IV24eb0da2016-06-14 18:12:28 +0000919 }
George Burgess IVab03af22015-03-10 02:58:15 +0000920
George Burgess IV1f99da52016-06-23 18:55:23 +0000921 // Special handling for interprocedural aliases
922 for (auto &Edge : GraphBuilder.getInterprocEdges()) {
George Burgess IVfe1397b2016-06-23 19:16:04 +0000923 auto FromVal = Edge.From.Val;
924 auto ToVal = Edge.To.Val;
George Burgess IV1f99da52016-06-23 18:55:23 +0000925 SetBuilder.add(FromVal);
926 SetBuilder.add(ToVal);
927 SetBuilder.addBelowWith(FromVal, Edge.From.DerefLevel, ToVal,
928 Edge.To.DerefLevel);
929 }
930
George Burgess IVa3d62be2016-06-24 01:00:03 +0000931 // Special handling for interprocedural attributes
932 for (auto &IPAttr : GraphBuilder.getInterprocAttrs()) {
933 auto Val = IPAttr.Node.Val;
934 SetBuilder.add(Val);
935 SetBuilder.addAttributesBelow(Val, IPAttr.Node.DerefLevel, IPAttr.Attr);
936 }
937
George Burgess IV1f99da52016-06-23 18:55:23 +0000938 // Special handling for opaque external functions
George Burgess IV24eb0da2016-06-14 18:12:28 +0000939 for (auto *Escape : GraphBuilder.getEscapedValues()) {
940 SetBuilder.add(Escape);
941 SetBuilder.noteAttributes(Escape, AttrEscaped);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000942 SetBuilder.addAttributesBelow(Escape, 1, AttrUnknown);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000943 }
Hal Finkel7529c552014-09-02 21:43:13 +0000944
George Burgess IV87b2e412016-06-20 23:10:56 +0000945 return FunctionInfo(*Fn, GraphBuilder.getReturnValues(), SetBuilder.build());
Hal Finkel7529c552014-09-02 21:43:13 +0000946}
947
Chandler Carruth7b560d42015-09-09 17:55:00 +0000948void CFLAAResult::scan(Function *Fn) {
Hal Finkel8d1590d2014-09-02 22:52:30 +0000949 auto InsertPair = Cache.insert(std::make_pair(Fn, Optional<FunctionInfo>()));
Hal Finkel7529c552014-09-02 21:43:13 +0000950 (void)InsertPair;
951 assert(InsertPair.second &&
952 "Trying to scan a function that has already been cached");
953
George Burgess IV6edb8912016-05-02 18:09:19 +0000954 // Note that we can't do Cache[Fn] = buildSetsFrom(Fn) here: the function call
955 // may get evaluated after operator[], potentially triggering a DenseMap
956 // resize and invalidating the reference returned by operator[]
957 auto FunInfo = buildSetsFrom(Fn);
958 Cache[Fn] = std::move(FunInfo);
959
Hal Finkel7529c552014-09-02 21:43:13 +0000960 Handles.push_front(FunctionHandle(Fn, this));
961}
962
Chandler Carruth7b560d42015-09-09 17:55:00 +0000963void CFLAAResult::evict(Function *Fn) { Cache.erase(Fn); }
Chandler Carruth8b046a42015-08-14 02:42:20 +0000964
George Burgess IVcae581d2016-04-13 23:27:37 +0000965/// Ensures that the given function is available in the cache, and returns the
966/// entry.
Chandler Carruth7b560d42015-09-09 17:55:00 +0000967const Optional<CFLAAResult::FunctionInfo> &
968CFLAAResult::ensureCached(Function *Fn) {
Chandler Carruth8b046a42015-08-14 02:42:20 +0000969 auto Iter = Cache.find(Fn);
970 if (Iter == Cache.end()) {
971 scan(Fn);
972 Iter = Cache.find(Fn);
973 assert(Iter != Cache.end());
974 assert(Iter->second.hasValue());
975 }
976 return Iter->second;
977}
978
Chandler Carruth7b560d42015-09-09 17:55:00 +0000979AliasResult CFLAAResult::query(const MemoryLocation &LocA,
980 const MemoryLocation &LocB) {
Hal Finkel7529c552014-09-02 21:43:13 +0000981 auto *ValA = const_cast<Value *>(LocA.Ptr);
982 auto *ValB = const_cast<Value *>(LocB.Ptr);
983
George Burgess IV259d9012016-06-15 20:43:41 +0000984 if (!ValA->getType()->isPointerTy() || !ValB->getType()->isPointerTy())
985 return NoAlias;
986
Hal Finkel7529c552014-09-02 21:43:13 +0000987 Function *Fn = nullptr;
988 auto MaybeFnA = parentFunctionOfValue(ValA);
989 auto MaybeFnB = parentFunctionOfValue(ValB);
990 if (!MaybeFnA.hasValue() && !MaybeFnB.hasValue()) {
George Burgess IVcae581d2016-04-13 23:27:37 +0000991 // The only times this is known to happen are when globals + InlineAsm are
992 // involved
George Burgess IV33305e72015-02-12 03:07:07 +0000993 DEBUG(dbgs() << "CFLAA: could not extract parent function information.\n");
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000994 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000995 }
996
997 if (MaybeFnA.hasValue()) {
998 Fn = *MaybeFnA;
999 assert((!MaybeFnB.hasValue() || *MaybeFnB == *MaybeFnA) &&
1000 "Interprocedural queries not supported");
1001 } else {
1002 Fn = *MaybeFnB;
1003 }
1004
1005 assert(Fn != nullptr);
1006 auto &MaybeInfo = ensureCached(Fn);
1007 assert(MaybeInfo.hasValue());
1008
George Burgess IV87b2e412016-06-20 23:10:56 +00001009 auto &Sets = MaybeInfo->getStratifiedSets();
Hal Finkel7529c552014-09-02 21:43:13 +00001010 auto MaybeA = Sets.find(ValA);
1011 if (!MaybeA.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +00001012 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +00001013
1014 auto MaybeB = Sets.find(ValB);
1015 if (!MaybeB.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +00001016 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +00001017
1018 auto SetA = *MaybeA;
1019 auto SetB = *MaybeB;
Hal Finkel7529c552014-09-02 21:43:13 +00001020 auto AttrsA = Sets.getLink(SetA.Index).Attrs;
1021 auto AttrsB = Sets.getLink(SetB.Index).Attrs;
George Burgess IV33305e72015-02-12 03:07:07 +00001022
George Burgess IVa1f9a2d2016-06-07 18:35:37 +00001023 // If both values are local (meaning the corresponding set has attribute
1024 // AttrNone or AttrEscaped), then we know that CFLAA fully models them: they
1025 // may-alias each other if and only if they are in the same set
1026 // If at least one value is non-local (meaning it either is global/argument or
1027 // it comes from unknown sources like integer cast), the situation becomes a
1028 // bit more interesting. We follow three general rules described below:
1029 // - Non-local values may alias each other
1030 // - AttrNone values do not alias any non-local values
George Burgess IV652ec4f2016-06-09 23:15:04 +00001031 // - AttrEscaped do not alias globals/arguments, but they may alias
George Burgess IVa1f9a2d2016-06-07 18:35:37 +00001032 // AttrUnknown values
1033 if (SetA.Index == SetB.Index)
Chandler Carruthc3f49eb2015-06-22 02:16:51 +00001034 return MayAlias;
George Burgess IVa1f9a2d2016-06-07 18:35:37 +00001035 if (AttrsA.none() || AttrsB.none())
1036 return NoAlias;
George Burgess IV652ec4f2016-06-09 23:15:04 +00001037 if (isUnknownAttr(AttrsA) || isUnknownAttr(AttrsB))
George Burgess IVa1f9a2d2016-06-07 18:35:37 +00001038 return MayAlias;
1039 if (isGlobalOrArgAttr(AttrsA) && isGlobalOrArgAttr(AttrsB))
1040 return MayAlias;
1041 return NoAlias;
Hal Finkel7529c552014-09-02 21:43:13 +00001042}
Mehdi Amini46a43552015-03-04 18:43:29 +00001043
Chandler Carruthb4faf132016-03-11 10:22:49 +00001044char CFLAA::PassID;
1045
Chandler Carruthb47f8012016-03-11 11:05:24 +00001046CFLAAResult CFLAA::run(Function &F, AnalysisManager<Function> &AM) {
George Burgess IV18b83fe2016-06-01 18:39:54 +00001047 return CFLAAResult(AM.getResult<TargetLibraryAnalysis>(F));
Chandler Carruth7b560d42015-09-09 17:55:00 +00001048}
1049
Chandler Carruth7b560d42015-09-09 17:55:00 +00001050char CFLAAWrapperPass::ID = 0;
Chandler Carruth12884f72016-03-02 15:56:53 +00001051INITIALIZE_PASS(CFLAAWrapperPass, "cfl-aa", "CFL-Based Alias Analysis", false,
1052 true)
Chandler Carruth7b560d42015-09-09 17:55:00 +00001053
1054ImmutablePass *llvm::createCFLAAWrapperPass() { return new CFLAAWrapperPass(); }
1055
1056CFLAAWrapperPass::CFLAAWrapperPass() : ImmutablePass(ID) {
1057 initializeCFLAAWrapperPassPass(*PassRegistry::getPassRegistry());
1058}
1059
George Burgess IV18b83fe2016-06-01 18:39:54 +00001060void CFLAAWrapperPass::initializePass() {
1061 auto &TLIWP = getAnalysis<TargetLibraryInfoWrapperPass>();
1062 Result.reset(new CFLAAResult(TLIWP.getTLI()));
Chandler Carruth7b560d42015-09-09 17:55:00 +00001063}
1064
1065void CFLAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
1066 AU.setPreservesAll();
George Burgess IV18b83fe2016-06-01 18:39:54 +00001067 AU.addRequired<TargetLibraryInfoWrapperPass>();
Mehdi Amini46a43552015-03-04 18:43:29 +00001068}