blob: 1f91468f54629112f5b877403c26b1a446523e44 [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"
Hal Finkel7529c552014-09-02 21:43:13 +000040#include "llvm/ADT/DenseMap.h"
Hal Finkel7529c552014-09-02 21:43:13 +000041#include "llvm/ADT/None.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000042#include "llvm/ADT/Optional.h"
George Burgess IV18b83fe2016-06-01 18:39:54 +000043#include "llvm/Analysis/MemoryBuiltins.h"
44#include "llvm/Analysis/TargetLibraryInfo.h"
Hal Finkel7529c552014-09-02 21:43:13 +000045#include "llvm/IR/Constants.h"
46#include "llvm/IR/Function.h"
Hal Finkel7529c552014-09-02 21:43:13 +000047#include "llvm/IR/InstVisitor.h"
Chandler Carruthd9903882015-01-14 11:23:27 +000048#include "llvm/IR/Instructions.h"
Hal Finkel7529c552014-09-02 21:43:13 +000049#include "llvm/Pass.h"
Hal Finkel7d7087c2014-09-02 22:13:00 +000050#include "llvm/Support/Compiler.h"
George Burgess IV33305e72015-02-12 03:07:07 +000051#include "llvm/Support/Debug.h"
Hal Finkel7529c552014-09-02 21:43:13 +000052#include "llvm/Support/ErrorHandling.h"
Benjamin Kramer799003b2015-03-23 19:32:43 +000053#include "llvm/Support/raw_ostream.h"
Hal Finkel7529c552014-09-02 21:43:13 +000054#include <algorithm>
55#include <cassert>
Benjamin Kramer799003b2015-03-23 19:32:43 +000056#include <memory>
Hal Finkel7529c552014-09-02 21:43:13 +000057#include <tuple>
58
59using namespace llvm;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000060using namespace llvm::cflaa;
Hal Finkel7529c552014-09-02 21:43:13 +000061
George Burgess IVbfa401e2016-07-06 00:26:41 +000062#define DEBUG_TYPE "cfl-steens-aa"
George Burgess IV33305e72015-02-12 03:07:07 +000063
George Burgess IVbfa401e2016-07-06 00:26:41 +000064CFLSteensAAResult::CFLSteensAAResult(const TargetLibraryInfo &TLI)
George Burgess IV18b83fe2016-06-01 18:39:54 +000065 : AAResultBase(), TLI(TLI) {}
George Burgess IVbfa401e2016-07-06 00:26:41 +000066CFLSteensAAResult::CFLSteensAAResult(CFLSteensAAResult &&Arg)
George Burgess IV18b83fe2016-06-01 18:39:54 +000067 : AAResultBase(std::move(Arg)), TLI(Arg.TLI) {}
George Burgess IVbfa401e2016-07-06 00:26:41 +000068CFLSteensAAResult::~CFLSteensAAResult() {}
Chandler Carruth8b046a42015-08-14 02:42:20 +000069
George Burgess IV1f99da52016-06-23 18:55:23 +000070/// We use InterfaceValue to describe parameters/return value, as well as
71/// potential memory locations that are pointed to by parameters/return value,
72/// of a function.
73/// Index is an integer which represents a single parameter or a return value.
74/// When the index is 0, it refers to the return value. Non-zero index i refers
75/// to the i-th parameter.
76/// DerefLevel indicates the number of dereferences one must perform on the
77/// parameter/return value to get this InterfaceValue.
78struct InterfaceValue {
79 unsigned Index;
80 unsigned DerefLevel;
81};
82
83bool operator==(InterfaceValue lhs, InterfaceValue rhs) {
84 return lhs.Index == rhs.Index && lhs.DerefLevel == rhs.DerefLevel;
85}
86bool operator!=(InterfaceValue lhs, InterfaceValue rhs) {
87 return !(lhs == rhs);
88}
89
90/// We use ExternalRelation to describe an externally visible aliasing relations
George Burgess IV87b2e412016-06-20 23:10:56 +000091/// between parameters/return value of a function.
George Burgess IV87b2e412016-06-20 23:10:56 +000092struct ExternalRelation {
George Burgess IV1f99da52016-06-23 18:55:23 +000093 InterfaceValue From, To;
George Burgess IV87b2e412016-06-20 23:10:56 +000094};
Chandler Carruth8b046a42015-08-14 02:42:20 +000095
George Burgess IVa3d62be2016-06-24 01:00:03 +000096/// We use ExternalAttribute to describe an externally visible StratifiedAttrs
97/// for parameters/return value.
98struct ExternalAttribute {
99 InterfaceValue IValue;
100 StratifiedAttrs Attr;
101};
102
George Burgess IV87b2e412016-06-20 23:10:56 +0000103/// Information we have about a function and would like to keep around.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000104class CFLSteensAAResult::FunctionInfo {
George Burgess IV87b2e412016-06-20 23:10:56 +0000105 StratifiedSets<Value *> Sets;
106
107 // RetParamRelations is a collection of ExternalRelations.
108 SmallVector<ExternalRelation, 8> RetParamRelations;
109
George Burgess IVa3d62be2016-06-24 01:00:03 +0000110 // RetParamAttributes is a collection of ExternalAttributes.
111 SmallVector<ExternalAttribute, 8> RetParamAttributes;
112
George Burgess IV87b2e412016-06-20 23:10:56 +0000113public:
114 FunctionInfo(Function &Fn, const SmallVectorImpl<Value *> &RetVals,
115 StratifiedSets<Value *> S);
116
117 const StratifiedSets<Value *> &getStratifiedSets() const { return Sets; }
118 const SmallVectorImpl<ExternalRelation> &getRetParamRelations() const {
119 return RetParamRelations;
120 }
George Burgess IVa3d62be2016-06-24 01:00:03 +0000121 const SmallVectorImpl<ExternalAttribute> &getRetParamAttributes() const {
122 return RetParamAttributes;
123 }
Chandler Carruth8b046a42015-08-14 02:42:20 +0000124};
125
George Burgess IVcae581d2016-04-13 23:27:37 +0000126/// Try to go from a Value* to a Function*. Never returns nullptr.
Hal Finkel7529c552014-09-02 21:43:13 +0000127static Optional<Function *> parentFunctionOfValue(Value *);
128
George Burgess IVcae581d2016-04-13 23:27:37 +0000129/// Returns possible functions called by the Inst* into the given
130/// SmallVectorImpl. Returns true if targets found, false otherwise. This is
131/// templated so we can use it with CallInsts and InvokeInsts.
George Burgess IV24eb0da2016-06-14 18:12:28 +0000132static bool getPossibleTargets(CallSite, SmallVectorImpl<Function *> &);
Hal Finkel7529c552014-09-02 21:43:13 +0000133
Hal Finkel1ae325f2014-09-02 23:50:01 +0000134const StratifiedIndex StratifiedLink::SetSentinel =
George Burgess IV11d509d2015-03-15 00:52:21 +0000135 std::numeric_limits<StratifiedIndex>::max();
Hal Finkel1ae325f2014-09-02 23:50:01 +0000136
Hal Finkel7529c552014-09-02 21:43:13 +0000137namespace {
George Burgess IVcae581d2016-04-13 23:27:37 +0000138/// StratifiedInfo Attribute things.
Hal Finkel7d7087c2014-09-02 22:13:00 +0000139LLVM_CONSTEXPR unsigned MaxStratifiedAttrIndex = NumStratifiedAttrs;
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000140LLVM_CONSTEXPR unsigned AttrEscapedIndex = 0;
141LLVM_CONSTEXPR unsigned AttrUnknownIndex = 1;
142LLVM_CONSTEXPR unsigned AttrGlobalIndex = 2;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000143LLVM_CONSTEXPR unsigned AttrCallerIndex = 3;
144LLVM_CONSTEXPR unsigned AttrFirstArgIndex = 4;
Hal Finkel7d7087c2014-09-02 22:13:00 +0000145LLVM_CONSTEXPR unsigned AttrLastArgIndex = MaxStratifiedAttrIndex;
146LLVM_CONSTEXPR unsigned AttrMaxNumArgs = AttrLastArgIndex - AttrFirstArgIndex;
Hal Finkel7529c552014-09-02 21:43:13 +0000147
George Burgess IVd9c39fc2016-06-24 01:41:29 +0000148// NOTE: These aren't StratifiedAttrs because bitsets don't have a constexpr
149// ctor for some versions of MSVC that we support. We could maybe refactor,
150// but...
151using StratifiedAttr = unsigned;
George Burgess IVd9c39fc2016-06-24 01:41:29 +0000152LLVM_CONSTEXPR StratifiedAttr AttrEscaped = 1 << AttrEscapedIndex;
153LLVM_CONSTEXPR StratifiedAttr AttrUnknown = 1 << AttrUnknownIndex;
154LLVM_CONSTEXPR StratifiedAttr AttrGlobal = 1 << AttrGlobalIndex;
155LLVM_CONSTEXPR StratifiedAttr AttrCaller = 1 << AttrCallerIndex;
156LLVM_CONSTEXPR StratifiedAttr ExternalAttrMask =
157 AttrEscaped | AttrUnknown | AttrGlobal;
Hal Finkel7529c552014-09-02 21:43:13 +0000158
George Burgess IV87b2e412016-06-20 23:10:56 +0000159/// The maximum number of arguments we can put into a summary.
160LLVM_CONSTEXPR unsigned MaxSupportedArgsInSummary = 50;
161
George Burgess IVcae581d2016-04-13 23:27:37 +0000162/// StratifiedSets call for knowledge of "direction", so this is how we
163/// represent that locally.
Hal Finkel7529c552014-09-02 21:43:13 +0000164enum class Level { Same, Above, Below };
165
George Burgess IVa3d62be2016-06-24 01:00:03 +0000166// This is the result of instantiating InterfaceValue at a particular callsite
167struct InterprocNode {
168 Value *Val;
169 unsigned DerefLevel;
170};
171
George Burgess IV1f99da52016-06-23 18:55:23 +0000172// Interprocedural assignment edges that CFLGraph may not easily model
173struct InterprocEdge {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000174 InterprocNode From, To;
175};
George Burgess IV1f99da52016-06-23 18:55:23 +0000176
George Burgess IVa3d62be2016-06-24 01:00:03 +0000177// Interprocedural attribute tagging that CFLGraph may not easily model
178struct InterprocAttr {
179 InterprocNode Node;
180 StratifiedAttrs Attr;
George Burgess IV1f99da52016-06-23 18:55:23 +0000181};
182
George Burgess IVcae581d2016-04-13 23:27:37 +0000183/// Gets the edges our graph should have, based on an Instruction*
Hal Finkel7529c552014-09-02 21:43:13 +0000184class GetEdgesVisitor : public InstVisitor<GetEdgesVisitor, void> {
George Burgess IVbfa401e2016-07-06 00:26:41 +0000185 CFLSteensAAResult &AA;
George Burgess IV18b83fe2016-06-01 18:39:54 +0000186 const TargetLibraryInfo &TLI;
Hal Finkel7529c552014-09-02 21:43:13 +0000187
George Burgess IV24eb0da2016-06-14 18:12:28 +0000188 CFLGraph &Graph;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000189 SmallVectorImpl<Value *> &ReturnValues;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000190 SmallPtrSetImpl<Value *> &Externals;
191 SmallPtrSetImpl<Value *> &Escapes;
George Burgess IV1f99da52016-06-23 18:55:23 +0000192 SmallVectorImpl<InterprocEdge> &InterprocEdges;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000193 SmallVectorImpl<InterprocAttr> &InterprocAttrs;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000194
195 static bool hasUsefulEdges(ConstantExpr *CE) {
196 // ConstantExpr doesn't have terminators, invokes, or fences, so only needs
197 // to check for compares.
198 return CE->getOpcode() != Instruction::ICmp &&
199 CE->getOpcode() != Instruction::FCmp;
200 }
201
202 void addNode(Value *Val) {
203 if (!Graph.addNode(Val))
204 return;
205
206 if (isa<GlobalValue>(Val))
207 Externals.insert(Val);
208 else if (auto CExpr = dyn_cast<ConstantExpr>(Val))
209 if (hasUsefulEdges(CExpr))
210 visitConstantExpr(CExpr);
211 }
212
George Burgess IV259d9012016-06-15 20:43:41 +0000213 void addNodeWithAttr(Value *Val, StratifiedAttrs Attr) {
214 addNode(Val);
215 Graph.addAttr(Val, Attr);
216 }
217
218 void addEdge(Value *From, Value *To, EdgeType Type) {
219 if (!From->getType()->isPointerTy() || !To->getType()->isPointerTy())
220 return;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000221 addNode(From);
222 if (To != From)
223 addNode(To);
George Burgess IV259d9012016-06-15 20:43:41 +0000224 Graph.addEdge(From, To, Type);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000225 }
226
Hal Finkel7529c552014-09-02 21:43:13 +0000227public:
George Burgess IVbfa401e2016-07-06 00:26:41 +0000228 GetEdgesVisitor(CFLSteensAAResult &AA, const TargetLibraryInfo &TLI,
George Burgess IVa3d62be2016-06-24 01:00:03 +0000229 CFLGraph &Graph, SmallVectorImpl<Value *> &ReturnValues,
230 SmallPtrSetImpl<Value *> &Externals,
George Burgess IV1f99da52016-06-23 18:55:23 +0000231 SmallPtrSetImpl<Value *> &Escapes,
George Burgess IVa3d62be2016-06-24 01:00:03 +0000232 SmallVectorImpl<InterprocEdge> &InterprocEdges,
233 SmallVectorImpl<InterprocAttr> &InterprocAttrs)
234 : AA(AA), TLI(TLI), Graph(Graph), ReturnValues(ReturnValues),
235 Externals(Externals), Escapes(Escapes), InterprocEdges(InterprocEdges),
236 InterprocAttrs(InterprocAttrs) {}
Hal Finkel7529c552014-09-02 21:43:13 +0000237
238 void visitInstruction(Instruction &) {
239 llvm_unreachable("Unsupported instruction encountered");
240 }
241
George Burgess IVa3d62be2016-06-24 01:00:03 +0000242 void visitReturnInst(ReturnInst &Inst) {
243 if (auto RetVal = Inst.getReturnValue()) {
244 if (RetVal->getType()->isPointerTy()) {
245 addNode(RetVal);
246 ReturnValues.push_back(RetVal);
247 }
248 }
249 }
250
George Burgess IVb54a8d622015-03-10 02:40:06 +0000251 void visitPtrToIntInst(PtrToIntInst &Inst) {
252 auto *Ptr = Inst.getOperand(0);
George Burgess IV259d9012016-06-15 20:43:41 +0000253 addNodeWithAttr(Ptr, AttrEscaped);
George Burgess IVb54a8d622015-03-10 02:40:06 +0000254 }
255
256 void visitIntToPtrInst(IntToPtrInst &Inst) {
257 auto *Ptr = &Inst;
George Burgess IV259d9012016-06-15 20:43:41 +0000258 addNodeWithAttr(Ptr, AttrUnknown);
George Burgess IVb54a8d622015-03-10 02:40:06 +0000259 }
260
Hal Finkel7529c552014-09-02 21:43:13 +0000261 void visitCastInst(CastInst &Inst) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000262 auto *Src = Inst.getOperand(0);
George Burgess IV259d9012016-06-15 20:43:41 +0000263 addEdge(Src, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000264 }
265
266 void visitBinaryOperator(BinaryOperator &Inst) {
267 auto *Op1 = Inst.getOperand(0);
268 auto *Op2 = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000269 addEdge(Op1, &Inst, EdgeType::Assign);
270 addEdge(Op2, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000271 }
272
273 void visitAtomicCmpXchgInst(AtomicCmpXchgInst &Inst) {
274 auto *Ptr = Inst.getPointerOperand();
275 auto *Val = Inst.getNewValOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000276 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000277 }
278
279 void visitAtomicRMWInst(AtomicRMWInst &Inst) {
280 auto *Ptr = Inst.getPointerOperand();
281 auto *Val = Inst.getValOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000282 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000283 }
284
285 void visitPHINode(PHINode &Inst) {
George Burgess IV77351ba32016-01-28 00:54:01 +0000286 for (Value *Val : Inst.incoming_values())
George Burgess IV259d9012016-06-15 20:43:41 +0000287 addEdge(Val, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000288 }
289
290 void visitGetElementPtrInst(GetElementPtrInst &Inst) {
291 auto *Op = Inst.getPointerOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000292 addEdge(Op, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000293 }
294
295 void visitSelectInst(SelectInst &Inst) {
Daniel Berlin16f7a522015-01-26 17:31:17 +0000296 // Condition is not processed here (The actual statement producing
297 // the condition result is processed elsewhere). For select, the
298 // condition is evaluated, but not loaded, stored, or assigned
299 // simply as a result of being the condition of a select.
300
Hal Finkel7529c552014-09-02 21:43:13 +0000301 auto *TrueVal = Inst.getTrueValue();
Hal Finkel7529c552014-09-02 21:43:13 +0000302 auto *FalseVal = Inst.getFalseValue();
George Burgess IV259d9012016-06-15 20:43:41 +0000303 addEdge(TrueVal, &Inst, EdgeType::Assign);
304 addEdge(FalseVal, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000305 }
306
George Burgess IV24eb0da2016-06-14 18:12:28 +0000307 void visitAllocaInst(AllocaInst &Inst) { Graph.addNode(&Inst); }
Hal Finkel7529c552014-09-02 21:43:13 +0000308
309 void visitLoadInst(LoadInst &Inst) {
310 auto *Ptr = Inst.getPointerOperand();
311 auto *Val = &Inst;
George Burgess IV259d9012016-06-15 20:43:41 +0000312 addEdge(Val, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000313 }
314
315 void visitStoreInst(StoreInst &Inst) {
316 auto *Ptr = Inst.getPointerOperand();
317 auto *Val = Inst.getValueOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000318 addEdge(Ptr, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000319 }
320
Hal Finkeldb5f86a2014-10-14 20:51:26 +0000321 void visitVAArgInst(VAArgInst &Inst) {
322 // We can't fully model va_arg here. For *Ptr = Inst.getOperand(0), it does
323 // two things:
324 // 1. Loads a value from *((T*)*Ptr).
325 // 2. Increments (stores to) *Ptr by some target-specific amount.
326 // For now, we'll handle this like a landingpad instruction (by placing the
327 // result in its own group, and having that group alias externals).
George Burgess IV259d9012016-06-15 20:43:41 +0000328 addNodeWithAttr(&Inst, AttrUnknown);
Hal Finkeldb5f86a2014-10-14 20:51:26 +0000329 }
330
Hal Finkel7529c552014-09-02 21:43:13 +0000331 static bool isFunctionExternal(Function *Fn) {
George Burgess IV9fdbfe12016-06-21 01:42:47 +0000332 return !Fn->hasExactDefinition();
Hal Finkel7529c552014-09-02 21:43:13 +0000333 }
334
George Burgess IV87b2e412016-06-20 23:10:56 +0000335 bool tryInterproceduralAnalysis(CallSite CS,
336 const SmallVectorImpl<Function *> &Fns) {
Hal Finkel7529c552014-09-02 21:43:13 +0000337 assert(Fns.size() > 0);
338
George Burgess IV87b2e412016-06-20 23:10:56 +0000339 if (CS.arg_size() > MaxSupportedArgsInSummary)
Hal Finkel7529c552014-09-02 21:43:13 +0000340 return false;
341
342 // Exit early if we'll fail anyway
343 for (auto *Fn : Fns) {
344 if (isFunctionExternal(Fn) || Fn->isVarArg())
345 return false;
George Burgess IV87b2e412016-06-20 23:10:56 +0000346 // Fail if the caller does not provide enough arguments
347 assert(Fn->arg_size() <= CS.arg_size());
Hal Finkel7529c552014-09-02 21:43:13 +0000348 auto &MaybeInfo = AA.ensureCached(Fn);
349 if (!MaybeInfo.hasValue())
350 return false;
351 }
352
George Burgess IVa3d62be2016-06-24 01:00:03 +0000353 auto InstantiateInterfaceIndex = [&CS](unsigned Index) {
354 auto Value =
355 (Index == 0) ? CS.getInstruction() : CS.getArgument(Index - 1);
356 return Value->getType()->isPointerTy() ? Value : nullptr;
357 };
358
Hal Finkel7529c552014-09-02 21:43:13 +0000359 for (auto *Fn : Fns) {
George Burgess IV87b2e412016-06-20 23:10:56 +0000360 auto &FnInfo = AA.ensureCached(Fn);
361 assert(FnInfo.hasValue());
Hal Finkel7529c552014-09-02 21:43:13 +0000362
George Burgess IV87b2e412016-06-20 23:10:56 +0000363 auto &RetParamRelations = FnInfo->getRetParamRelations();
364 for (auto &Relation : RetParamRelations) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000365 auto FromVal = InstantiateInterfaceIndex(Relation.From.Index);
366 auto ToVal = InstantiateInterfaceIndex(Relation.To.Index);
367 if (FromVal && ToVal) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000368 auto FromLevel = Relation.From.DerefLevel;
369 auto ToLevel = Relation.To.DerefLevel;
370 InterprocEdges.push_back(
George Burgess IVa3d62be2016-06-24 01:00:03 +0000371 InterprocEdge{InterprocNode{FromVal, FromLevel},
372 InterprocNode{ToVal, ToLevel}});
373 }
374 }
375
376 auto &RetParamAttributes = FnInfo->getRetParamAttributes();
377 for (auto &Attribute : RetParamAttributes) {
378 if (auto Val = InstantiateInterfaceIndex(Attribute.IValue.Index)) {
379 InterprocAttrs.push_back(InterprocAttr{
380 InterprocNode{Val, Attribute.IValue.DerefLevel}, Attribute.Attr});
George Burgess IV1f99da52016-06-23 18:55:23 +0000381 }
Hal Finkel7529c552014-09-02 21:43:13 +0000382 }
George Burgess IV259d9012016-06-15 20:43:41 +0000383 }
George Burgess IV24eb0da2016-06-14 18:12:28 +0000384
Hal Finkel7529c552014-09-02 21:43:13 +0000385 return true;
386 }
387
George Burgess IV24eb0da2016-06-14 18:12:28 +0000388 void visitCallSite(CallSite CS) {
389 auto Inst = CS.getInstruction();
390
391 // Make sure all arguments and return value are added to the graph first
392 for (Value *V : CS.args())
393 addNode(V);
George Burgess IV87b2e412016-06-20 23:10:56 +0000394 if (Inst->getType()->isPointerTy())
George Burgess IV24eb0da2016-06-14 18:12:28 +0000395 addNode(Inst);
396
George Burgess IV18b83fe2016-06-01 18:39:54 +0000397 // Check if Inst is a call to a library function that allocates/deallocates
398 // on the heap. Those kinds of functions do not introduce any aliases.
399 // TODO: address other common library functions such as realloc(), strdup(),
400 // etc.
George Burgess IV24eb0da2016-06-14 18:12:28 +0000401 if (isMallocLikeFn(Inst, &TLI) || isCallocLikeFn(Inst, &TLI) ||
402 isFreeCall(Inst, &TLI))
George Burgess IV18b83fe2016-06-01 18:39:54 +0000403 return;
George Burgess IV18b83fe2016-06-01 18:39:54 +0000404
George Burgess IV68b36e02015-08-28 00:16:18 +0000405 // TODO: Add support for noalias args/all the other fun function attributes
406 // that we can tack on.
Hal Finkel7529c552014-09-02 21:43:13 +0000407 SmallVector<Function *, 4> Targets;
George Burgess IV24eb0da2016-06-14 18:12:28 +0000408 if (getPossibleTargets(CS, Targets))
George Burgess IV87b2e412016-06-20 23:10:56 +0000409 if (tryInterproceduralAnalysis(CS, Targets))
Hal Finkel7529c552014-09-02 21:43:13 +0000410 return;
Hal Finkel7529c552014-09-02 21:43:13 +0000411
George Burgess IV68b36e02015-08-28 00:16:18 +0000412 // Because the function is opaque, we need to note that anything
George Burgess IV24eb0da2016-06-14 18:12:28 +0000413 // could have happened to the arguments (unless the function is marked
414 // readonly or readnone), and that the result could alias just about
415 // anything, too (unless the result is marked noalias).
416 if (!CS.onlyReadsMemory())
417 for (Value *V : CS.args()) {
George Burgess IV259d9012016-06-15 20:43:41 +0000418 if (V->getType()->isPointerTy())
419 Escapes.insert(V);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000420 }
421
George Burgess IV87b2e412016-06-20 23:10:56 +0000422 if (Inst->getType()->isPointerTy()) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000423 auto *Fn = CS.getCalledFunction();
424 if (Fn == nullptr || !Fn->doesNotAlias(0))
George Burgess IV259d9012016-06-15 20:43:41 +0000425 Graph.addAttr(Inst, AttrUnknown);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000426 }
Hal Finkel7529c552014-09-02 21:43:13 +0000427 }
428
George Burgess IVcae581d2016-04-13 23:27:37 +0000429 /// Because vectors/aggregates are immutable and unaddressable, there's
430 /// nothing we can do to coax a value out of them, other than calling
431 /// Extract{Element,Value}. We can effectively treat them as pointers to
432 /// arbitrary memory locations we can store in and load from.
Hal Finkel7529c552014-09-02 21:43:13 +0000433 void visitExtractElementInst(ExtractElementInst &Inst) {
434 auto *Ptr = Inst.getVectorOperand();
435 auto *Val = &Inst;
George Burgess IV259d9012016-06-15 20:43:41 +0000436 addEdge(Val, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000437 }
438
439 void visitInsertElementInst(InsertElementInst &Inst) {
440 auto *Vec = Inst.getOperand(0);
441 auto *Val = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000442 addEdge(Vec, &Inst, EdgeType::Assign);
443 addEdge(&Inst, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000444 }
445
446 void visitLandingPadInst(LandingPadInst &Inst) {
447 // Exceptions come from "nowhere", from our analysis' perspective.
448 // So we place the instruction its own group, noting that said group may
449 // alias externals
George Burgess IV259d9012016-06-15 20:43:41 +0000450 addNodeWithAttr(&Inst, AttrUnknown);
Hal Finkel7529c552014-09-02 21:43:13 +0000451 }
452
453 void visitInsertValueInst(InsertValueInst &Inst) {
454 auto *Agg = Inst.getOperand(0);
455 auto *Val = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000456 addEdge(Agg, &Inst, EdgeType::Assign);
457 addEdge(&Inst, Val, EdgeType::Dereference);
Hal Finkel7529c552014-09-02 21:43:13 +0000458 }
459
460 void visitExtractValueInst(ExtractValueInst &Inst) {
461 auto *Ptr = Inst.getAggregateOperand();
George Burgess IV259d9012016-06-15 20:43:41 +0000462 addEdge(&Inst, Ptr, EdgeType::Reference);
Hal Finkel7529c552014-09-02 21:43:13 +0000463 }
464
465 void visitShuffleVectorInst(ShuffleVectorInst &Inst) {
466 auto *From1 = Inst.getOperand(0);
467 auto *From2 = Inst.getOperand(1);
George Burgess IV259d9012016-06-15 20:43:41 +0000468 addEdge(From1, &Inst, EdgeType::Assign);
469 addEdge(From2, &Inst, EdgeType::Assign);
Hal Finkel7529c552014-09-02 21:43:13 +0000470 }
Pete Cooper36642532015-06-12 16:13:54 +0000471
472 void visitConstantExpr(ConstantExpr *CE) {
473 switch (CE->getOpcode()) {
474 default:
475 llvm_unreachable("Unknown instruction type encountered!");
476// Build the switch statement using the Instruction.def file.
477#define HANDLE_INST(NUM, OPCODE, CLASS) \
478 case Instruction::OPCODE: \
479 visit##OPCODE(*(CLASS *)CE); \
480 break;
481#include "llvm/IR/Instruction.def"
482 }
483 }
Hal Finkel7529c552014-09-02 21:43:13 +0000484};
485
George Burgess IVe17756e2016-06-14 18:02:27 +0000486class CFLGraphBuilder {
487 // Input of the builder
George Burgess IVbfa401e2016-07-06 00:26:41 +0000488 CFLSteensAAResult &Analysis;
George Burgess IVe17756e2016-06-14 18:02:27 +0000489 const TargetLibraryInfo &TLI;
490
491 // Output of the builder
492 CFLGraph Graph;
493 SmallVector<Value *, 4> ReturnedValues;
494
495 // Auxiliary structures used by the builder
George Burgess IV24eb0da2016-06-14 18:12:28 +0000496 SmallPtrSet<Value *, 8> ExternalValues;
497 SmallPtrSet<Value *, 8> EscapedValues;
George Burgess IV1f99da52016-06-23 18:55:23 +0000498 SmallVector<InterprocEdge, 8> InterprocEdges;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000499 SmallVector<InterprocAttr, 8> InterprocAttrs;
George Burgess IVe17756e2016-06-14 18:02:27 +0000500
501 // Helper functions
502
503 // Determines whether or not we an instruction is useless to us (e.g.
504 // FenceInst)
505 static bool hasUsefulEdges(Instruction *Inst) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000506 bool IsNonInvokeRetTerminator = isa<TerminatorInst>(Inst) &&
507 !isa<InvokeInst>(Inst) &&
508 !isa<ReturnInst>(Inst);
George Burgess IVe17756e2016-06-14 18:02:27 +0000509 return !isa<CmpInst>(Inst) && !isa<FenceInst>(Inst) &&
George Burgess IVa3d62be2016-06-24 01:00:03 +0000510 !IsNonInvokeRetTerminator;
George Burgess IVe17756e2016-06-14 18:02:27 +0000511 }
512
George Burgess IV24eb0da2016-06-14 18:12:28 +0000513 void addArgumentToGraph(Argument &Arg) {
George Burgess IV259d9012016-06-15 20:43:41 +0000514 if (Arg.getType()->isPointerTy()) {
515 Graph.addNode(&Arg);
516 ExternalValues.insert(&Arg);
517 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000518 }
519
520 // Given an Instruction, this will add it to the graph, along with any
521 // Instructions that are potentially only available from said Instruction
522 // For example, given the following line:
523 // %0 = load i16* getelementptr ([1 x i16]* @a, 0, 0), align 2
524 // addInstructionToGraph would add both the `load` and `getelementptr`
525 // instructions to the graph appropriately.
526 void addInstructionToGraph(Instruction &Inst) {
George Burgess IVe17756e2016-06-14 18:02:27 +0000527 if (!hasUsefulEdges(&Inst))
528 return;
529
George Burgess IVa3d62be2016-06-24 01:00:03 +0000530 GetEdgesVisitor(Analysis, TLI, Graph, ReturnedValues, ExternalValues,
531 EscapedValues, InterprocEdges, InterprocAttrs)
George Burgess IV24eb0da2016-06-14 18:12:28 +0000532 .visit(Inst);
533 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000534
George Burgess IV24eb0da2016-06-14 18:12:28 +0000535 // Builds the graph needed for constructing the StratifiedSets for the given
536 // function
537 void buildGraphFrom(Function &Fn) {
538 for (auto &Bb : Fn.getBasicBlockList())
539 for (auto &Inst : Bb.getInstList())
540 addInstructionToGraph(Inst);
George Burgess IVe17756e2016-06-14 18:02:27 +0000541
George Burgess IV24eb0da2016-06-14 18:12:28 +0000542 for (auto &Arg : Fn.args())
543 addArgumentToGraph(Arg);
George Burgess IVe17756e2016-06-14 18:02:27 +0000544 }
545
546public:
George Burgess IVbfa401e2016-07-06 00:26:41 +0000547 CFLGraphBuilder(CFLSteensAAResult &Analysis, const TargetLibraryInfo &TLI,
George Burgess IVe17756e2016-06-14 18:02:27 +0000548 Function &Fn)
549 : Analysis(Analysis), TLI(TLI) {
550 buildGraphFrom(Fn);
551 }
552
George Burgess IV87b2e412016-06-20 23:10:56 +0000553 const CFLGraph &getCFLGraph() const { return Graph; }
554 const SmallVector<Value *, 4> &getReturnValues() const {
555 return ReturnedValues;
George Burgess IVe17756e2016-06-14 18:02:27 +0000556 }
George Burgess IV87b2e412016-06-20 23:10:56 +0000557 const SmallPtrSet<Value *, 8> &getExternalValues() const {
558 return ExternalValues;
559 }
560 const SmallPtrSet<Value *, 8> &getEscapedValues() const {
561 return EscapedValues;
562 }
George Burgess IV1f99da52016-06-23 18:55:23 +0000563 const SmallVector<InterprocEdge, 8> &getInterprocEdges() const {
564 return InterprocEdges;
565 }
George Burgess IVa3d62be2016-06-24 01:00:03 +0000566 const SmallVector<InterprocAttr, 8> &getInterprocAttrs() const {
567 return InterprocAttrs;
568 }
George Burgess IVe17756e2016-06-14 18:02:27 +0000569};
Alexander Kornienkof00654e2015-06-23 09:49:53 +0000570}
Hal Finkel7529c552014-09-02 21:43:13 +0000571
Hal Finkel7529c552014-09-02 21:43:13 +0000572//===----------------------------------------------------------------------===//
573// Function declarations that require types defined in the namespace above
574//===----------------------------------------------------------------------===//
575
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000576/// Given a StratifiedAttrs, returns true if it marks the corresponding values
577/// as globals or arguments
578static bool isGlobalOrArgAttr(StratifiedAttrs Attr);
Hal Finkel7529c552014-09-02 21:43:13 +0000579
George Burgess IV652ec4f2016-06-09 23:15:04 +0000580/// Given a StratifiedAttrs, returns true if the corresponding values come from
581/// an unknown source (such as opaque memory or an integer cast)
582static bool isUnknownAttr(StratifiedAttrs Attr);
583
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000584/// Given an argument number, returns the appropriate StratifiedAttr to set.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000585static StratifiedAttrs argNumberToAttr(unsigned ArgNum);
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000586
587/// Given a Value, potentially return which StratifiedAttr it maps to.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000588static Optional<StratifiedAttrs> valueToAttr(Value *Val);
Hal Finkel7529c552014-09-02 21:43:13 +0000589
George Burgess IVcae581d2016-04-13 23:27:37 +0000590/// Gets the "Level" that one should travel in StratifiedSets
591/// given an EdgeType.
Hal Finkel7529c552014-09-02 21:43:13 +0000592static Level directionOfEdgeType(EdgeType);
593
George Burgess IVcae581d2016-04-13 23:27:37 +0000594/// Determines whether it would be pointless to add the given Value to our sets.
George Burgess IVab03af22015-03-10 02:58:15 +0000595static bool canSkipAddingToSets(Value *Val);
596
Hal Finkel7529c552014-09-02 21:43:13 +0000597static Optional<Function *> parentFunctionOfValue(Value *Val) {
598 if (auto *Inst = dyn_cast<Instruction>(Val)) {
599 auto *Bb = Inst->getParent();
600 return Bb->getParent();
601 }
602
603 if (auto *Arg = dyn_cast<Argument>(Val))
604 return Arg->getParent();
George Burgess IV77351ba32016-01-28 00:54:01 +0000605 return None;
Hal Finkel7529c552014-09-02 21:43:13 +0000606}
607
George Burgess IV24eb0da2016-06-14 18:12:28 +0000608static bool getPossibleTargets(CallSite CS,
Hal Finkel7529c552014-09-02 21:43:13 +0000609 SmallVectorImpl<Function *> &Output) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000610 if (auto *Fn = CS.getCalledFunction()) {
Hal Finkel7529c552014-09-02 21:43:13 +0000611 Output.push_back(Fn);
612 return true;
613 }
614
615 // TODO: If the call is indirect, we might be able to enumerate all potential
616 // targets of the call and return them, rather than just failing.
617 return false;
618}
619
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000620static bool isGlobalOrArgAttr(StratifiedAttrs Attr) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000621 return Attr.reset(AttrEscapedIndex)
622 .reset(AttrUnknownIndex)
623 .reset(AttrCallerIndex)
624 .any();
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000625}
626
George Burgess IV652ec4f2016-06-09 23:15:04 +0000627static bool isUnknownAttr(StratifiedAttrs Attr) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000628 return Attr.test(AttrUnknownIndex) || Attr.test(AttrCallerIndex);
George Burgess IV652ec4f2016-06-09 23:15:04 +0000629}
630
George Burgess IVa3d62be2016-06-24 01:00:03 +0000631static Optional<StratifiedAttrs> valueToAttr(Value *Val) {
Hal Finkel7529c552014-09-02 21:43:13 +0000632 if (isa<GlobalValue>(Val))
George Burgess IVd9c39fc2016-06-24 01:41:29 +0000633 return StratifiedAttrs(AttrGlobal);
Hal Finkel7529c552014-09-02 21:43:13 +0000634
635 if (auto *Arg = dyn_cast<Argument>(Val))
Daniel Berlin16f7a522015-01-26 17:31:17 +0000636 // Only pointer arguments should have the argument attribute,
637 // because things can't escape through scalars without us seeing a
638 // cast, and thus, interaction with them doesn't matter.
639 if (!Arg->hasNoAliasAttr() && Arg->getType()->isPointerTy())
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000640 return argNumberToAttr(Arg->getArgNo());
George Burgess IV77351ba32016-01-28 00:54:01 +0000641 return None;
Hal Finkel7529c552014-09-02 21:43:13 +0000642}
643
George Burgess IVa3d62be2016-06-24 01:00:03 +0000644static StratifiedAttrs argNumberToAttr(unsigned ArgNum) {
George Burgess IV3c898c22015-01-21 16:37:21 +0000645 if (ArgNum >= AttrMaxNumArgs)
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000646 return AttrUnknown;
George Burgess IVf10c7fc2016-06-27 22:50:01 +0000647 // N.B. MSVC complains if we use `1U` here, since StratifiedAttrs' ctor takes
648 // an unsigned long long.
649 return StratifiedAttrs(1ULL << (ArgNum + AttrFirstArgIndex));
Hal Finkel7529c552014-09-02 21:43:13 +0000650}
651
Hal Finkel7529c552014-09-02 21:43:13 +0000652static Level directionOfEdgeType(EdgeType Weight) {
653 switch (Weight) {
654 case EdgeType::Reference:
655 return Level::Above;
656 case EdgeType::Dereference:
657 return Level::Below;
658 case EdgeType::Assign:
659 return Level::Same;
660 }
661 llvm_unreachable("Incomplete switch coverage");
662}
663
George Burgess IVab03af22015-03-10 02:58:15 +0000664static bool canSkipAddingToSets(Value *Val) {
665 // Constants can share instances, which may falsely unify multiple
666 // sets, e.g. in
667 // store i32* null, i32** %ptr1
668 // store i32* null, i32** %ptr2
669 // clearly ptr1 and ptr2 should not be unified into the same set, so
670 // we should filter out the (potentially shared) instance to
671 // i32* null.
672 if (isa<Constant>(Val)) {
George Burgess IVab03af22015-03-10 02:58:15 +0000673 // TODO: Because all of these things are constant, we can determine whether
674 // the data is *actually* mutable at graph building time. This will probably
675 // come for free/cheap with offset awareness.
Duncan P. N. Exon Smith1de3c7e2016-04-05 21:10:45 +0000676 bool CanStoreMutableData = isa<GlobalValue>(Val) ||
677 isa<ConstantExpr>(Val) ||
678 isa<ConstantAggregate>(Val);
George Burgess IVab03af22015-03-10 02:58:15 +0000679 return !CanStoreMutableData;
680 }
681
682 return false;
Hal Finkel7529c552014-09-02 21:43:13 +0000683}
684
George Burgess IVbfa401e2016-07-06 00:26:41 +0000685CFLSteensAAResult::FunctionInfo::FunctionInfo(
686 Function &Fn, const SmallVectorImpl<Value *> &RetVals,
687 StratifiedSets<Value *> S)
George Burgess IV87b2e412016-06-20 23:10:56 +0000688 : Sets(std::move(S)) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000689 // Historically, an arbitrary upper-bound of 50 args was selected. We may want
690 // to remove this if it doesn't really matter in practice.
691 if (Fn.arg_size() > MaxSupportedArgsInSummary)
692 return;
George Burgess IV87b2e412016-06-20 23:10:56 +0000693
George Burgess IV1f99da52016-06-23 18:55:23 +0000694 DenseMap<StratifiedIndex, InterfaceValue> InterfaceMap;
George Burgess IV87b2e412016-06-20 23:10:56 +0000695
George Burgess IV1f99da52016-06-23 18:55:23 +0000696 // Our intention here is to record all InterfaceValues that share the same
697 // StratifiedIndex in RetParamRelations. For each valid InterfaceValue, we
698 // have its StratifiedIndex scanned here and check if the index is presented
699 // in InterfaceMap: if it is not, we add the correspondence to the map;
700 // otherwise, an aliasing relation is found and we add it to
701 // RetParamRelations.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000702
George Burgess IVd14d05a2016-06-23 20:59:13 +0000703 auto AddToRetParamRelations = [&](unsigned InterfaceIndex,
704 StratifiedIndex SetIndex) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000705 unsigned Level = 0;
706 while (true) {
707 InterfaceValue CurrValue{InterfaceIndex, Level};
George Burgess IV87b2e412016-06-20 23:10:56 +0000708
George Burgess IV1f99da52016-06-23 18:55:23 +0000709 auto Itr = InterfaceMap.find(SetIndex);
710 if (Itr != InterfaceMap.end()) {
711 if (CurrValue != Itr->second)
712 RetParamRelations.push_back(ExternalRelation{CurrValue, Itr->second});
713 break;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000714 }
George Burgess IV87b2e412016-06-20 23:10:56 +0000715
George Burgess IV1f99da52016-06-23 18:55:23 +0000716 auto &Link = Sets.getLink(SetIndex);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000717 InterfaceMap.insert(std::make_pair(SetIndex, CurrValue));
George Burgess IVd9c39fc2016-06-24 01:41:29 +0000718 auto ExternalAttrs = Link.Attrs & StratifiedAttrs(ExternalAttrMask);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000719 if (ExternalAttrs.any())
720 RetParamAttributes.push_back(
721 ExternalAttribute{CurrValue, ExternalAttrs});
722
George Burgess IV1f99da52016-06-23 18:55:23 +0000723 if (!Link.hasBelow())
724 break;
George Burgess IV87b2e412016-06-20 23:10:56 +0000725
George Burgess IV1f99da52016-06-23 18:55:23 +0000726 ++Level;
727 SetIndex = Link.Below;
George Burgess IV87b2e412016-06-20 23:10:56 +0000728 }
George Burgess IV1f99da52016-06-23 18:55:23 +0000729 };
730
731 // Populate RetParamRelations for return values
732 for (auto *RetVal : RetVals) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000733 assert(RetVal != nullptr);
734 assert(RetVal->getType()->isPointerTy());
George Burgess IV1f99da52016-06-23 18:55:23 +0000735 auto RetInfo = Sets.find(RetVal);
736 if (RetInfo.hasValue())
737 AddToRetParamRelations(0, RetInfo->Index);
738 }
739
740 // Populate RetParamRelations for parameters
741 unsigned I = 0;
742 for (auto &Param : Fn.args()) {
743 if (Param.getType()->isPointerTy()) {
744 auto ParamInfo = Sets.find(&Param);
745 if (ParamInfo.hasValue())
746 AddToRetParamRelations(I + 1, ParamInfo->Index);
747 }
748 ++I;
George Burgess IV87b2e412016-06-20 23:10:56 +0000749 }
750}
751
Chandler Carruth8b046a42015-08-14 02:42:20 +0000752// Builds the graph + StratifiedSets for a function.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000753CFLSteensAAResult::FunctionInfo CFLSteensAAResult::buildSetsFrom(Function *Fn) {
George Burgess IVe17756e2016-06-14 18:02:27 +0000754 CFLGraphBuilder GraphBuilder(*this, TLI, *Fn);
755 StratifiedSetsBuilder<Value *> SetBuilder;
Hal Finkel7529c552014-09-02 21:43:13 +0000756
George Burgess IVe17756e2016-06-14 18:02:27 +0000757 auto &Graph = GraphBuilder.getCFLGraph();
George Burgess IVdc96feb2016-06-13 19:21:18 +0000758 SmallVector<Value *, 16> Worklist;
George Burgess IVdc96feb2016-06-13 19:21:18 +0000759 for (auto Node : Graph.nodes())
760 Worklist.push_back(Node);
761
762 while (!Worklist.empty()) {
763 auto *CurValue = Worklist.pop_back_val();
George Burgess IVe17756e2016-06-14 18:02:27 +0000764 SetBuilder.add(CurValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000765 if (canSkipAddingToSets(CurValue))
766 continue;
767
George Burgess IV259d9012016-06-15 20:43:41 +0000768 auto Attr = Graph.attrFor(CurValue);
769 SetBuilder.noteAttributes(CurValue, Attr);
770
George Burgess IVdc96feb2016-06-13 19:21:18 +0000771 for (const auto &Edge : Graph.edgesFor(CurValue)) {
772 auto Label = Edge.Type;
773 auto *OtherValue = Edge.Other;
774
775 if (canSkipAddingToSets(OtherValue))
Hal Finkel7529c552014-09-02 21:43:13 +0000776 continue;
777
George Burgess IVdc96feb2016-06-13 19:21:18 +0000778 bool Added;
779 switch (directionOfEdgeType(Label)) {
780 case Level::Above:
George Burgess IVe17756e2016-06-14 18:02:27 +0000781 Added = SetBuilder.addAbove(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000782 break;
783 case Level::Below:
George Burgess IVe17756e2016-06-14 18:02:27 +0000784 Added = SetBuilder.addBelow(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000785 break;
786 case Level::Same:
George Burgess IVe17756e2016-06-14 18:02:27 +0000787 Added = SetBuilder.addWith(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000788 break;
Hal Finkel7529c552014-09-02 21:43:13 +0000789 }
George Burgess IVdc96feb2016-06-13 19:21:18 +0000790
George Burgess IVdc96feb2016-06-13 19:21:18 +0000791 if (Added)
792 Worklist.push_back(OtherValue);
Hal Finkel7529c552014-09-02 21:43:13 +0000793 }
794 }
795
George Burgess IV652ec4f2016-06-09 23:15:04 +0000796 // Special handling for globals and arguments
George Burgess IV24eb0da2016-06-14 18:12:28 +0000797 for (auto *External : GraphBuilder.getExternalValues()) {
798 SetBuilder.add(External);
799 auto Attr = valueToAttr(External);
George Burgess IV652ec4f2016-06-09 23:15:04 +0000800 if (Attr.hasValue()) {
George Burgess IV24eb0da2016-06-14 18:12:28 +0000801 SetBuilder.noteAttributes(External, *Attr);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000802 if (*Attr == AttrGlobal)
803 SetBuilder.addAttributesBelow(External, 1, AttrUnknown);
804 else
805 SetBuilder.addAttributesBelow(External, 1, AttrCaller);
George Burgess IV652ec4f2016-06-09 23:15:04 +0000806 }
George Burgess IV24eb0da2016-06-14 18:12:28 +0000807 }
George Burgess IVab03af22015-03-10 02:58:15 +0000808
George Burgess IV1f99da52016-06-23 18:55:23 +0000809 // Special handling for interprocedural aliases
810 for (auto &Edge : GraphBuilder.getInterprocEdges()) {
George Burgess IVfe1397b2016-06-23 19:16:04 +0000811 auto FromVal = Edge.From.Val;
812 auto ToVal = Edge.To.Val;
George Burgess IV1f99da52016-06-23 18:55:23 +0000813 SetBuilder.add(FromVal);
814 SetBuilder.add(ToVal);
815 SetBuilder.addBelowWith(FromVal, Edge.From.DerefLevel, ToVal,
816 Edge.To.DerefLevel);
817 }
818
George Burgess IVa3d62be2016-06-24 01:00:03 +0000819 // Special handling for interprocedural attributes
820 for (auto &IPAttr : GraphBuilder.getInterprocAttrs()) {
821 auto Val = IPAttr.Node.Val;
822 SetBuilder.add(Val);
823 SetBuilder.addAttributesBelow(Val, IPAttr.Node.DerefLevel, IPAttr.Attr);
824 }
825
George Burgess IV1f99da52016-06-23 18:55:23 +0000826 // Special handling for opaque external functions
George Burgess IV24eb0da2016-06-14 18:12:28 +0000827 for (auto *Escape : GraphBuilder.getEscapedValues()) {
828 SetBuilder.add(Escape);
829 SetBuilder.noteAttributes(Escape, AttrEscaped);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000830 SetBuilder.addAttributesBelow(Escape, 1, AttrUnknown);
George Burgess IV24eb0da2016-06-14 18:12:28 +0000831 }
Hal Finkel7529c552014-09-02 21:43:13 +0000832
George Burgess IV87b2e412016-06-20 23:10:56 +0000833 return FunctionInfo(*Fn, GraphBuilder.getReturnValues(), SetBuilder.build());
Hal Finkel7529c552014-09-02 21:43:13 +0000834}
835
George Burgess IVbfa401e2016-07-06 00:26:41 +0000836void CFLSteensAAResult::scan(Function *Fn) {
Hal Finkel8d1590d2014-09-02 22:52:30 +0000837 auto InsertPair = Cache.insert(std::make_pair(Fn, Optional<FunctionInfo>()));
Hal Finkel7529c552014-09-02 21:43:13 +0000838 (void)InsertPair;
839 assert(InsertPair.second &&
840 "Trying to scan a function that has already been cached");
841
George Burgess IV6edb8912016-05-02 18:09:19 +0000842 // Note that we can't do Cache[Fn] = buildSetsFrom(Fn) here: the function call
843 // may get evaluated after operator[], potentially triggering a DenseMap
844 // resize and invalidating the reference returned by operator[]
845 auto FunInfo = buildSetsFrom(Fn);
846 Cache[Fn] = std::move(FunInfo);
847
Hal Finkel7529c552014-09-02 21:43:13 +0000848 Handles.push_front(FunctionHandle(Fn, this));
849}
850
George Burgess IVbfa401e2016-07-06 00:26:41 +0000851void CFLSteensAAResult::evict(Function *Fn) { Cache.erase(Fn); }
Chandler Carruth8b046a42015-08-14 02:42:20 +0000852
George Burgess IVcae581d2016-04-13 23:27:37 +0000853/// Ensures that the given function is available in the cache, and returns the
854/// entry.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000855const Optional<CFLSteensAAResult::FunctionInfo> &
856CFLSteensAAResult::ensureCached(Function *Fn) {
Chandler Carruth8b046a42015-08-14 02:42:20 +0000857 auto Iter = Cache.find(Fn);
858 if (Iter == Cache.end()) {
859 scan(Fn);
860 Iter = Cache.find(Fn);
861 assert(Iter != Cache.end());
862 assert(Iter->second.hasValue());
863 }
864 return Iter->second;
865}
866
George Burgess IVbfa401e2016-07-06 00:26:41 +0000867AliasResult CFLSteensAAResult::query(const MemoryLocation &LocA,
868 const MemoryLocation &LocB) {
Hal Finkel7529c552014-09-02 21:43:13 +0000869 auto *ValA = const_cast<Value *>(LocA.Ptr);
870 auto *ValB = const_cast<Value *>(LocB.Ptr);
871
George Burgess IV259d9012016-06-15 20:43:41 +0000872 if (!ValA->getType()->isPointerTy() || !ValB->getType()->isPointerTy())
873 return NoAlias;
874
Hal Finkel7529c552014-09-02 21:43:13 +0000875 Function *Fn = nullptr;
876 auto MaybeFnA = parentFunctionOfValue(ValA);
877 auto MaybeFnB = parentFunctionOfValue(ValB);
878 if (!MaybeFnA.hasValue() && !MaybeFnB.hasValue()) {
George Burgess IVcae581d2016-04-13 23:27:37 +0000879 // The only times this is known to happen are when globals + InlineAsm are
880 // involved
George Burgess IVbfa401e2016-07-06 00:26:41 +0000881 DEBUG(dbgs()
882 << "CFLSteensAA: could not extract parent function information.\n");
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000883 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000884 }
885
886 if (MaybeFnA.hasValue()) {
887 Fn = *MaybeFnA;
888 assert((!MaybeFnB.hasValue() || *MaybeFnB == *MaybeFnA) &&
889 "Interprocedural queries not supported");
890 } else {
891 Fn = *MaybeFnB;
892 }
893
894 assert(Fn != nullptr);
895 auto &MaybeInfo = ensureCached(Fn);
896 assert(MaybeInfo.hasValue());
897
George Burgess IV87b2e412016-06-20 23:10:56 +0000898 auto &Sets = MaybeInfo->getStratifiedSets();
Hal Finkel7529c552014-09-02 21:43:13 +0000899 auto MaybeA = Sets.find(ValA);
900 if (!MaybeA.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000901 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000902
903 auto MaybeB = Sets.find(ValB);
904 if (!MaybeB.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000905 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000906
907 auto SetA = *MaybeA;
908 auto SetB = *MaybeB;
Hal Finkel7529c552014-09-02 21:43:13 +0000909 auto AttrsA = Sets.getLink(SetA.Index).Attrs;
910 auto AttrsB = Sets.getLink(SetB.Index).Attrs;
George Burgess IV33305e72015-02-12 03:07:07 +0000911
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000912 // If both values are local (meaning the corresponding set has attribute
George Burgess IVbfa401e2016-07-06 00:26:41 +0000913 // AttrNone or AttrEscaped), then we know that CFLSteensAA fully models them:
914 // they may-alias each other if and only if they are in the same set.
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000915 // If at least one value is non-local (meaning it either is global/argument or
916 // it comes from unknown sources like integer cast), the situation becomes a
917 // bit more interesting. We follow three general rules described below:
918 // - Non-local values may alias each other
919 // - AttrNone values do not alias any non-local values
George Burgess IV652ec4f2016-06-09 23:15:04 +0000920 // - AttrEscaped do not alias globals/arguments, but they may alias
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000921 // AttrUnknown values
922 if (SetA.Index == SetB.Index)
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000923 return MayAlias;
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000924 if (AttrsA.none() || AttrsB.none())
925 return NoAlias;
George Burgess IV652ec4f2016-06-09 23:15:04 +0000926 if (isUnknownAttr(AttrsA) || isUnknownAttr(AttrsB))
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000927 return MayAlias;
928 if (isGlobalOrArgAttr(AttrsA) && isGlobalOrArgAttr(AttrsB))
929 return MayAlias;
930 return NoAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000931}
Mehdi Amini46a43552015-03-04 18:43:29 +0000932
George Burgess IVbfa401e2016-07-06 00:26:41 +0000933ModRefInfo CFLSteensAAResult::getArgModRefInfo(ImmutableCallSite CS,
934 unsigned ArgIdx) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000935 if (auto CalledFunc = CS.getCalledFunction()) {
936 auto &MaybeInfo = ensureCached(const_cast<Function *>(CalledFunc));
937 if (!MaybeInfo.hasValue())
938 return MRI_ModRef;
939 auto &RetParamAttributes = MaybeInfo->getRetParamAttributes();
940 auto &RetParamRelations = MaybeInfo->getRetParamRelations();
941
942 bool ArgAttributeIsWritten =
943 std::any_of(RetParamAttributes.begin(), RetParamAttributes.end(),
944 [ArgIdx](const ExternalAttribute &ExtAttr) {
945 return ExtAttr.IValue.Index == ArgIdx + 1;
946 });
947 bool ArgIsAccessed =
948 std::any_of(RetParamRelations.begin(), RetParamRelations.end(),
949 [ArgIdx](const ExternalRelation &ExtRelation) {
950 return ExtRelation.To.Index == ArgIdx + 1 ||
951 ExtRelation.From.Index == ArgIdx + 1;
952 });
953
954 return (!ArgIsAccessed && !ArgAttributeIsWritten) ? MRI_NoModRef
955 : MRI_ModRef;
956 }
957
958 return MRI_ModRef;
959}
960
George Burgess IVbfa401e2016-07-06 00:26:41 +0000961FunctionModRefBehavior
962CFLSteensAAResult::getModRefBehavior(ImmutableCallSite CS) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000963 // If we know the callee, try analyzing it
964 if (auto CalledFunc = CS.getCalledFunction())
965 return getModRefBehavior(CalledFunc);
966
967 // Otherwise, be conservative
968 return FMRB_UnknownModRefBehavior;
969}
970
George Burgess IVbfa401e2016-07-06 00:26:41 +0000971FunctionModRefBehavior CFLSteensAAResult::getModRefBehavior(const Function *F) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000972 assert(F != nullptr);
973
974 // TODO: Remove the const_cast
975 auto &MaybeInfo = ensureCached(const_cast<Function *>(F));
976 if (!MaybeInfo.hasValue())
977 return FMRB_UnknownModRefBehavior;
978 auto &RetParamAttributes = MaybeInfo->getRetParamAttributes();
979 auto &RetParamRelations = MaybeInfo->getRetParamRelations();
980
981 // First, if any argument is marked Escpaed, Unknown or Global, anything may
982 // happen to them and thus we can't draw any conclusion.
983 if (!RetParamAttributes.empty())
984 return FMRB_UnknownModRefBehavior;
985
986 // Currently we don't (and can't) distinguish reads from writes in
987 // RetParamRelations. All we can say is whether there may be memory access or
988 // not.
989 if (RetParamRelations.empty())
990 return FMRB_DoesNotAccessMemory;
991
992 // Check if something beyond argmem gets touched.
993 bool AccessArgMemoryOnly =
994 std::all_of(RetParamRelations.begin(), RetParamRelations.end(),
995 [](const ExternalRelation &ExtRelation) {
996 // Both DerefLevels has to be 0, since we don't know which
997 // one is a read and which is a write.
998 return ExtRelation.From.DerefLevel == 0 &&
999 ExtRelation.To.DerefLevel == 0;
1000 });
1001 return AccessArgMemoryOnly ? FMRB_OnlyAccessesArgumentPointees
1002 : FMRB_UnknownModRefBehavior;
1003}
1004
George Burgess IVbfa401e2016-07-06 00:26:41 +00001005char CFLSteensAA::PassID;
Chandler Carruthb4faf132016-03-11 10:22:49 +00001006
George Burgess IVbfa401e2016-07-06 00:26:41 +00001007CFLSteensAAResult CFLSteensAA::run(Function &F, AnalysisManager<Function> &AM) {
1008 return CFLSteensAAResult(AM.getResult<TargetLibraryAnalysis>(F));
Chandler Carruth7b560d42015-09-09 17:55:00 +00001009}
1010
George Burgess IVbfa401e2016-07-06 00:26:41 +00001011char CFLSteensAAWrapperPass::ID = 0;
1012INITIALIZE_PASS(CFLSteensAAWrapperPass, "cfl-steens-aa",
1013 "Unification-Based CFL Alias Analysis", false, true)
Chandler Carruth7b560d42015-09-09 17:55:00 +00001014
George Burgess IVbfa401e2016-07-06 00:26:41 +00001015ImmutablePass *llvm::createCFLSteensAAWrapperPass() {
1016 return new CFLSteensAAWrapperPass();
Chandler Carruth7b560d42015-09-09 17:55:00 +00001017}
1018
George Burgess IVbfa401e2016-07-06 00:26:41 +00001019CFLSteensAAWrapperPass::CFLSteensAAWrapperPass() : ImmutablePass(ID) {
1020 initializeCFLSteensAAWrapperPassPass(*PassRegistry::getPassRegistry());
1021}
1022
1023void CFLSteensAAWrapperPass::initializePass() {
George Burgess IV18b83fe2016-06-01 18:39:54 +00001024 auto &TLIWP = getAnalysis<TargetLibraryInfoWrapperPass>();
George Burgess IVbfa401e2016-07-06 00:26:41 +00001025 Result.reset(new CFLSteensAAResult(TLIWP.getTLI()));
Chandler Carruth7b560d42015-09-09 17:55:00 +00001026}
1027
George Burgess IVbfa401e2016-07-06 00:26:41 +00001028void CFLSteensAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
Chandler Carruth7b560d42015-09-09 17:55:00 +00001029 AU.setPreservesAll();
George Burgess IV18b83fe2016-06-01 18:39:54 +00001030 AU.addRequired<TargetLibraryInfoWrapperPass>();
Mehdi Amini46a43552015-03-04 18:43:29 +00001031}