blob: ae2430fd4b2f73e808f8004497380b0b64372511 [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/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/Pass.h"
Hal Finkel7d7087c2014-09-02 22:13:00 +000048#include "llvm/Support/Compiler.h"
George Burgess IV33305e72015-02-12 03:07:07 +000049#include "llvm/Support/Debug.h"
Hal Finkel7529c552014-09-02 21:43:13 +000050#include "llvm/Support/ErrorHandling.h"
Benjamin Kramer799003b2015-03-23 19:32:43 +000051#include "llvm/Support/raw_ostream.h"
Hal Finkel7529c552014-09-02 21:43:13 +000052#include <algorithm>
53#include <cassert>
Benjamin Kramer799003b2015-03-23 19:32:43 +000054#include <memory>
Hal Finkel7529c552014-09-02 21:43:13 +000055#include <tuple>
56
57using namespace llvm;
George Burgess IV1ca8aff2016-07-06 00:36:12 +000058using namespace llvm::cflaa;
Hal Finkel7529c552014-09-02 21:43:13 +000059
George Burgess IVbfa401e2016-07-06 00:26:41 +000060#define DEBUG_TYPE "cfl-steens-aa"
George Burgess IV33305e72015-02-12 03:07:07 +000061
George Burgess IVbfa401e2016-07-06 00:26:41 +000062CFLSteensAAResult::CFLSteensAAResult(const TargetLibraryInfo &TLI)
George Burgess IV18b83fe2016-06-01 18:39:54 +000063 : AAResultBase(), TLI(TLI) {}
George Burgess IVbfa401e2016-07-06 00:26:41 +000064CFLSteensAAResult::CFLSteensAAResult(CFLSteensAAResult &&Arg)
George Burgess IV18b83fe2016-06-01 18:39:54 +000065 : AAResultBase(std::move(Arg)), TLI(Arg.TLI) {}
George Burgess IVbfa401e2016-07-06 00:26:41 +000066CFLSteensAAResult::~CFLSteensAAResult() {}
Chandler Carruth8b046a42015-08-14 02:42:20 +000067
George Burgess IV87b2e412016-06-20 23:10:56 +000068/// Information we have about a function and would like to keep around.
George Burgess IVbfa401e2016-07-06 00:26:41 +000069class CFLSteensAAResult::FunctionInfo {
George Burgess IV87b2e412016-06-20 23:10:56 +000070 StratifiedSets<Value *> Sets;
George Burgess IVc294d0d2016-07-09 02:54:42 +000071 AliasSummary Summary;
George Burgess IVa3d62be2016-06-24 01:00:03 +000072
George Burgess IV87b2e412016-06-20 23:10:56 +000073public:
74 FunctionInfo(Function &Fn, const SmallVectorImpl<Value *> &RetVals,
75 StratifiedSets<Value *> S);
76
77 const StratifiedSets<Value *> &getStratifiedSets() const { return Sets; }
George Burgess IVc294d0d2016-07-09 02:54:42 +000078 const AliasSummary &getAliasSummary() const { return Summary; }
Chandler Carruth8b046a42015-08-14 02:42:20 +000079};
80
George Burgess IVcae581d2016-04-13 23:27:37 +000081/// Try to go from a Value* to a Function*. Never returns nullptr.
Hal Finkel7529c552014-09-02 21:43:13 +000082static Optional<Function *> parentFunctionOfValue(Value *);
83
Hal Finkel1ae325f2014-09-02 23:50:01 +000084const StratifiedIndex StratifiedLink::SetSentinel =
George Burgess IV11d509d2015-03-15 00:52:21 +000085 std::numeric_limits<StratifiedIndex>::max();
Hal Finkel1ae325f2014-09-02 23:50:01 +000086
Hal Finkel7529c552014-09-02 21:43:13 +000087namespace {
Hal Finkel7529c552014-09-02 21:43:13 +000088
George Burgess IVcae581d2016-04-13 23:27:37 +000089/// StratifiedSets call for knowledge of "direction", so this is how we
90/// represent that locally.
Hal Finkel7529c552014-09-02 21:43:13 +000091enum class Level { Same, Above, Below };
Alexander Kornienkof00654e2015-06-23 09:49:53 +000092}
Hal Finkel7529c552014-09-02 21:43:13 +000093
Hal Finkel7529c552014-09-02 21:43:13 +000094//===----------------------------------------------------------------------===//
95// Function declarations that require types defined in the namespace above
96//===----------------------------------------------------------------------===//
97
George Burgess IVcae581d2016-04-13 23:27:37 +000098/// Gets the "Level" that one should travel in StratifiedSets
99/// given an EdgeType.
Hal Finkel7529c552014-09-02 21:43:13 +0000100static Level directionOfEdgeType(EdgeType);
101
George Burgess IVcae581d2016-04-13 23:27:37 +0000102/// Determines whether it would be pointless to add the given Value to our sets.
George Burgess IVab03af22015-03-10 02:58:15 +0000103static bool canSkipAddingToSets(Value *Val);
104
Hal Finkel7529c552014-09-02 21:43:13 +0000105static Optional<Function *> parentFunctionOfValue(Value *Val) {
106 if (auto *Inst = dyn_cast<Instruction>(Val)) {
107 auto *Bb = Inst->getParent();
108 return Bb->getParent();
109 }
110
111 if (auto *Arg = dyn_cast<Argument>(Val))
112 return Arg->getParent();
George Burgess IV77351ba32016-01-28 00:54:01 +0000113 return None;
Hal Finkel7529c552014-09-02 21:43:13 +0000114}
115
Hal Finkel7529c552014-09-02 21:43:13 +0000116static Level directionOfEdgeType(EdgeType Weight) {
117 switch (Weight) {
118 case EdgeType::Reference:
119 return Level::Above;
120 case EdgeType::Dereference:
121 return Level::Below;
122 case EdgeType::Assign:
123 return Level::Same;
124 }
125 llvm_unreachable("Incomplete switch coverage");
126}
127
George Burgess IVab03af22015-03-10 02:58:15 +0000128static bool canSkipAddingToSets(Value *Val) {
129 // Constants can share instances, which may falsely unify multiple
130 // sets, e.g. in
131 // store i32* null, i32** %ptr1
132 // store i32* null, i32** %ptr2
133 // clearly ptr1 and ptr2 should not be unified into the same set, so
134 // we should filter out the (potentially shared) instance to
135 // i32* null.
136 if (isa<Constant>(Val)) {
George Burgess IVab03af22015-03-10 02:58:15 +0000137 // TODO: Because all of these things are constant, we can determine whether
138 // the data is *actually* mutable at graph building time. This will probably
139 // come for free/cheap with offset awareness.
Duncan P. N. Exon Smith1de3c7e2016-04-05 21:10:45 +0000140 bool CanStoreMutableData = isa<GlobalValue>(Val) ||
141 isa<ConstantExpr>(Val) ||
142 isa<ConstantAggregate>(Val);
George Burgess IVab03af22015-03-10 02:58:15 +0000143 return !CanStoreMutableData;
144 }
145
146 return false;
Hal Finkel7529c552014-09-02 21:43:13 +0000147}
148
George Burgess IVbfa401e2016-07-06 00:26:41 +0000149CFLSteensAAResult::FunctionInfo::FunctionInfo(
150 Function &Fn, const SmallVectorImpl<Value *> &RetVals,
151 StratifiedSets<Value *> S)
George Burgess IV87b2e412016-06-20 23:10:56 +0000152 : Sets(std::move(S)) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000153 // Historically, an arbitrary upper-bound of 50 args was selected. We may want
154 // to remove this if it doesn't really matter in practice.
155 if (Fn.arg_size() > MaxSupportedArgsInSummary)
156 return;
George Burgess IV87b2e412016-06-20 23:10:56 +0000157
George Burgess IV1f99da52016-06-23 18:55:23 +0000158 DenseMap<StratifiedIndex, InterfaceValue> InterfaceMap;
George Burgess IV87b2e412016-06-20 23:10:56 +0000159
George Burgess IV1f99da52016-06-23 18:55:23 +0000160 // Our intention here is to record all InterfaceValues that share the same
161 // StratifiedIndex in RetParamRelations. For each valid InterfaceValue, we
162 // have its StratifiedIndex scanned here and check if the index is presented
163 // in InterfaceMap: if it is not, we add the correspondence to the map;
164 // otherwise, an aliasing relation is found and we add it to
165 // RetParamRelations.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000166
George Burgess IVd14d05a2016-06-23 20:59:13 +0000167 auto AddToRetParamRelations = [&](unsigned InterfaceIndex,
168 StratifiedIndex SetIndex) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000169 unsigned Level = 0;
170 while (true) {
171 InterfaceValue CurrValue{InterfaceIndex, Level};
George Burgess IV87b2e412016-06-20 23:10:56 +0000172
George Burgess IV1f99da52016-06-23 18:55:23 +0000173 auto Itr = InterfaceMap.find(SetIndex);
174 if (Itr != InterfaceMap.end()) {
175 if (CurrValue != Itr->second)
George Burgess IVc294d0d2016-07-09 02:54:42 +0000176 Summary.RetParamRelations.push_back(
177 ExternalRelation{CurrValue, Itr->second});
George Burgess IV1f99da52016-06-23 18:55:23 +0000178 break;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000179 }
George Burgess IV87b2e412016-06-20 23:10:56 +0000180
George Burgess IV1f99da52016-06-23 18:55:23 +0000181 auto &Link = Sets.getLink(SetIndex);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000182 InterfaceMap.insert(std::make_pair(SetIndex, CurrValue));
George Burgess IVe1919962016-07-06 00:47:21 +0000183 auto ExternalAttrs = getExternallyVisibleAttrs(Link.Attrs);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000184 if (ExternalAttrs.any())
George Burgess IVc294d0d2016-07-09 02:54:42 +0000185 Summary.RetParamAttributes.push_back(
George Burgess IVa3d62be2016-06-24 01:00:03 +0000186 ExternalAttribute{CurrValue, ExternalAttrs});
187
George Burgess IV1f99da52016-06-23 18:55:23 +0000188 if (!Link.hasBelow())
189 break;
George Burgess IV87b2e412016-06-20 23:10:56 +0000190
George Burgess IV1f99da52016-06-23 18:55:23 +0000191 ++Level;
192 SetIndex = Link.Below;
George Burgess IV87b2e412016-06-20 23:10:56 +0000193 }
George Burgess IV1f99da52016-06-23 18:55:23 +0000194 };
195
196 // Populate RetParamRelations for return values
197 for (auto *RetVal : RetVals) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000198 assert(RetVal != nullptr);
199 assert(RetVal->getType()->isPointerTy());
George Burgess IV1f99da52016-06-23 18:55:23 +0000200 auto RetInfo = Sets.find(RetVal);
201 if (RetInfo.hasValue())
202 AddToRetParamRelations(0, RetInfo->Index);
203 }
204
205 // Populate RetParamRelations for parameters
206 unsigned I = 0;
207 for (auto &Param : Fn.args()) {
208 if (Param.getType()->isPointerTy()) {
209 auto ParamInfo = Sets.find(&Param);
210 if (ParamInfo.hasValue())
211 AddToRetParamRelations(I + 1, ParamInfo->Index);
212 }
213 ++I;
George Burgess IV87b2e412016-06-20 23:10:56 +0000214 }
215}
216
Chandler Carruth8b046a42015-08-14 02:42:20 +0000217// Builds the graph + StratifiedSets for a function.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000218CFLSteensAAResult::FunctionInfo CFLSteensAAResult::buildSetsFrom(Function *Fn) {
George Burgess IVc294d0d2016-07-09 02:54:42 +0000219 CFLGraphBuilder<CFLSteensAAResult> GraphBuilder(*this, TLI, *Fn);
George Burgess IVe17756e2016-06-14 18:02:27 +0000220 StratifiedSetsBuilder<Value *> SetBuilder;
Hal Finkel7529c552014-09-02 21:43:13 +0000221
George Burgess IVe17756e2016-06-14 18:02:27 +0000222 auto &Graph = GraphBuilder.getCFLGraph();
George Burgess IVdc96feb2016-06-13 19:21:18 +0000223 SmallVector<Value *, 16> Worklist;
George Burgess IVdc96feb2016-06-13 19:21:18 +0000224 for (auto Node : Graph.nodes())
225 Worklist.push_back(Node);
226
227 while (!Worklist.empty()) {
228 auto *CurValue = Worklist.pop_back_val();
George Burgess IVe17756e2016-06-14 18:02:27 +0000229 SetBuilder.add(CurValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000230 if (canSkipAddingToSets(CurValue))
231 continue;
232
George Burgess IV259d9012016-06-15 20:43:41 +0000233 auto Attr = Graph.attrFor(CurValue);
234 SetBuilder.noteAttributes(CurValue, Attr);
235
George Burgess IVdc96feb2016-06-13 19:21:18 +0000236 for (const auto &Edge : Graph.edgesFor(CurValue)) {
237 auto Label = Edge.Type;
238 auto *OtherValue = Edge.Other;
239
240 if (canSkipAddingToSets(OtherValue))
Hal Finkel7529c552014-09-02 21:43:13 +0000241 continue;
242
George Burgess IVdc96feb2016-06-13 19:21:18 +0000243 bool Added;
244 switch (directionOfEdgeType(Label)) {
245 case Level::Above:
George Burgess IVe17756e2016-06-14 18:02:27 +0000246 Added = SetBuilder.addAbove(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000247 break;
248 case Level::Below:
George Burgess IVe17756e2016-06-14 18:02:27 +0000249 Added = SetBuilder.addBelow(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000250 break;
251 case Level::Same:
George Burgess IVe17756e2016-06-14 18:02:27 +0000252 Added = SetBuilder.addWith(CurValue, OtherValue);
George Burgess IVdc96feb2016-06-13 19:21:18 +0000253 break;
Hal Finkel7529c552014-09-02 21:43:13 +0000254 }
George Burgess IVdc96feb2016-06-13 19:21:18 +0000255
George Burgess IVdc96feb2016-06-13 19:21:18 +0000256 if (Added)
257 Worklist.push_back(OtherValue);
Hal Finkel7529c552014-09-02 21:43:13 +0000258 }
259 }
260
George Burgess IV1f99da52016-06-23 18:55:23 +0000261 // Special handling for interprocedural aliases
George Burgess IVe1919962016-07-06 00:47:21 +0000262 for (auto &Edge : GraphBuilder.getInstantiatedRelations()) {
George Burgess IVfe1397b2016-06-23 19:16:04 +0000263 auto FromVal = Edge.From.Val;
264 auto ToVal = Edge.To.Val;
George Burgess IV1f99da52016-06-23 18:55:23 +0000265 SetBuilder.add(FromVal);
266 SetBuilder.add(ToVal);
267 SetBuilder.addBelowWith(FromVal, Edge.From.DerefLevel, ToVal,
268 Edge.To.DerefLevel);
269 }
270
George Burgess IVa3d62be2016-06-24 01:00:03 +0000271 // Special handling for interprocedural attributes
George Burgess IVe1919962016-07-06 00:47:21 +0000272 for (auto &IPAttr : GraphBuilder.getInstantiatedAttrs()) {
273 auto Val = IPAttr.IValue.Val;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000274 SetBuilder.add(Val);
George Burgess IVe1919962016-07-06 00:47:21 +0000275 SetBuilder.addAttributesBelow(Val, IPAttr.IValue.DerefLevel, IPAttr.Attr);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000276 }
277
George Burgess IV87b2e412016-06-20 23:10:56 +0000278 return FunctionInfo(*Fn, GraphBuilder.getReturnValues(), SetBuilder.build());
Hal Finkel7529c552014-09-02 21:43:13 +0000279}
280
George Burgess IVbfa401e2016-07-06 00:26:41 +0000281void CFLSteensAAResult::scan(Function *Fn) {
Hal Finkel8d1590d2014-09-02 22:52:30 +0000282 auto InsertPair = Cache.insert(std::make_pair(Fn, Optional<FunctionInfo>()));
Hal Finkel7529c552014-09-02 21:43:13 +0000283 (void)InsertPair;
284 assert(InsertPair.second &&
285 "Trying to scan a function that has already been cached");
286
George Burgess IV6edb8912016-05-02 18:09:19 +0000287 // Note that we can't do Cache[Fn] = buildSetsFrom(Fn) here: the function call
288 // may get evaluated after operator[], potentially triggering a DenseMap
289 // resize and invalidating the reference returned by operator[]
290 auto FunInfo = buildSetsFrom(Fn);
291 Cache[Fn] = std::move(FunInfo);
292
Hal Finkel7529c552014-09-02 21:43:13 +0000293 Handles.push_front(FunctionHandle(Fn, this));
294}
295
George Burgess IVbfa401e2016-07-06 00:26:41 +0000296void CFLSteensAAResult::evict(Function *Fn) { Cache.erase(Fn); }
Chandler Carruth8b046a42015-08-14 02:42:20 +0000297
George Burgess IVcae581d2016-04-13 23:27:37 +0000298/// Ensures that the given function is available in the cache, and returns the
299/// entry.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000300const Optional<CFLSteensAAResult::FunctionInfo> &
301CFLSteensAAResult::ensureCached(Function *Fn) {
Chandler Carruth8b046a42015-08-14 02:42:20 +0000302 auto Iter = Cache.find(Fn);
303 if (Iter == Cache.end()) {
304 scan(Fn);
305 Iter = Cache.find(Fn);
306 assert(Iter != Cache.end());
307 assert(Iter->second.hasValue());
308 }
309 return Iter->second;
310}
311
George Burgess IVc294d0d2016-07-09 02:54:42 +0000312const AliasSummary *CFLSteensAAResult::getAliasSummary(Function &Fn) {
313 auto &FunInfo = ensureCached(&Fn);
314 if (FunInfo.hasValue())
315 return &FunInfo->getAliasSummary();
316 else
317 return nullptr;
318}
319
George Burgess IVbfa401e2016-07-06 00:26:41 +0000320AliasResult CFLSteensAAResult::query(const MemoryLocation &LocA,
321 const MemoryLocation &LocB) {
Hal Finkel7529c552014-09-02 21:43:13 +0000322 auto *ValA = const_cast<Value *>(LocA.Ptr);
323 auto *ValB = const_cast<Value *>(LocB.Ptr);
324
George Burgess IV259d9012016-06-15 20:43:41 +0000325 if (!ValA->getType()->isPointerTy() || !ValB->getType()->isPointerTy())
326 return NoAlias;
327
Hal Finkel7529c552014-09-02 21:43:13 +0000328 Function *Fn = nullptr;
329 auto MaybeFnA = parentFunctionOfValue(ValA);
330 auto MaybeFnB = parentFunctionOfValue(ValB);
331 if (!MaybeFnA.hasValue() && !MaybeFnB.hasValue()) {
George Burgess IVcae581d2016-04-13 23:27:37 +0000332 // The only times this is known to happen are when globals + InlineAsm are
333 // involved
George Burgess IVbfa401e2016-07-06 00:26:41 +0000334 DEBUG(dbgs()
335 << "CFLSteensAA: could not extract parent function information.\n");
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000336 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000337 }
338
339 if (MaybeFnA.hasValue()) {
340 Fn = *MaybeFnA;
341 assert((!MaybeFnB.hasValue() || *MaybeFnB == *MaybeFnA) &&
342 "Interprocedural queries not supported");
343 } else {
344 Fn = *MaybeFnB;
345 }
346
347 assert(Fn != nullptr);
348 auto &MaybeInfo = ensureCached(Fn);
349 assert(MaybeInfo.hasValue());
350
George Burgess IV87b2e412016-06-20 23:10:56 +0000351 auto &Sets = MaybeInfo->getStratifiedSets();
Hal Finkel7529c552014-09-02 21:43:13 +0000352 auto MaybeA = Sets.find(ValA);
353 if (!MaybeA.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000354 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000355
356 auto MaybeB = Sets.find(ValB);
357 if (!MaybeB.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000358 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000359
360 auto SetA = *MaybeA;
361 auto SetB = *MaybeB;
Hal Finkel7529c552014-09-02 21:43:13 +0000362 auto AttrsA = Sets.getLink(SetA.Index).Attrs;
363 auto AttrsB = Sets.getLink(SetB.Index).Attrs;
George Burgess IV33305e72015-02-12 03:07:07 +0000364
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000365 // If both values are local (meaning the corresponding set has attribute
George Burgess IVbfa401e2016-07-06 00:26:41 +0000366 // AttrNone or AttrEscaped), then we know that CFLSteensAA fully models them:
367 // they may-alias each other if and only if they are in the same set.
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000368 // If at least one value is non-local (meaning it either is global/argument or
369 // it comes from unknown sources like integer cast), the situation becomes a
370 // bit more interesting. We follow three general rules described below:
371 // - Non-local values may alias each other
372 // - AttrNone values do not alias any non-local values
George Burgess IV652ec4f2016-06-09 23:15:04 +0000373 // - AttrEscaped do not alias globals/arguments, but they may alias
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000374 // AttrUnknown values
375 if (SetA.Index == SetB.Index)
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000376 return MayAlias;
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000377 if (AttrsA.none() || AttrsB.none())
378 return NoAlias;
George Burgess IVe1919962016-07-06 00:47:21 +0000379 if (hasUnknownOrCallerAttr(AttrsA) || hasUnknownOrCallerAttr(AttrsB))
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000380 return MayAlias;
381 if (isGlobalOrArgAttr(AttrsA) && isGlobalOrArgAttr(AttrsB))
382 return MayAlias;
383 return NoAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000384}
Mehdi Amini46a43552015-03-04 18:43:29 +0000385
George Burgess IVbfa401e2016-07-06 00:26:41 +0000386ModRefInfo CFLSteensAAResult::getArgModRefInfo(ImmutableCallSite CS,
387 unsigned ArgIdx) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000388 if (auto CalledFunc = CS.getCalledFunction()) {
389 auto &MaybeInfo = ensureCached(const_cast<Function *>(CalledFunc));
390 if (!MaybeInfo.hasValue())
391 return MRI_ModRef;
George Burgess IVc294d0d2016-07-09 02:54:42 +0000392 auto &RetParamAttributes = MaybeInfo->getAliasSummary().RetParamAttributes;
393 auto &RetParamRelations = MaybeInfo->getAliasSummary().RetParamRelations;
George Burgess IVd86e38e2016-06-30 02:11:26 +0000394
395 bool ArgAttributeIsWritten =
396 std::any_of(RetParamAttributes.begin(), RetParamAttributes.end(),
397 [ArgIdx](const ExternalAttribute &ExtAttr) {
398 return ExtAttr.IValue.Index == ArgIdx + 1;
399 });
400 bool ArgIsAccessed =
401 std::any_of(RetParamRelations.begin(), RetParamRelations.end(),
402 [ArgIdx](const ExternalRelation &ExtRelation) {
403 return ExtRelation.To.Index == ArgIdx + 1 ||
404 ExtRelation.From.Index == ArgIdx + 1;
405 });
406
407 return (!ArgIsAccessed && !ArgAttributeIsWritten) ? MRI_NoModRef
408 : MRI_ModRef;
409 }
410
411 return MRI_ModRef;
412}
413
George Burgess IVbfa401e2016-07-06 00:26:41 +0000414FunctionModRefBehavior
415CFLSteensAAResult::getModRefBehavior(ImmutableCallSite CS) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000416 // If we know the callee, try analyzing it
417 if (auto CalledFunc = CS.getCalledFunction())
418 return getModRefBehavior(CalledFunc);
419
420 // Otherwise, be conservative
421 return FMRB_UnknownModRefBehavior;
422}
423
George Burgess IVbfa401e2016-07-06 00:26:41 +0000424FunctionModRefBehavior CFLSteensAAResult::getModRefBehavior(const Function *F) {
George Burgess IVd86e38e2016-06-30 02:11:26 +0000425 assert(F != nullptr);
426
427 // TODO: Remove the const_cast
428 auto &MaybeInfo = ensureCached(const_cast<Function *>(F));
429 if (!MaybeInfo.hasValue())
430 return FMRB_UnknownModRefBehavior;
George Burgess IVc294d0d2016-07-09 02:54:42 +0000431 auto &RetParamAttributes = MaybeInfo->getAliasSummary().RetParamAttributes;
432 auto &RetParamRelations = MaybeInfo->getAliasSummary().RetParamRelations;
George Burgess IVd86e38e2016-06-30 02:11:26 +0000433
434 // First, if any argument is marked Escpaed, Unknown or Global, anything may
435 // happen to them and thus we can't draw any conclusion.
436 if (!RetParamAttributes.empty())
437 return FMRB_UnknownModRefBehavior;
438
439 // Currently we don't (and can't) distinguish reads from writes in
440 // RetParamRelations. All we can say is whether there may be memory access or
441 // not.
442 if (RetParamRelations.empty())
443 return FMRB_DoesNotAccessMemory;
444
445 // Check if something beyond argmem gets touched.
446 bool AccessArgMemoryOnly =
447 std::all_of(RetParamRelations.begin(), RetParamRelations.end(),
448 [](const ExternalRelation &ExtRelation) {
449 // Both DerefLevels has to be 0, since we don't know which
450 // one is a read and which is a write.
451 return ExtRelation.From.DerefLevel == 0 &&
452 ExtRelation.To.DerefLevel == 0;
453 });
454 return AccessArgMemoryOnly ? FMRB_OnlyAccessesArgumentPointees
455 : FMRB_UnknownModRefBehavior;
456}
457
George Burgess IVbfa401e2016-07-06 00:26:41 +0000458char CFLSteensAA::PassID;
Chandler Carruthb4faf132016-03-11 10:22:49 +0000459
George Burgess IVbfa401e2016-07-06 00:26:41 +0000460CFLSteensAAResult CFLSteensAA::run(Function &F, AnalysisManager<Function> &AM) {
461 return CFLSteensAAResult(AM.getResult<TargetLibraryAnalysis>(F));
Chandler Carruth7b560d42015-09-09 17:55:00 +0000462}
463
George Burgess IVbfa401e2016-07-06 00:26:41 +0000464char CFLSteensAAWrapperPass::ID = 0;
465INITIALIZE_PASS(CFLSteensAAWrapperPass, "cfl-steens-aa",
466 "Unification-Based CFL Alias Analysis", false, true)
Chandler Carruth7b560d42015-09-09 17:55:00 +0000467
George Burgess IVbfa401e2016-07-06 00:26:41 +0000468ImmutablePass *llvm::createCFLSteensAAWrapperPass() {
469 return new CFLSteensAAWrapperPass();
Chandler Carruth7b560d42015-09-09 17:55:00 +0000470}
471
George Burgess IVbfa401e2016-07-06 00:26:41 +0000472CFLSteensAAWrapperPass::CFLSteensAAWrapperPass() : ImmutablePass(ID) {
473 initializeCFLSteensAAWrapperPassPass(*PassRegistry::getPassRegistry());
474}
475
476void CFLSteensAAWrapperPass::initializePass() {
George Burgess IV18b83fe2016-06-01 18:39:54 +0000477 auto &TLIWP = getAnalysis<TargetLibraryInfoWrapperPass>();
George Burgess IVbfa401e2016-07-06 00:26:41 +0000478 Result.reset(new CFLSteensAAResult(TLIWP.getTLI()));
Chandler Carruth7b560d42015-09-09 17:55:00 +0000479}
480
George Burgess IVbfa401e2016-07-06 00:26:41 +0000481void CFLSteensAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
Chandler Carruth7b560d42015-09-09 17:55:00 +0000482 AU.setPreservesAll();
George Burgess IV18b83fe2016-06-01 18:39:54 +0000483 AU.addRequired<TargetLibraryInfoWrapperPass>();
Mehdi Amini46a43552015-03-04 18:43:29 +0000484}