blob: c637d640a9c5c4dd2cd372c2b4a4c61a13493bdd [file] [log] [blame]
George Burgess IVbfa401e2016-07-06 00:26:41 +00001//- CFLSteensAliasAnalysis.cpp - Unification-based Alias Analysis ---*- C++-*-//
Hal Finkel7529c552014-09-02 21:43:13 +00002//
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//
George Burgess IVbfa401e2016-07-06 00:26:41 +000010// This file implements a CFL-base, summary-based alias analysis algorithm. It
11// does not depend on types. The algorithm is a mixture of the one described in
12// "Demand-driven alias analysis for C" by Xin Zheng and Radu Rugina, and "Fast
13// algorithms for Dyck-CFL-reachability with applications to Alias Analysis" by
14// Zhang Q, Lyu M R, Yuan H, and Su Z. -- to summarize the papers, we build a
15// graph of the uses of a variable, where each node is a memory location, and
16// each edge is an action that happened on that memory location. The "actions"
17// can be one of Dereference, Reference, or Assign. The precision of this
18// analysis is roughly the same as that of an one level context-sensitive
19// Steensgaard's algorithm.
Hal Finkel7529c552014-09-02 21:43:13 +000020//
21// Two variables are considered as aliasing iff you can reach one value's node
22// from the other value's node and the language formed by concatenating all of
23// the edge labels (actions) conforms to a context-free grammar.
24//
25// Because this algorithm requires a graph search on each query, we execute the
26// algorithm outlined in "Fast algorithms..." (mentioned above)
27// in order to transform the graph into sets of variables that may alias in
George Burgess IV77351ba32016-01-28 00:54:01 +000028// ~nlogn time (n = number of variables), which makes queries take constant
Hal Finkel7529c552014-09-02 21:43:13 +000029// time.
30//===----------------------------------------------------------------------===//
31
George Burgess IV77351ba32016-01-28 00:54:01 +000032// N.B. AliasAnalysis as a whole is phrased as a FunctionPass at the moment, and
George Burgess IVbfa401e2016-07-06 00:26:41 +000033// CFLSteensAA is interprocedural. This is *technically* A Bad Thing, because
George Burgess IV77351ba32016-01-28 00:54:01 +000034// FunctionPasses are only allowed to inspect the Function that they're being
35// run on. Realistically, this likely isn't a problem until we allow
36// FunctionPasses to run concurrently.
37
George Burgess IVbfa401e2016-07-06 00:26:41 +000038#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
George Burgess IV1ca8aff2016-07-06 00:36:12 +000039#include "CFLGraph.h"
George Burgess IVe1919962016-07-06 00:47:21 +000040#include "StratifiedSets.h"
Hal Finkel7529c552014-09-02 21:43:13 +000041#include "llvm/ADT/DenseMap.h"
Hal Finkel7529c552014-09-02 21:43:13 +000042#include "llvm/ADT/None.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000043#include "llvm/ADT/Optional.h"
George Burgess IV18b83fe2016-06-01 18:39:54 +000044#include "llvm/Analysis/MemoryBuiltins.h"
45#include "llvm/Analysis/TargetLibraryInfo.h"
Hal Finkel7529c552014-09-02 21:43:13 +000046#include "llvm/IR/Constants.h"
47#include "llvm/IR/Function.h"
Hal Finkel7529c552014-09-02 21:43:13 +000048#include "llvm/IR/InstVisitor.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000049#include "llvm/IR/Instructions.h"
Hal Finkel7529c552014-09-02 21:43:13 +000050#include "llvm/Pass.h"
Hal Finkel7d7087c2014-09-02 22:13:00 +000051#include "llvm/Support/Compiler.h"
George Burgess IV33305e72015-02-12 03:07:07 +000052#include "llvm/Support/Debug.h"
Hal Finkel7529c552014-09-02 21:43:13 +000053#include "llvm/Support/ErrorHandling.h"
Benjamin Kramer799003b2015-03-23 19:32:43 +000054#include "llvm/Support/raw_ostream.h"
Hal Finkel7529c552014-09-02 21:43:13 +000055#include <algorithm>
56#include <cassert>
Benjamin Kramer799003b2015-03-23 19:32:43 +000057#include <memory>
Hal Finkel7529c552014-09-02 21:43:13 +000058#include <tuple>
59
60using namespace llvm;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000061using namespace llvm::cflaa;
Hal Finkel7529c552014-09-02 21:43:13 +000062
George Burgess IVbfa401e2016-07-06 00:26:41 +000063#define DEBUG_TYPE "cfl-steens-aa"
George Burgess IV33305e72015-02-12 03:07:07 +000064
George Burgess IVbfa401e2016-07-06 00:26:41 +000065CFLSteensAAResult::CFLSteensAAResult(const TargetLibraryInfo &TLI)
George Burgess IV18b83fe2016-06-01 18:39:54 +000066 : AAResultBase(), TLI(TLI) {}
George Burgess IVbfa401e2016-07-06 00:26:41 +000067CFLSteensAAResult::CFLSteensAAResult(CFLSteensAAResult &&Arg)
George Burgess IV18b83fe2016-06-01 18:39:54 +000068 : AAResultBase(std::move(Arg)), TLI(Arg.TLI) {}
George Burgess IVbfa401e2016-07-06 00:26:41 +000069CFLSteensAAResult::~CFLSteensAAResult() {}
Chandler Carruth8b046a42015-08-14 02:42:20 +000070
George Burgess IV87b2e412016-06-20 23:10:56 +000071/// Information we have about a function and would like to keep around.
George Burgess IVbfa401e2016-07-06 00:26:41 +000072class CFLSteensAAResult::FunctionInfo {
George Burgess IV87b2e412016-06-20 23:10:56 +000073 StratifiedSets<Value *> Sets;
74
75 // RetParamRelations is a collection of ExternalRelations.
76 SmallVector<ExternalRelation, 8> RetParamRelations;
77
George Burgess IVa3d62be2016-06-24 01:00:03 +000078 // RetParamAttributes is a collection of ExternalAttributes.
79 SmallVector<ExternalAttribute, 8> RetParamAttributes;
80
George Burgess IV87b2e412016-06-20 23:10:56 +000081public:
82 FunctionInfo(Function &Fn, const SmallVectorImpl<Value *> &RetVals,
83 StratifiedSets<Value *> S);
84
85 const StratifiedSets<Value *> &getStratifiedSets() const { return Sets; }
86 const SmallVectorImpl<ExternalRelation> &getRetParamRelations() const {
87 return RetParamRelations;
88 }
George Burgess IVa3d62be2016-06-24 01:00:03 +000089 const SmallVectorImpl<ExternalAttribute> &getRetParamAttributes() const {
90 return RetParamAttributes;
91 }
Chandler Carruth8b046a42015-08-14 02:42:20 +000092};
93
George Burgess IVcae581d2016-04-13 23:27:37 +000094/// Try to go from a Value* to a Function*. Never returns nullptr.
Hal Finkel7529c552014-09-02 21:43:13 +000095static Optional<Function *> parentFunctionOfValue(Value *);
96
George Burgess IVcae581d2016-04-13 23:27:37 +000097/// Returns possible functions called by the Inst* into the given
98/// SmallVectorImpl. Returns true if targets found, false otherwise. This is
99/// templated so we can use it with CallInsts and InvokeInsts.
George Burgess IV24eb0da2016-06-14 18:12:28 +0000100static bool getPossibleTargets(CallSite, SmallVectorImpl<Function *> &);
Hal Finkel7529c552014-09-02 21:43:13 +0000101
Hal Finkel1ae325f2014-09-02 23:50:01 +0000102const StratifiedIndex StratifiedLink::SetSentinel =
George Burgess IV11d509d2015-03-15 00:52:21 +0000103 std::numeric_limits<StratifiedIndex>::max();
Hal Finkel1ae325f2014-09-02 23:50:01 +0000104
Hal Finkel7529c552014-09-02 21:43:13 +0000105namespace {
Hal Finkel7529c552014-09-02 21:43:13 +0000106
George Burgess IV87b2e412016-06-20 23:10:56 +0000107/// The maximum number of arguments we can put into a summary.
108LLVM_CONSTEXPR unsigned MaxSupportedArgsInSummary = 50;
109
George Burgess IVcae581d2016-04-13 23:27:37 +0000110/// StratifiedSets call for knowledge of "direction", so this is how we
111/// represent that locally.
Hal Finkel7529c552014-09-02 21:43:13 +0000112enum class Level { Same, Above, Below };
113
George Burgess IVcae581d2016-04-13 23:27:37 +0000114/// Gets the edges our graph should have, based on an Instruction*
Hal Finkel7529c552014-09-02 21:43:13 +0000115class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
George Burgess IVbfa401e2016-07-06 00:26:41 +0000116 CFLSteensAAResult &AA;
George Burgess IV18b83fe2016-06-01 18:39:54 +0000117 const TargetLibraryInfo &TLI;
Hal Finkel7529c552014-09-02 21:43:13 +0000118
George Burgess IV24eb0da2016-06-14 18:12:28 +0000119 CFLGraph &Graph;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000120 SmallVectorImpl<Value *> &ReturnValues;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000121 SmallPtrSetImpl<Value *> &Externals;
122 SmallPtrSetImpl<Value *> &Escapes;
George Burgess IVe1919962016-07-06 00:47:21 +0000123 SmallVectorImpl<InstantiatedRelation> &InstantiatedRelations;
124 SmallVectorImpl<InstantiatedAttr> &InstantiatedAttrs;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000125
126 static bool hasUsefulEdges(ConstantExpr *CE) {
127 // ConstantExpr doesn't have terminators, invokes, or fences, so only needs
128 // to check for compares.
129 return CE->getOpcode() != Instruction::ICmp &&
130 CE->getOpcode() != Instruction::FCmp;
131 }
132
133 void addNode(Value *Val) {
134 if (!Graph.addNode(Val))
135 return;
136
137 if (isa<GlobalValue>(Val))
138 Externals.insert(Val);
139 else if (auto CExpr = dyn_cast<ConstantExpr>(Val))
140 if (hasUsefulEdges(CExpr))
141 visitConstantExpr(CExpr);
142 }
143
George Burgess IVe1919962016-07-06 00:47:21 +0000144 void addNodeWithAttr(Value *Val, AliasAttrs Attr) {
George Burgess IV259d9012016-06-15 20:43:41 +0000145 addNode(Val);
146 Graph.addAttr(Val, Attr);
147 }
148
149 void addEdge(Value *From, Value *To, EdgeType Type) {
150 if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
151 return;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000152 addNode(From);
153 if (To != From)
154 addNode(To);
George Burgess IV259d9012016-06-15 20:43:41 +0000155 Graph.addEdge(From, To, Type);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000156 }
157
Hal Finkel7529c552014-09-02 21:43:13 +0000158public:
George Burgess IVbfa401e2016-07-06 00:26:41 +0000159 GetEdgesVisitor(CFLSteensAAResult &AA, const TargetLibraryInfo &TLI,
George Burgess IVa3d62be2016-06-24 01:00:03 +0000160 CFLGraph &Graph, SmallVectorImpl<Value *> &ReturnValues,
161 SmallPtrSetImpl<Value *> &Externals,
George Burgess IV1f99da52016-06-23 18:55:23 +0000162 SmallPtrSetImpl<Value *> &Escapes,
George Burgess IVe1919962016-07-06 00:47:21 +0000163 SmallVectorImpl<InstantiatedRelation> &InstantiatedRelations,
164 SmallVectorImpl<InstantiatedAttr> &InstantiatedAttrs)
George Burgess IVa3d62be2016-06-24 01:00:03 +0000165 : AA(AA), TLI(TLI), Graph(Graph), ReturnValues(ReturnValues),
George Burgess IVe1919962016-07-06 00:47:21 +0000166 Externals(Externals), Escapes(Escapes),
167 InstantiatedRelations(InstantiatedRelations),
168 InstantiatedAttrs(InstantiatedAttrs) {}
Hal Finkel7529c552014-09-02 21:43:13 +0000169
170 void visitInstruction(Instruction &) {
171 llvm_unreachable("Unsupported instruction encountered");
172 }
173
George Burgess IVa3d62be2016-06-24 01:00:03 +0000174 void visitReturnInst(ReturnInst &Inst) {
175 if (auto RetVal = Inst.getReturnValue()) {
176 if (RetVal->getType()->isPointerTy()) {
177 addNode(RetVal);
178 ReturnValues.push_back(RetVal);
179 }
180 }
181 }
182
George Burgess IVb54a8d622015-03-10 02:40:06 +0000183 void visitPtrToIntInst(PtrToIntInst &Inst) {
184 auto *Ptr = Inst.getOperand(0);
George Burgess IVe1919962016-07-06 00:47:21 +0000185 addNodeWithAttr(Ptr, getAttrEscaped());
George Burgess IVb54a8d622015-03-10 02:40:06 +0000186 }
187
188 void visitIntToPtrInst(IntToPtrInst &Inst) {
189 auto *Ptr = &Inst;
George Burgess IVe1919962016-07-06 00:47:21 +0000190 addNodeWithAttr(Ptr, getAttrUnknown());
George Burgess IVb54a8d622015-03-10 02:40:06 +0000191 }
192
Hal Finkel7529c552014-09-02 21:43:13 +0000193 void visitCastInst(CastInst &Inst) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000194 auto *Src = Inst.getOperand(0);
George Burgess IV259d9012016-06-15 20:43:41 +0000195 addEdge(Src, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000196 }
197
198 void visitBinaryOperator(BinaryOperator &Inst) {
199 auto *Op1 = Inst.getOperand(0);
200 auto *Op2 = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000201 addEdge(Op1, &Inst, EdgeType::Assign);
202 addEdge(Op2, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000203 }
204
205 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
206 auto *Ptr = Inst.getPointerOperand();
207 auto *Val = Inst.getNewValOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000208 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000209 }
210
211 void visitAtomicRMWInst(AtomicRMWInst &Inst) {
212 auto *Ptr = Inst.getPointerOperand();
213 auto *Val = Inst.getValOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000214 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000215 }
216
217 void visitPHINode(PHINode &Inst) {
George Burgess IV77351ba32016-01-28 00:54:01 +0000218 for (Value *Val : Inst.incoming_values())
George Burgess IV259d9012016-06-15 20:43:41 +0000219 addEdge(Val, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000220 }
221
222 void visitGetElementPtrInst(GetElementPtrInst &Inst) {
223 auto *Op = Inst.getPointerOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000224 addEdge(Op, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000225 }
226
227 void visitSelectInst(SelectInst &Inst) {
Daniel Berlin16f7a522015-01-26 17:31:17 +0000228 // Condition is not processed here (The actual statement producing
229 // the condition result is processed elsewhere). For select, the
230 // condition is evaluated, but not loaded, stored, or assigned
231 // simply as a result of being the condition of a select.
232
Hal Finkel7529c552014-09-02 21:43:13 +0000233 auto *TrueVal = Inst.getTrueValue();
Hal Finkel7529c552014-09-02 21:43:13 +0000234 auto *FalseVal = Inst.getFalseValue();
George Burgess IV259d9012016-06-15 20:43:41 +0000235 addEdge(TrueVal, &Inst, EdgeType::Assign);
236 addEdge(FalseVal, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000237 }
238
George Burgess IV24eb0da2016-06-14 18:12:28 +0000239 void visitAllocaInst(AllocaInst &Inst) { Graph.addNode(&Inst); }
Hal Finkel7529c552014-09-02 21:43:13 +0000240
241 void visitLoadInst(LoadInst &Inst) {
242 auto *Ptr = Inst.getPointerOperand();
243 auto *Val = &Inst;
George Burgess IV259d9012016-06-15 20:43:41 +0000244 addEdge(Val, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000245 }
246
247 void visitStoreInst(StoreInst &Inst) {
248 auto *Ptr = Inst.getPointerOperand();
249 auto *Val = Inst.getValueOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000250 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000251 }
252
Hal Finkeldb5f86a2014-10-14 20:51:26 +0000253 void visitVAArgInst(VAArgInst &Inst) {
254 // We can't fully model va_arg here. For *Ptr = Inst.getOperand(0), it does
255 // two things:
256 // 1. Loads a value from *((T*)*Ptr).
257 // 2. Increments (stores to) *Ptr by some target-specific amount.
258 // For now, we'll handle this like a landingpad instruction (by placing the
259 // result in its own group, and having that group alias externals).
George Burgess IVe1919962016-07-06 00:47:21 +0000260 addNodeWithAttr(&Inst, getAttrUnknown());
Hal Finkeldb5f86a2014-10-14 20:51:26 +0000261 }
262
Hal Finkel7529c552014-09-02 21:43:13 +0000263 static bool isFunctionExternal(Function *Fn) {
George Burgess IV9fdbfe12016-06-21 01:42:47 +0000264 return !Fn->hasExactDefinition();
Hal Finkel7529c552014-09-02 21:43:13 +0000265 }
266
George Burgess IV87b2e412016-06-20 23:10:56 +0000267 bool tryInterproceduralAnalysis(CallSite CS,
268 const SmallVectorImpl<Function *> &Fns) {
Hal Finkel7529c552014-09-02 21:43:13 +0000269 assert(Fns.size() > 0);
270
George Burgess IV87b2e412016-06-20 23:10:56 +0000271 if (CS.arg_size() > MaxSupportedArgsInSummary)
Hal Finkel7529c552014-09-02 21:43:13 +0000272 return false;
273
274 // Exit early if we'll fail anyway
275 for (auto *Fn : Fns) {
276 if (isFunctionExternal(Fn) || Fn->isVarArg())
277 return false;
George Burgess IV87b2e412016-06-20 23:10:56 +0000278 // Fail if the caller does not provide enough arguments
279 assert(Fn->arg_size() <= CS.arg_size());
Hal Finkel7529c552014-09-02 21:43:13 +0000280 auto &MaybeInfo = AA.ensureCached(Fn);
281 if (!MaybeInfo.hasValue())
282 return false;
283 }
284
Hal Finkel7529c552014-09-02 21:43:13 +0000285 for (auto *Fn : Fns) {
George Burgess IV87b2e412016-06-20 23:10:56 +0000286 auto &FnInfo = AA.ensureCached(Fn);
287 assert(FnInfo.hasValue());
Hal Finkel7529c552014-09-02 21:43:13 +0000288
George Burgess IV87b2e412016-06-20 23:10:56 +0000289 auto &RetParamRelations = FnInfo->getRetParamRelations();
290 for (auto &Relation : RetParamRelations) {
George Burgess IVe1919962016-07-06 00:47:21 +0000291 auto IRelation = instantiateExternalRelation(Relation, CS);
292 if (IRelation.hasValue())
293 InstantiatedRelations.push_back(*IRelation);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000294 }
295
296 auto &RetParamAttributes = FnInfo->getRetParamAttributes();
297 for (auto &Attribute : RetParamAttributes) {
George Burgess IVe1919962016-07-06 00:47:21 +0000298 auto IAttr = instantiateExternalAttribute(Attribute, CS);
299 if (IAttr.hasValue())
300 InstantiatedAttrs.push_back(*IAttr);
Hal Finkel7529c552014-09-02 21:43:13 +0000301 }
George Burgess IV259d9012016-06-15 20:43:41 +0000302 }
George Burgess IV24eb0da2016-06-14 18:12:28 +0000303
Hal Finkel7529c552014-09-02 21:43:13 +0000304 return true;
305 }
306
George Burgess IV24eb0da2016-06-14 18:12:28 +0000307 void visitCallSite(CallSite CS) {
308 auto Inst = CS.getInstruction();
309
310 // Make sure all arguments and return value are added to the graph first
311 for (Value *V : CS.args())
312 addNode(V);
George Burgess IV87b2e412016-06-20 23:10:56 +0000313 if (Inst->getType()->isPointerTy())
George Burgess IV24eb0da2016-06-14 18:12:28 +0000314 addNode(Inst);
315
George Burgess IV18b83fe2016-06-01 18:39:54 +0000316 // Check if Inst is a call to a library function that allocates/deallocates
317 // on the heap. Those kinds of functions do not introduce any aliases.
318 // TODO: address other common library functions such as realloc(), strdup(),
319 // etc.
George Burgess IV24eb0da2016-06-14 18:12:28 +0000320 if (isMallocLikeFn(Inst, &TLI) || isCallocLikeFn(Inst, &TLI) ||
321 isFreeCall(Inst, &TLI))
George Burgess IV18b83fe2016-06-01 18:39:54 +0000322 return;
George Burgess IV18b83fe2016-06-01 18:39:54 +0000323
George Burgess IV68b36e02015-08-28 00:16:18 +0000324 // TODO: Add support for noalias args/all the other fun function attributes
325 // that we can tack on.
Hal Finkel7529c552014-09-02 21:43:13 +0000326 SmallVector<Function *, 4> Targets;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000327 if (getPossibleTargets(CS, Targets))
George Burgess IV87b2e412016-06-20 23:10:56 +0000328 if (tryInterproceduralAnalysis(CS, Targets))
Hal Finkel7529c552014-09-02 21:43:13 +0000329 return;
Hal Finkel7529c552014-09-02 21:43:13 +0000330
George Burgess IV68b36e02015-08-28 00:16:18 +0000331 // Because the function is opaque, we need to note that anything
George Burgess IV24eb0da2016-06-14 18:12:28 +0000332 // could have happened to the arguments (unless the function is marked
333 // readonly or readnone), and that the result could alias just about
334 // anything, too (unless the result is marked noalias).
335 if (!CS.onlyReadsMemory())
336 for (Value *V : CS.args()) {
George Burgess IV259d9012016-06-15 20:43:41 +0000337 if (V->getType()->isPointerTy())
338 Escapes.insert(V);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000339 }
340
George Burgess IV87b2e412016-06-20 23:10:56 +0000341 if (Inst->getType()->isPointerTy()) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000342 auto *Fn = CS.getCalledFunction();
343 if (Fn == nullptr || !Fn->doesNotAlias(0))
George Burgess IVe1919962016-07-06 00:47:21 +0000344 Graph.addAttr(Inst, getAttrUnknown());
George Burgess IV24eb0da2016-06-14 18:12:28 +0000345 }
Hal Finkel7529c552014-09-02 21:43:13 +0000346 }
347
George Burgess IVcae581d2016-04-13 23:27:37 +0000348 /// Because vectors/aggregates are immutable and unaddressable, there's
349 /// nothing we can do to coax a value out of them, other than calling
350 /// Extract{Element,Value}. We can effectively treat them as pointers to
351 /// arbitrary memory locations we can store in and load from.
Hal Finkel7529c552014-09-02 21:43:13 +0000352 void visitExtractElementInst(ExtractElementInst &Inst) {
353 auto *Ptr = Inst.getVectorOperand();
354 auto *Val = &Inst;
George Burgess IV259d9012016-06-15 20:43:41 +0000355 addEdge(Val, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000356 }
357
358 void visitInsertElementInst(InsertElementInst &Inst) {
359 auto *Vec = Inst.getOperand(0);
360 auto *Val = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000361 addEdge(Vec, &Inst, EdgeType::Assign);
362 addEdge(&Inst, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000363 }
364
365 void visitLandingPadInst(LandingPadInst &Inst) {
366 // Exceptions come from "nowhere", from our analysis' perspective.
367 // So we place the instruction its own group, noting that said group may
368 // alias externals
George Burgess IVe1919962016-07-06 00:47:21 +0000369 addNodeWithAttr(&Inst, getAttrUnknown());
Hal Finkel7529c552014-09-02 21:43:13 +0000370 }
371
372 void visitInsertValueInst(InsertValueInst &Inst) {
373 auto *Agg = Inst.getOperand(0);
374 auto *Val = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000375 addEdge(Agg, &Inst, EdgeType::Assign);
376 addEdge(&Inst, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000377 }
378
379 void visitExtractValueInst(ExtractValueInst &Inst) {
380 auto *Ptr = Inst.getAggregateOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000381 addEdge(&Inst, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000382 }
383
384 void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
385 auto *From1 = Inst.getOperand(0);
386 auto *From2 = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000387 addEdge(From1, &Inst, EdgeType::Assign);
388 addEdge(From2, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000389 }
Pete Cooper36642532015-06-12 16:13:54 +0000390
391 void visitConstantExpr(ConstantExpr *CE) {
392 switch (CE->getOpcode()) {
393 default:
394 llvm_unreachable("Unknown instruction type encountered!");
395// Build the switch statement using the Instruction.def file.
396#define HANDLE_INST(NUM, OPCODE, CLASS) \
397 case Instruction::OPCODE: \
398 visit##OPCODE(*(CLASS *)CE); \
399 break;
400#include "llvm/IR/Instruction.def"
401 }
402 }
Hal Finkel7529c552014-09-02 21:43:13 +0000403};
404
George Burgess IVe17756e2016-06-14 18:02:27 +0000405class CFLGraphBuilder {
406 // Input of the builder
George Burgess IVbfa401e2016-07-06 00:26:41 +0000407 CFLSteensAAResult &Analysis;
George Burgess IVe17756e2016-06-14 18:02:27 +0000408 const TargetLibraryInfo &TLI;
409
410 // Output of the builder
411 CFLGraph Graph;
412 SmallVector<Value *, 4> ReturnedValues;
413
414 // Auxiliary structures used by the builder
George Burgess IV24eb0da2016-06-14 18:12:28 +0000415 SmallPtrSet<Value *, 8> ExternalValues;
416 SmallPtrSet<Value *, 8> EscapedValues;
George Burgess IVe1919962016-07-06 00:47:21 +0000417 SmallVector<InstantiatedRelation, 8> InstantiatedRelations;
418 SmallVector<InstantiatedAttr, 8> InstantiatedAttrs;
George Burgess IVe17756e2016-06-14 18:02:27 +0000419
420 // Helper functions
421
422 // Determines whether or not we an instruction is useless to us (e.g.
423 // FenceInst)
424 static bool hasUsefulEdges(Instruction *Inst) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000425 bool IsNonInvokeRetTerminator = isa<TerminatorInst>(Inst) &&
426 !isa<InvokeInst>(Inst) &&
427 !isa<ReturnInst>(Inst);
George Burgess IVe17756e2016-06-14 18:02:27 +0000428 return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) &&
George Burgess IVa3d62be2016-06-24 01:00:03 +0000429 !IsNonInvokeRetTerminator;
George Burgess IVe17756e2016-06-14 18:02:27 +0000430 }
431
George Burgess IV24eb0da2016-06-14 18:12:28 +0000432 void addArgumentToGraph(Argument &Arg) {
George Burgess IV259d9012016-06-15 20:43:41 +0000433 if (Arg.getType()->isPointerTy()) {
434 Graph.addNode(&Arg);
435 ExternalValues.insert(&Arg);
436 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000437 }
438
439 // Given an Instruction, this will add it to the graph, along with any
440 // Instructions that are potentially only available from said Instruction
441 // For example, given the following line:
442 // %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
443 // addInstructionToGraph would add both the `load` and `getelementptr`
444 // instructions to the graph appropriately.
445 void addInstructionToGraph(Instruction &Inst) {
George Burgess IVe17756e2016-06-14 18:02:27 +0000446 if (!hasUsefulEdges(&Inst))
447 return;
448
George Burgess IVa3d62be2016-06-24 01:00:03 +0000449 GetEdgesVisitor(Analysis, TLI, Graph, ReturnedValues, ExternalValues,
George Burgess IVe1919962016-07-06 00:47:21 +0000450 EscapedValues, InstantiatedRelations, InstantiatedAttrs)
George Burgess IV24eb0da2016-06-14 18:12:28 +0000451 .visit(Inst);
452 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000453
George Burgess IV24eb0da2016-06-14 18:12:28 +0000454 // Builds the graph needed for constructing the StratifiedSets for the given
455 // function
456 void buildGraphFrom(Function &Fn) {
457 for (auto &Bb : Fn.getBasicBlockList())
458 for (auto &Inst : Bb.getInstList())
459 addInstructionToGraph(Inst);
George Burgess IVe17756e2016-06-14 18:02:27 +0000460
George Burgess IV24eb0da2016-06-14 18:12:28 +0000461 for (auto &Arg : Fn.args())
462 addArgumentToGraph(Arg);
George Burgess IVe17756e2016-06-14 18:02:27 +0000463 }
464
465public:
George Burgess IVbfa401e2016-07-06 00:26:41 +0000466 CFLGraphBuilder(CFLSteensAAResult &Analysis, const TargetLibraryInfo &TLI,
George Burgess IVe17756e2016-06-14 18:02:27 +0000467 Function &Fn)
468 : Analysis(Analysis), TLI(TLI) {
469 buildGraphFrom(Fn);
470 }
471
George Burgess IV87b2e412016-06-20 23:10:56 +0000472 const CFLGraph &getCFLGraph() const { return Graph; }
473 const SmallVector<Value *, 4> &getReturnValues() const {
474 return ReturnedValues;
George Burgess IVe17756e2016-06-14 18:02:27 +0000475 }
George Burgess IV87b2e412016-06-20 23:10:56 +0000476 const SmallPtrSet<Value *, 8> &getExternalValues() const {
477 return ExternalValues;
478 }
479 const SmallPtrSet<Value *, 8> &getEscapedValues() const {
480 return EscapedValues;
481 }
George Burgess IVe1919962016-07-06 00:47:21 +0000482 const SmallVector<InstantiatedRelation, 8> &getInstantiatedRelations() const {
483 return InstantiatedRelations;
George Burgess IV1f99da52016-06-23 18:55:23 +0000484 }
George Burgess IVe1919962016-07-06 00:47:21 +0000485 const SmallVector<InstantiatedAttr, 8> &getInstantiatedAttrs() const {
486 return InstantiatedAttrs;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000487 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000488};
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000489}
Hal Finkel7529c552014-09-02 21:43:13 +0000490
Hal Finkel7529c552014-09-02 21:43:13 +0000491//===----------------------------------------------------------------------===//
492// Function declarations that require types defined in the namespace above
493//===----------------------------------------------------------------------===//
494
George Burgess IVcae581d2016-04-13 23:27:37 +0000495/// Gets the "Level" that one should travel in StratifiedSets
496/// given an EdgeType.
Hal Finkel7529c552014-09-02 21:43:13 +0000497static Level directionOfEdgeType(EdgeType);
498
George Burgess IVcae581d2016-04-13 23:27:37 +0000499/// Determines whether it would be pointless to add the given Value to our sets.
George Burgess IVab03af22015-03-10 02:58:15 +0000500static bool canSkipAddingToSets(Value *Val);
501
Hal Finkel7529c552014-09-02 21:43:13 +0000502static Optional<Function *> parentFunctionOfValue(Value *Val) {
503 if (auto *Inst = dyn_cast<Instruction>(Val)) {
504 auto *Bb = Inst->getParent();
505 return Bb->getParent();
506 }
507
508 if (auto *Arg = dyn_cast<Argument>(Val))
509 return Arg->getParent();
George Burgess IV77351ba32016-01-28 00:54:01 +0000510 return None;
Hal Finkel7529c552014-09-02 21:43:13 +0000511}
512
George Burgess IV24eb0da2016-06-14 18:12:28 +0000513static bool getPossibleTargets(CallSite CS,
Hal Finkel7529c552014-09-02 21:43:13 +0000514 SmallVectorImpl<Function *> &Output) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000515 if (auto *Fn = CS.getCalledFunction()) {
Hal Finkel7529c552014-09-02 21:43:13 +0000516 Output.push_back(Fn);
517 return true;
518 }
519
520 // TODO: If the call is indirect, we might be able to enumerate all potential
521 // targets of the call and return them, rather than just failing.
522 return false;
523}
524
Hal Finkel7529c552014-09-02 21:43:13 +0000525static Level directionOfEdgeType(EdgeType Weight) {
526 switch (Weight) {
527 case EdgeType::Reference:
528 return Level::Above;
529 case EdgeType::Dereference:
530 return Level::Below;
531 case EdgeType::Assign:
532 return Level::Same;
533 }
534 llvm_unreachable("Incomplete switch coverage");
535}
536
George Burgess IVab03af22015-03-10 02:58:15 +0000537static bool canSkipAddingToSets(Value *Val) {
538 // Constants can share instances, which may falsely unify multiple
539 // sets, e.g. in
540 // store i32* null, i32** %ptr1
541 // store i32* null, i32** %ptr2
542 // clearly ptr1 and ptr2 should not be unified into the same set, so
543 // we should filter out the (potentially shared) instance to
544 // i32* null.
545 if (isa<Constant>(Val)) {
George Burgess IVab03af22015-03-10 02:58:15 +0000546 // TODO: Because all of these things are constant, we can determine whether
547 // the data is *actually* mutable at graph building time. This will probably
548 // come for free/cheap with offset awareness.
Duncan P. N. Exon Smith1de3c7e2016-04-05 21:10:45 +0000549 bool CanStoreMutableData = isa<GlobalValue>(Val) ||
550 isa<ConstantExpr>(Val) ||
551 isa<ConstantAggregate>(Val);
George Burgess IVab03af22015-03-10 02:58:15 +0000552 return !CanStoreMutableData;
553 }
554
555 return false;
Hal Finkel7529c552014-09-02 21:43:13 +0000556}
557
George Burgess IVbfa401e2016-07-06 00:26:41 +0000558CFLSteensAAResult::FunctionInfo::FunctionInfo(
559 Function &Fn, const SmallVectorImpl<Value *> &RetVals,
560 StratifiedSets<Value *> S)
George Burgess IV87b2e412016-06-20 23:10:56 +0000561 : Sets(std::move(S)) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000562 // Historically, an arbitrary upper-bound of 50 args was selected. We may want
563 // to remove this if it doesn't really matter in practice.
564 if (Fn.arg_size() > MaxSupportedArgsInSummary)
565 return;
George Burgess IV87b2e412016-06-20 23:10:56 +0000566
George Burgess IV1f99da52016-06-23 18:55:23 +0000567 DenseMap<StratifiedIndex, InterfaceValue> InterfaceMap;
George Burgess IV87b2e412016-06-20 23:10:56 +0000568
George Burgess IV1f99da52016-06-23 18:55:23 +0000569 // Our intention here is to record all InterfaceValues that share the same
570 // StratifiedIndex in RetParamRelations. For each valid InterfaceValue, we
571 // have its StratifiedIndex scanned here and check if the index is presented
572 // in InterfaceMap: if it is not, we add the correspondence to the map;
573 // otherwise, an aliasing relation is found and we add it to
574 // RetParamRelations.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000575
George Burgess IVd14d05a2016-06-23 20:59:13 +0000576 auto AddToRetParamRelations = [&](unsigned InterfaceIndex,
577 StratifiedIndex SetIndex) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000578 unsigned Level = 0;
579 while (true) {
580 InterfaceValue CurrValue{InterfaceIndex, Level};
George Burgess IV87b2e412016-06-20 23:10:56 +0000581
George Burgess IV1f99da52016-06-23 18:55:23 +0000582 auto Itr = InterfaceMap.find(SetIndex);
583 if (Itr != InterfaceMap.end()) {
584 if (CurrValue != Itr->second)
585 RetParamRelations.push_back(ExternalRelation{CurrValue, Itr->second});
586 break;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000587 }
George Burgess IV87b2e412016-06-20 23:10:56 +0000588
George Burgess IV1f99da52016-06-23 18:55:23 +0000589 auto &Link = Sets.getLink(SetIndex);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000590 InterfaceMap.insert(std::make_pair(SetIndex, CurrValue));
George Burgess IVe1919962016-07-06 00:47:21 +0000591 auto ExternalAttrs = getExternallyVisibleAttrs(Link.Attrs);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000592 if (ExternalAttrs.any())
593 RetParamAttributes.push_back(
594 ExternalAttribute{CurrValue, ExternalAttrs});
595
George Burgess IV1f99da52016-06-23 18:55:23 +0000596 if (!Link.hasBelow())
597 break;
George Burgess IV87b2e412016-06-20 23:10:56 +0000598
George Burgess IV1f99da52016-06-23 18:55:23 +0000599 ++Level;
600 SetIndex = Link.Below;
George Burgess IV87b2e412016-06-20 23:10:56 +0000601 }
George Burgess IV1f99da52016-06-23 18:55:23 +0000602 };
603
604 // Populate RetParamRelations for return values
605 for (auto *RetVal : RetVals) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000606 assert(RetVal != nullptr);
607 assert(RetVal->getType()->isPointerTy());
George Burgess IV1f99da52016-06-23 18:55:23 +0000608 auto RetInfo = Sets.find(RetVal);
609 if (RetInfo.hasValue())
610 AddToRetParamRelations(0, RetInfo->Index);
611 }
612
613 // Populate RetParamRelations for parameters
614 unsigned I = 0;
615 for (auto &Param : Fn.args()) {
616 if (Param.getType()->isPointerTy()) {
617 auto ParamInfo = Sets.find(&Param);
618 if (ParamInfo.hasValue())
619 AddToRetParamRelations(I + 1, ParamInfo->Index);
620 }
621 ++I;
George Burgess IV87b2e412016-06-20 23:10:56 +0000622 }
623}
624
Chandler Carruth8b046a42015-08-14 02:42:20 +0000625// Builds the graph + StratifiedSets for a function.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000626CFLSteensAAResult::FunctionInfo CFLSteensAAResult::buildSetsFrom(Function *Fn) {
George Burgess IVe17756e2016-06-14 18:02:27 +0000627 CFLGraphBuilder GraphBuilder(*this, TLI, *Fn);
628 StratifiedSetsBuilder<Value *> SetBuilder;
Hal Finkel7529c552014-09-02 21:43:13 +0000629
George Burgess IVe17756e2016-06-14 18:02:27 +0000630 auto &Graph = GraphBuilder.getCFLGraph();
George Burgess IVdc96feb2016-06-13 19:21:18 +0000631 SmallVector<Value *, 16> Worklist;
George Burgess IVdc96feb2016-06-13 19:21:18 +0000632 for (auto Node : Graph.nodes())
633 Worklist.push_back(Node);
634
635 while (!Worklist.empty()) {
636 auto *CurValue = Worklist.pop_back_val();
George Burgess IVe17756e2016-06-14 18:02:27 +0000637 SetBuilder.add(CurValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000638 if (canSkipAddingToSets(CurValue))
639 continue;
640
George Burgess IV259d9012016-06-15 20:43:41 +0000641 auto Attr = Graph.attrFor(CurValue);
642 SetBuilder.noteAttributes(CurValue, Attr);
643
George Burgess IVdc96feb2016-06-13 19:21:18 +0000644 for (const auto &Edge : Graph.edgesFor(CurValue)) {
645 auto Label = Edge.Type;
646 auto *OtherValue = Edge.Other;
647
648 if (canSkipAddingToSets(OtherValue))
Hal Finkel7529c552014-09-02 21:43:13 +0000649 continue;
650
George Burgess IVdc96feb2016-06-13 19:21:18 +0000651 bool Added;
652 switch (directionOfEdgeType(Label)) {
653 case Level::Above:
George Burgess IVe17756e2016-06-14 18:02:27 +0000654 Added = SetBuilder.addAbove(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000655 break;
656 case Level::Below:
George Burgess IVe17756e2016-06-14 18:02:27 +0000657 Added = SetBuilder.addBelow(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000658 break;
659 case Level::Same:
George Burgess IVe17756e2016-06-14 18:02:27 +0000660 Added = SetBuilder.addWith(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000661 break;
Hal Finkel7529c552014-09-02 21:43:13 +0000662 }
George Burgess IVdc96feb2016-06-13 19:21:18 +0000663
George Burgess IVdc96feb2016-06-13 19:21:18 +0000664 if (Added)
665 Worklist.push_back(OtherValue);
Hal Finkel7529c552014-09-02 21:43:13 +0000666 }
667 }
668
George Burgess IV652ec4f2016-06-09 23:15:04 +0000669 // Special handling for globals and arguments
George Burgess IV24eb0da2016-06-14 18:12:28 +0000670 for (auto *External : GraphBuilder.getExternalValues()) {
671 SetBuilder.add(External);
George Burgess IVe1919962016-07-06 00:47:21 +0000672 auto Attr = getGlobalOrArgAttrFromValue(*External);
673 if (Attr.any()) {
674 SetBuilder.noteAttributes(External, Attr);
675 if (isa<GlobalValue>(External))
676 SetBuilder.addAttributesBelow(External, 1, getAttrUnknown());
George Burgess IVa3d62be2016-06-24 01:00:03 +0000677 else
George Burgess IVe1919962016-07-06 00:47:21 +0000678 SetBuilder.addAttributesBelow(External, 1, getAttrCaller());
George Burgess IV652ec4f2016-06-09 23:15:04 +0000679 }
George Burgess IV24eb0da2016-06-14 18:12:28 +0000680 }
George Burgess IVab03af22015-03-10 02:58:15 +0000681
George Burgess IV1f99da52016-06-23 18:55:23 +0000682 // Special handling for interprocedural aliases
George Burgess IVe1919962016-07-06 00:47:21 +0000683 for (auto &Edge : GraphBuilder.getInstantiatedRelations()) {
George Burgess IVfe1397b2016-06-23 19:16:04 +0000684 auto FromVal = Edge.From.Val;
685 auto ToVal = Edge.To.Val;
George Burgess IV1f99da52016-06-23 18:55:23 +0000686 SetBuilder.add(FromVal);
687 SetBuilder.add(ToVal);
688 SetBuilder.addBelowWith(FromVal, Edge.From.DerefLevel, ToVal,
689 Edge.To.DerefLevel);
690 }
691
George Burgess IVa3d62be2016-06-24 01:00:03 +0000692 // Special handling for interprocedural attributes
George Burgess IVe1919962016-07-06 00:47:21 +0000693 for (auto &IPAttr : GraphBuilder.getInstantiatedAttrs()) {
694 auto Val = IPAttr.IValue.Val;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000695 SetBuilder.add(Val);
George Burgess IVe1919962016-07-06 00:47:21 +0000696 SetBuilder.addAttributesBelow(Val, IPAttr.IValue.DerefLevel, IPAttr.Attr);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000697 }
698
George Burgess IV1f99da52016-06-23 18:55:23 +0000699 // Special handling for opaque external functions
George Burgess IV24eb0da2016-06-14 18:12:28 +0000700 for (auto *Escape : GraphBuilder.getEscapedValues()) {
701 SetBuilder.add(Escape);
George Burgess IVe1919962016-07-06 00:47:21 +0000702 SetBuilder.noteAttributes(Escape, getAttrEscaped());
703 SetBuilder.addAttributesBelow(Escape, 1, getAttrUnknown());
George Burgess IV24eb0da2016-06-14 18:12:28 +0000704 }
Hal Finkel7529c552014-09-02 21:43:13 +0000705
George Burgess IV87b2e412016-06-20 23:10:56 +0000706 return FunctionInfo(*Fn, GraphBuilder.getReturnValues(), SetBuilder.build());
Hal Finkel7529c552014-09-02 21:43:13 +0000707}
708
George Burgess IVbfa401e2016-07-06 00:26:41 +0000709void CFLSteensAAResult::scan(Function *Fn) {
Hal Finkel8d1590d2014-09-02 22:52:30 +0000710 auto InsertPair = Cache.insert(std::make_pair(Fn, Optional<FunctionInfo>()));
Hal Finkel7529c552014-09-02 21:43:13 +0000711 (void)InsertPair;
712 assert(InsertPair.second &&
713 "Trying to scan a function that has already been cached");
714
George Burgess IV6edb8912016-05-02 18:09:19 +0000715 // Note that we can't do Cache[Fn] = buildSetsFrom(Fn) here: the function call
716 // may get evaluated after operator[], potentially triggering a DenseMap
717 // resize and invalidating the reference returned by operator[]
718 auto FunInfo = buildSetsFrom(Fn);
719 Cache[Fn] = std::move(FunInfo);
720
Hal Finkel7529c552014-09-02 21:43:13 +0000721 Handles.push_front(FunctionHandle(Fn, this));
722}
723
George Burgess IVbfa401e2016-07-06 00:26:41 +0000724void CFLSteensAAResult::evict(Function *Fn) { Cache.erase(Fn); }
Chandler Carruth8b046a42015-08-14 02:42:20 +0000725
George Burgess IVcae581d2016-04-13 23:27:37 +0000726/// Ensures that the given function is available in the cache, and returns the
727/// entry.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000728const Optional<CFLSteensAAResult::FunctionInfo> &
729CFLSteensAAResult::ensureCached(Function *Fn) {
Chandler Carruth8b046a42015-08-14 02:42:20 +0000730 auto Iter = Cache.find(Fn);
731 if (Iter == Cache.end()) {
732 scan(Fn);
733 Iter = Cache.find(Fn);
734 assert(Iter != Cache.end());
735 assert(Iter->second.hasValue());
736 }
737 return Iter->second;
738}
739
George Burgess IVbfa401e2016-07-06 00:26:41 +0000740AliasResult CFLSteensAAResult::query(const MemoryLocation &LocA,
741 const MemoryLocation &LocB) {
Hal Finkel7529c552014-09-02 21:43:13 +0000742 auto *ValA = const_cast<Value *>(LocA.Ptr);
743 auto *ValB = const_cast<Value *>(LocB.Ptr);
744
George Burgess IV259d9012016-06-15 20:43:41 +0000745 if (!ValA->getType()->isPointerTy() || !ValB->getType()->isPointerTy())
746 return NoAlias;
747
Hal Finkel7529c552014-09-02 21:43:13 +0000748 Function *Fn = nullptr;
749 auto MaybeFnA = parentFunctionOfValue(ValA);
750 auto MaybeFnB = parentFunctionOfValue(ValB);
751 if (!MaybeFnA.hasValue() && !MaybeFnB.hasValue()) {
George Burgess IVcae581d2016-04-13 23:27:37 +0000752 // The only times this is known to happen are when globals + InlineAsm are
753 // involved
George Burgess IVbfa401e2016-07-06 00:26:41 +0000754 DEBUG(dbgs()
755 << "CFLSteensAA: could not extract parent function information.\n");
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000756 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000757 }
758
759 if (MaybeFnA.hasValue()) {
760 Fn = *MaybeFnA;
761 assert((!MaybeFnB.hasValue() || *MaybeFnB == *MaybeFnA) &&
762 "Interprocedural queries not supported");
763 } else {
764 Fn = *MaybeFnB;
765 }
766
767 assert(Fn != nullptr);
768 auto &MaybeInfo = ensureCached(Fn);
769 assert(MaybeInfo.hasValue());
770
George Burgess IV87b2e412016-06-20 23:10:56 +0000771 auto &Sets = MaybeInfo->getStratifiedSets();
Hal Finkel7529c552014-09-02 21:43:13 +0000772 auto MaybeA = Sets.find(ValA);
773 if (!MaybeA.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000774 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000775
776 auto MaybeB = Sets.find(ValB);
777 if (!MaybeB.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000778 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000779
780 auto SetA = *MaybeA;
781 auto SetB = *MaybeB;
Hal Finkel7529c552014-09-02 21:43:13 +0000782 auto AttrsA = Sets.getLink(SetA.Index).Attrs;
783 auto AttrsB = Sets.getLink(SetB.Index).Attrs;
George Burgess IV33305e72015-02-12 03:07:07 +0000784
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000785 // If both values are local (meaning the corresponding set has attribute
George Burgess IVbfa401e2016-07-06 00:26:41 +0000786 // AttrNone or AttrEscaped), then we know that CFLSteensAA fully models them:
787 // they may-alias each other if and only if they are in the same set.
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000788 // If at least one value is non-local (meaning it either is global/argument or
789 // it comes from unknown sources like integer cast), the situation becomes a
790 // bit more interesting. We follow three general rules described below:
791 // - Non-local values may alias each other
792 // - AttrNone values do not alias any non-local values
George Burgess IV652ec4f2016-06-09 23:15:04 +0000793 // - AttrEscaped do not alias globals/arguments, but they may alias
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000794 // AttrUnknown values
795 if (SetA.Index == SetB.Index)
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000796 return MayAlias;
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000797 if (AttrsA.none() || AttrsB.none())
798 return NoAlias;
George Burgess IVe1919962016-07-06 00:47:21 +0000799 if (hasUnknownOrCallerAttr(AttrsA) || hasUnknownOrCallerAttr(AttrsB))
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000800 return MayAlias;
801 if (isGlobalOrArgAttr(AttrsA) && isGlobalOrArgAttr(AttrsB))
802 return MayAlias;
803 return NoAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000804}
Mehdi Amini46a43552015-03-04 18:43:29 +0000805
George Burgess IVbfa401e2016-07-06 00:26:41 +0000806ModRefInfo CFLSteensAAResult::getArgModRefInfo(ImmutableCallSite CS,
807 unsigned ArgIdx) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000808 if (auto CalledFunc = CS.getCalledFunction()) {
809 auto &MaybeInfo = ensureCached(const_cast<Function *>(CalledFunc));
810 if (!MaybeInfo.hasValue())
811 return MRI_ModRef;
812 auto &RetParamAttributes = MaybeInfo->getRetParamAttributes();
813 auto &RetParamRelations = MaybeInfo->getRetParamRelations();
814
815 bool ArgAttributeIsWritten =
816 std::any_of(RetParamAttributes.begin(), RetParamAttributes.end(),
817 [ArgIdx](const ExternalAttribute &ExtAttr) {
818 return ExtAttr.IValue.Index == ArgIdx + 1;
819 });
820 bool ArgIsAccessed =
821 std::any_of(RetParamRelations.begin(), RetParamRelations.end(),
822 [ArgIdx](const ExternalRelation &ExtRelation) {
823 return ExtRelation.To.Index == ArgIdx + 1 ||
824 ExtRelation.From.Index == ArgIdx + 1;
825 });
826
827 return (!ArgIsAccessed && !ArgAttributeIsWritten) ? MRI_NoModRef
828 : MRI_ModRef;
829 }
830
831 return MRI_ModRef;
832}
833
George Burgess IVbfa401e2016-07-06 00:26:41 +0000834FunctionModRefBehavior
835CFLSteensAAResult::getModRefBehavior(ImmutableCallSite CS) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000836 // If we know the callee, try analyzing it
837 if (auto CalledFunc = CS.getCalledFunction())
838 return getModRefBehavior(CalledFunc);
839
840 // Otherwise, be conservative
841 return FMRB_UnknownModRefBehavior;
842}
843
George Burgess IVbfa401e2016-07-06 00:26:41 +0000844FunctionModRefBehavior CFLSteensAAResult::getModRefBehavior(const Function *F) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000845 assert(F != nullptr);
846
847 // TODO: Remove the const_cast
848 auto &MaybeInfo = ensureCached(const_cast<Function *>(F));
849 if (!MaybeInfo.hasValue())
850 return FMRB_UnknownModRefBehavior;
851 auto &RetParamAttributes = MaybeInfo->getRetParamAttributes();
852 auto &RetParamRelations = MaybeInfo->getRetParamRelations();
853
854 // First, if any argument is marked Escpaed, Unknown or Global, anything may
855 // happen to them and thus we can't draw any conclusion.
856 if (!RetParamAttributes.empty())
857 return FMRB_UnknownModRefBehavior;
858
859 // Currently we don't (and can't) distinguish reads from writes in
860 // RetParamRelations. All we can say is whether there may be memory access or
861 // not.
862 if (RetParamRelations.empty())
863 return FMRB_DoesNotAccessMemory;
864
865 // Check if something beyond argmem gets touched.
866 bool AccessArgMemoryOnly =
867 std::all_of(RetParamRelations.begin(), RetParamRelations.end(),
868 [](const ExternalRelation &ExtRelation) {
869 // Both DerefLevels has to be 0, since we don't know which
870 // one is a read and which is a write.
871 return ExtRelation.From.DerefLevel == 0 &&
872 ExtRelation.To.DerefLevel == 0;
873 });
874 return AccessArgMemoryOnly ? FMRB_OnlyAccessesArgumentPointees
875 : FMRB_UnknownModRefBehavior;
876}
877
George Burgess IVbfa401e2016-07-06 00:26:41 +0000878char CFLSteensAA::PassID;
Chandler Carruthb4faf132016-03-11 10:22:49 +0000879
George Burgess IVbfa401e2016-07-06 00:26:41 +0000880CFLSteensAAResult CFLSteensAA::run(Function &F, AnalysisManager<Function> &AM) {
881 return CFLSteensAAResult(AM.getResult<TargetLibraryAnalysis>(F));
Chandler Carruth7b560d42015-09-09 17:55:00 +0000882}
883
George Burgess IVbfa401e2016-07-06 00:26:41 +0000884char CFLSteensAAWrapperPass::ID = 0;
885INITIALIZE_PASS(CFLSteensAAWrapperPass, "cfl-steens-aa",
886 "Unification-Based CFL Alias Analysis", false, true)
Chandler Carruth7b560d42015-09-09 17:55:00 +0000887
George Burgess IVbfa401e2016-07-06 00:26:41 +0000888ImmutablePass *llvm::createCFLSteensAAWrapperPass() {
889 return new CFLSteensAAWrapperPass();
Chandler Carruth7b560d42015-09-09 17:55:00 +0000890}
891
George Burgess IVbfa401e2016-07-06 00:26:41 +0000892CFLSteensAAWrapperPass::CFLSteensAAWrapperPass() : ImmutablePass(ID) {
893 initializeCFLSteensAAWrapperPassPass(*PassRegistry::getPassRegistry());
894}
895
896void CFLSteensAAWrapperPass::initializePass() {
George Burgess IV18b83fe2016-06-01 18:39:54 +0000897 auto &TLIWP = getAnalysis<TargetLibraryInfoWrapperPass>();
George Burgess IVbfa401e2016-07-06 00:26:41 +0000898 Result.reset(new CFLSteensAAResult(TLIWP.getTLI()));
Chandler Carruth7b560d42015-09-09 17:55:00 +0000899}
900
George Burgess IVbfa401e2016-07-06 00:26:41 +0000901void CFLSteensAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
Chandler Carruth7b560d42015-09-09 17:55:00 +0000902 AU.setPreservesAll();
George Burgess IV18b83fe2016-06-01 18:39:54 +0000903 AU.addRequired<TargetLibraryInfoWrapperPass>();
Mehdi Amini46a43552015-03-04 18:43:29 +0000904}