blob: 85a8c3d2a00b070ad651eb3973e3ca4729550876 [file] [log] [blame]
Eugene Zelenko530851c2017-08-11 21:30:02 +00001//===- CFLSteensAliasAnalysis.cpp - Unification-based Alias Analysis ------===//
Hal Finkel7529c552014-09-02 21:43:13 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
Hal Finkel7529c552014-09-02 21:43:13 +00006//
7//===----------------------------------------------------------------------===//
8//
George Burgess IVbfa401e2016-07-06 00:26:41 +00009// This file implements a CFL-base, summary-based alias analysis algorithm. It
10// does not depend on types. The algorithm is a mixture of the one described in
11// "Demand-driven alias analysis for C" by Xin Zheng and Radu Rugina, and "Fast
12// algorithms for Dyck-CFL-reachability with applications to Alias Analysis" by
13// Zhang Q, Lyu M R, Yuan H, and Su Z. -- to summarize the papers, we build a
14// graph of the uses of a variable, where each node is a memory location, and
15// each edge is an action that happened on that memory location. The "actions"
16// can be one of Dereference, Reference, or Assign. The precision of this
17// analysis is roughly the same as that of an one level context-sensitive
18// Steensgaard's algorithm.
Hal Finkel7529c552014-09-02 21:43:13 +000019//
20// Two variables are considered as aliasing iff you can reach one value's node
21// from the other value's node and the language formed by concatenating all of
22// the edge labels (actions) conforms to a context-free grammar.
23//
24// Because this algorithm requires a graph search on each query, we execute the
25// algorithm outlined in "Fast algorithms..." (mentioned above)
26// in order to transform the graph into sets of variables that may alias in
George Burgess IV77351ba32016-01-28 00:54:01 +000027// ~nlogn time (n = number of variables), which makes queries take constant
Hal Finkel7529c552014-09-02 21:43:13 +000028// time.
29//===----------------------------------------------------------------------===//
30
George Burgess IV77351ba32016-01-28 00:54:01 +000031// N.B. AliasAnalysis as a whole is phrased as a FunctionPass at the moment, and
George Burgess IVbfa401e2016-07-06 00:26:41 +000032// CFLSteensAA is interprocedural. This is *technically* A Bad Thing, because
George Burgess IV77351ba32016-01-28 00:54:01 +000033// FunctionPasses are only allowed to inspect the Function that they're being
34// run on. Realistically, this likely isn't a problem until we allow
35// FunctionPasses to run concurrently.
36
George Burgess IVbfa401e2016-07-06 00:26:41 +000037#include "llvm/Analysis/CFLSteensAliasAnalysis.h"
Eugene Zelenko530851c2017-08-11 21:30:02 +000038#include "AliasAnalysisSummary.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"
Chandler Carruthd9903882015-01-14 11:23:27 +000042#include "llvm/ADT/Optional.h"
Eugene Zelenko530851c2017-08-11 21:30:02 +000043#include "llvm/ADT/SmallVector.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"
Eugene Zelenko530851c2017-08-11 21:30:02 +000047#include "llvm/IR/Type.h"
48#include "llvm/IR/Value.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080049#include "llvm/InitializePasses.h"
Hal Finkel7529c552014-09-02 21:43:13 +000050#include "llvm/Pass.h"
George Burgess IV33305e72015-02-12 03:07:07 +000051#include "llvm/Support/Debug.h"
Benjamin Kramer799003b2015-03-23 19:32:43 +000052#include "llvm/Support/raw_ostream.h"
Hal Finkel7529c552014-09-02 21:43:13 +000053#include <algorithm>
54#include <cassert>
Eugene Zelenko530851c2017-08-11 21:30:02 +000055#include <limits>
Benjamin Kramer799003b2015-03-23 19:32:43 +000056#include <memory>
Eugene Zelenko530851c2017-08-11 21:30:02 +000057#include <utility>
Hal Finkel7529c552014-09-02 21:43:13 +000058
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
Teresa Johnson9c27b592019-09-07 03:09:36 +000064CFLSteensAAResult::CFLSteensAAResult(
65 std::function<const TargetLibraryInfo &(Function &F)> GetTLI)
66 : AAResultBase(), GetTLI(std::move(GetTLI)) {}
George Burgess IVbfa401e2016-07-06 00:26:41 +000067CFLSteensAAResult::CFLSteensAAResult(CFLSteensAAResult &&Arg)
Teresa Johnson9c27b592019-09-07 03:09:36 +000068 : AAResultBase(std::move(Arg)), GetTLI(std::move(Arg.GetTLI)) {}
Eugene Zelenko530851c2017-08-11 21:30:02 +000069CFLSteensAAResult::~CFLSteensAAResult() = default;
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 IVde1be712016-07-11 22:59:09 +000073 StratifiedSets<InstantiatedValue> Sets;
George Burgess IVc294d0d2016-07-09 02:54:42 +000074 AliasSummary Summary;
George Burgess IVa3d62be2016-06-24 01:00:03 +000075
George Burgess IV87b2e412016-06-20 23:10:56 +000076public:
77 FunctionInfo(Function &Fn, const SmallVectorImpl<Value *> &RetVals,
George Burgess IVde1be712016-07-11 22:59:09 +000078 StratifiedSets<InstantiatedValue> S);
George Burgess IV87b2e412016-06-20 23:10:56 +000079
George Burgess IVde1be712016-07-11 22:59:09 +000080 const StratifiedSets<InstantiatedValue> &getStratifiedSets() const {
81 return Sets;
82 }
Eugene Zelenko530851c2017-08-11 21:30:02 +000083
George Burgess IVc294d0d2016-07-09 02:54:42 +000084 const AliasSummary &getAliasSummary() const { return Summary; }
Chandler Carruth8b046a42015-08-14 02:42:20 +000085};
86
Hal Finkel1ae325f2014-09-02 23:50:01 +000087const StratifiedIndex StratifiedLink::SetSentinel =
George Burgess IV11d509d2015-03-15 00:52:21 +000088 std::numeric_limits<StratifiedIndex>::max();
Hal Finkel1ae325f2014-09-02 23:50:01 +000089
Hal Finkel7529c552014-09-02 21:43:13 +000090//===----------------------------------------------------------------------===//
91// Function declarations that require types defined in the namespace above
92//===----------------------------------------------------------------------===//
93
George Burgess IVcae581d2016-04-13 23:27:37 +000094/// Determines whether it would be pointless to add the given Value to our sets.
George Burgess IVab03af22015-03-10 02:58:15 +000095static bool canSkipAddingToSets(Value *Val) {
96 // Constants can share instances, which may falsely unify multiple
97 // sets, e.g. in
98 // store i32* null, i32** %ptr1
99 // store i32* null, i32** %ptr2
100 // clearly ptr1 and ptr2 should not be unified into the same set, so
101 // we should filter out the (potentially shared) instance to
102 // i32* null.
103 if (isa<Constant>(Val)) {
George Burgess IVab03af22015-03-10 02:58:15 +0000104 // TODO: Because all of these things are constant, we can determine whether
105 // the data is *actually* mutable at graph building time. This will probably
106 // come for free/cheap with offset awareness.
Duncan P. N. Exon Smith1de3c7e2016-04-05 21:10:45 +0000107 bool CanStoreMutableData = isa<GlobalValue>(Val) ||
108 isa<ConstantExpr>(Val) ||
109 isa<ConstantAggregate>(Val);
George Burgess IVab03af22015-03-10 02:58:15 +0000110 return !CanStoreMutableData;
111 }
112
113 return false;
Hal Finkel7529c552014-09-02 21:43:13 +0000114}
115
George Burgess IVbfa401e2016-07-06 00:26:41 +0000116CFLSteensAAResult::FunctionInfo::FunctionInfo(
117 Function &Fn, const SmallVectorImpl<Value *> &RetVals,
George Burgess IVde1be712016-07-11 22:59:09 +0000118 StratifiedSets<InstantiatedValue> S)
George Burgess IV87b2e412016-06-20 23:10:56 +0000119 : Sets(std::move(S)) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000120 // Historically, an arbitrary upper-bound of 50 args was selected. We may want
121 // to remove this if it doesn't really matter in practice.
122 if (Fn.arg_size() > MaxSupportedArgsInSummary)
123 return;
George Burgess IV87b2e412016-06-20 23:10:56 +0000124
George Burgess IV1f99da52016-06-23 18:55:23 +0000125 DenseMap<StratifiedIndex, InterfaceValue> InterfaceMap;
George Burgess IV87b2e412016-06-20 23:10:56 +0000126
George Burgess IV1f99da52016-06-23 18:55:23 +0000127 // Our intention here is to record all InterfaceValues that share the same
128 // StratifiedIndex in RetParamRelations. For each valid InterfaceValue, we
129 // have its StratifiedIndex scanned here and check if the index is presented
130 // in InterfaceMap: if it is not, we add the correspondence to the map;
131 // otherwise, an aliasing relation is found and we add it to
132 // RetParamRelations.
George Burgess IVa3d62be2016-06-24 01:00:03 +0000133
George Burgess IVd14d05a2016-06-23 20:59:13 +0000134 auto AddToRetParamRelations = [&](unsigned InterfaceIndex,
135 StratifiedIndex SetIndex) {
George Burgess IV1f99da52016-06-23 18:55:23 +0000136 unsigned Level = 0;
137 while (true) {
138 InterfaceValue CurrValue{InterfaceIndex, Level};
George Burgess IV87b2e412016-06-20 23:10:56 +0000139
George Burgess IV1f99da52016-06-23 18:55:23 +0000140 auto Itr = InterfaceMap.find(SetIndex);
141 if (Itr != InterfaceMap.end()) {
142 if (CurrValue != Itr->second)
George Burgess IVc294d0d2016-07-09 02:54:42 +0000143 Summary.RetParamRelations.push_back(
George Burgess IV4ec17532016-07-22 22:30:48 +0000144 ExternalRelation{CurrValue, Itr->second, UnknownOffset});
George Burgess IV1f99da52016-06-23 18:55:23 +0000145 break;
George Burgess IVa3d62be2016-06-24 01:00:03 +0000146 }
George Burgess IV87b2e412016-06-20 23:10:56 +0000147
George Burgess IV1f99da52016-06-23 18:55:23 +0000148 auto &Link = Sets.getLink(SetIndex);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000149 InterfaceMap.insert(std::make_pair(SetIndex, CurrValue));
George Burgess IVe1919962016-07-06 00:47:21 +0000150 auto ExternalAttrs = getExternallyVisibleAttrs(Link.Attrs);
George Burgess IVa3d62be2016-06-24 01:00:03 +0000151 if (ExternalAttrs.any())
George Burgess IVc294d0d2016-07-09 02:54:42 +0000152 Summary.RetParamAttributes.push_back(
George Burgess IVa3d62be2016-06-24 01:00:03 +0000153 ExternalAttribute{CurrValue, ExternalAttrs});
154
George Burgess IV1f99da52016-06-23 18:55:23 +0000155 if (!Link.hasBelow())
156 break;
George Burgess IV87b2e412016-06-20 23:10:56 +0000157
George Burgess IV1f99da52016-06-23 18:55:23 +0000158 ++Level;
159 SetIndex = Link.Below;
George Burgess IV87b2e412016-06-20 23:10:56 +0000160 }
George Burgess IV1f99da52016-06-23 18:55:23 +0000161 };
162
163 // Populate RetParamRelations for return values
164 for (auto *RetVal : RetVals) {
George Burgess IVa3d62be2016-06-24 01:00:03 +0000165 assert(RetVal != nullptr);
166 assert(RetVal->getType()->isPointerTy());
George Burgess IVde1be712016-07-11 22:59:09 +0000167 auto RetInfo = Sets.find(InstantiatedValue{RetVal, 0});
George Burgess IV1f99da52016-06-23 18:55:23 +0000168 if (RetInfo.hasValue())
169 AddToRetParamRelations(0, RetInfo->Index);
170 }
171
172 // Populate RetParamRelations for parameters
173 unsigned I = 0;
174 for (auto &Param : Fn.args()) {
175 if (Param.getType()->isPointerTy()) {
George Burgess IVde1be712016-07-11 22:59:09 +0000176 auto ParamInfo = Sets.find(InstantiatedValue{&Param, 0});
George Burgess IV1f99da52016-06-23 18:55:23 +0000177 if (ParamInfo.hasValue())
178 AddToRetParamRelations(I + 1, ParamInfo->Index);
179 }
180 ++I;
George Burgess IV87b2e412016-06-20 23:10:56 +0000181 }
182}
183
Chandler Carruth8b046a42015-08-14 02:42:20 +0000184// Builds the graph + StratifiedSets for a function.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000185CFLSteensAAResult::FunctionInfo CFLSteensAAResult::buildSetsFrom(Function *Fn) {
Teresa Johnson9c27b592019-09-07 03:09:36 +0000186 CFLGraphBuilder<CFLSteensAAResult> GraphBuilder(*this, GetTLI(*Fn), *Fn);
George Burgess IVde1be712016-07-11 22:59:09 +0000187 StratifiedSetsBuilder<InstantiatedValue> SetBuilder;
Hal Finkel7529c552014-09-02 21:43:13 +0000188
George Burgess IVde1be712016-07-11 22:59:09 +0000189 // Add all CFLGraph nodes and all Dereference edges to StratifiedSets
George Burgess IVe17756e2016-06-14 18:02:27 +0000190 auto &Graph = GraphBuilder.getCFLGraph();
George Burgess IVde1be712016-07-11 22:59:09 +0000191 for (const auto &Mapping : Graph.value_mappings()) {
192 auto Val = Mapping.first;
193 if (canSkipAddingToSets(Val))
George Burgess IVdc96feb2016-06-13 19:21:18 +0000194 continue;
George Burgess IVde1be712016-07-11 22:59:09 +0000195 auto &ValueInfo = Mapping.second;
George Burgess IVdc96feb2016-06-13 19:21:18 +0000196
George Burgess IVde1be712016-07-11 22:59:09 +0000197 assert(ValueInfo.getNumLevels() > 0);
198 SetBuilder.add(InstantiatedValue{Val, 0});
199 SetBuilder.noteAttributes(InstantiatedValue{Val, 0},
200 ValueInfo.getNodeInfoAtLevel(0).Attr);
201 for (unsigned I = 0, E = ValueInfo.getNumLevels() - 1; I < E; ++I) {
202 SetBuilder.add(InstantiatedValue{Val, I + 1});
203 SetBuilder.noteAttributes(InstantiatedValue{Val, I + 1},
204 ValueInfo.getNodeInfoAtLevel(I + 1).Attr);
205 SetBuilder.addBelow(InstantiatedValue{Val, I},
206 InstantiatedValue{Val, I + 1});
Hal Finkel7529c552014-09-02 21:43:13 +0000207 }
208 }
209
George Burgess IVde1be712016-07-11 22:59:09 +0000210 // Add all assign edges to StratifiedSets
211 for (const auto &Mapping : Graph.value_mappings()) {
212 auto Val = Mapping.first;
213 if (canSkipAddingToSets(Val))
214 continue;
215 auto &ValueInfo = Mapping.second;
George Burgess IV1f99da52016-06-23 18:55:23 +0000216
George Burgess IVde1be712016-07-11 22:59:09 +0000217 for (unsigned I = 0, E = ValueInfo.getNumLevels(); I < E; ++I) {
218 auto Src = InstantiatedValue{Val, I};
219 for (auto &Edge : ValueInfo.getNodeInfoAtLevel(I).Edges)
220 SetBuilder.addWith(Src, Edge.Other);
221 }
George Burgess IVa3d62be2016-06-24 01:00:03 +0000222 }
223
George Burgess IV87b2e412016-06-20 23:10:56 +0000224 return FunctionInfo(*Fn, GraphBuilder.getReturnValues(), SetBuilder.build());
Hal Finkel7529c552014-09-02 21:43:13 +0000225}
226
George Burgess IVbfa401e2016-07-06 00:26:41 +0000227void CFLSteensAAResult::scan(Function *Fn) {
Hal Finkel8d1590d2014-09-02 22:52:30 +0000228 auto InsertPair = Cache.insert(std::make_pair(Fn, Optional<FunctionInfo>()));
Hal Finkel7529c552014-09-02 21:43:13 +0000229 (void)InsertPair;
230 assert(InsertPair.second &&
231 "Trying to scan a function that has already been cached");
232
George Burgess IV6edb8912016-05-02 18:09:19 +0000233 // Note that we can't do Cache[Fn] = buildSetsFrom(Fn) here: the function call
234 // may get evaluated after operator[], potentially triggering a DenseMap
235 // resize and invalidating the reference returned by operator[]
236 auto FunInfo = buildSetsFrom(Fn);
237 Cache[Fn] = std::move(FunInfo);
238
Davide Italianoe34a8062017-06-26 23:59:14 +0000239 Handles.emplace_front(Fn, this);
Hal Finkel7529c552014-09-02 21:43:13 +0000240}
241
George Burgess IVbfa401e2016-07-06 00:26:41 +0000242void CFLSteensAAResult::evict(Function *Fn) { Cache.erase(Fn); }
Chandler Carruth8b046a42015-08-14 02:42:20 +0000243
George Burgess IVcae581d2016-04-13 23:27:37 +0000244/// Ensures that the given function is available in the cache, and returns the
245/// entry.
George Burgess IVbfa401e2016-07-06 00:26:41 +0000246const Optional<CFLSteensAAResult::FunctionInfo> &
247CFLSteensAAResult::ensureCached(Function *Fn) {
Chandler Carruth8b046a42015-08-14 02:42:20 +0000248 auto Iter = Cache.find(Fn);
249 if (Iter == Cache.end()) {
250 scan(Fn);
251 Iter = Cache.find(Fn);
252 assert(Iter != Cache.end());
253 assert(Iter->second.hasValue());
254 }
255 return Iter->second;
256}
257
George Burgess IVc294d0d2016-07-09 02:54:42 +0000258const AliasSummary *CFLSteensAAResult::getAliasSummary(Function &Fn) {
259 auto &FunInfo = ensureCached(&Fn);
260 if (FunInfo.hasValue())
261 return &FunInfo->getAliasSummary();
262 else
263 return nullptr;
264}
265
George Burgess IVbfa401e2016-07-06 00:26:41 +0000266AliasResult CFLSteensAAResult::query(const MemoryLocation &LocA,
267 const MemoryLocation &LocB) {
Hal Finkel7529c552014-09-02 21:43:13 +0000268 auto *ValA = const_cast<Value *>(LocA.Ptr);
269 auto *ValB = const_cast<Value *>(LocB.Ptr);
270
George Burgess IV259d9012016-06-15 20:43:41 +0000271 if (!ValA->getType()->isPointerTy() || !ValB->getType()->isPointerTy())
272 return NoAlias;
273
Hal Finkel7529c552014-09-02 21:43:13 +0000274 Function *Fn = nullptr;
Davide Italiano31d4c1b2017-06-27 02:25:06 +0000275 Function *MaybeFnA = const_cast<Function *>(parentFunctionOfValue(ValA));
276 Function *MaybeFnB = const_cast<Function *>(parentFunctionOfValue(ValB));
Davide Italiano604c0032017-06-27 00:33:37 +0000277 if (!MaybeFnA && !MaybeFnB) {
George Burgess IVcae581d2016-04-13 23:27:37 +0000278 // The only times this is known to happen are when globals + InlineAsm are
279 // involved
Nicola Zaghend34e60c2018-05-14 12:53:11 +0000280 LLVM_DEBUG(
281 dbgs()
282 << "CFLSteensAA: could not extract parent function information.\n");
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000283 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000284 }
285
Davide Italiano604c0032017-06-27 00:33:37 +0000286 if (MaybeFnA) {
287 Fn = MaybeFnA;
288 assert((!MaybeFnB || MaybeFnB == MaybeFnA) &&
Hal Finkel7529c552014-09-02 21:43:13 +0000289 "Interprocedural queries not supported");
290 } else {
Davide Italiano604c0032017-06-27 00:33:37 +0000291 Fn = MaybeFnB;
Hal Finkel7529c552014-09-02 21:43:13 +0000292 }
293
294 assert(Fn != nullptr);
295 auto &MaybeInfo = ensureCached(Fn);
296 assert(MaybeInfo.hasValue());
297
George Burgess IV87b2e412016-06-20 23:10:56 +0000298 auto &Sets = MaybeInfo->getStratifiedSets();
George Burgess IVde1be712016-07-11 22:59:09 +0000299 auto MaybeA = Sets.find(InstantiatedValue{ValA, 0});
Hal Finkel7529c552014-09-02 21:43:13 +0000300 if (!MaybeA.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000301 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000302
George Burgess IVde1be712016-07-11 22:59:09 +0000303 auto MaybeB = Sets.find(InstantiatedValue{ValB, 0});
Hal Finkel7529c552014-09-02 21:43:13 +0000304 if (!MaybeB.hasValue())
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000305 return MayAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000306
307 auto SetA = *MaybeA;
308 auto SetB = *MaybeB;
Hal Finkel7529c552014-09-02 21:43:13 +0000309 auto AttrsA = Sets.getLink(SetA.Index).Attrs;
310 auto AttrsB = Sets.getLink(SetB.Index).Attrs;
George Burgess IV33305e72015-02-12 03:07:07 +0000311
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000312 // If both values are local (meaning the corresponding set has attribute
George Burgess IVbfa401e2016-07-06 00:26:41 +0000313 // AttrNone or AttrEscaped), then we know that CFLSteensAA fully models them:
314 // they may-alias each other if and only if they are in the same set.
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000315 // If at least one value is non-local (meaning it either is global/argument or
316 // it comes from unknown sources like integer cast), the situation becomes a
317 // bit more interesting. We follow three general rules described below:
318 // - Non-local values may alias each other
319 // - AttrNone values do not alias any non-local values
George Burgess IV652ec4f2016-06-09 23:15:04 +0000320 // - AttrEscaped do not alias globals/arguments, but they may alias
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000321 // AttrUnknown values
322 if (SetA.Index == SetB.Index)
Chandler Carruthc3f49eb2015-06-22 02:16:51 +0000323 return MayAlias;
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000324 if (AttrsA.none() || AttrsB.none())
325 return NoAlias;
George Burgess IVe1919962016-07-06 00:47:21 +0000326 if (hasUnknownOrCallerAttr(AttrsA) || hasUnknownOrCallerAttr(AttrsB))
George Burgess IVa1f9a2d2016-06-07 18:35:37 +0000327 return MayAlias;
328 if (isGlobalOrArgAttr(AttrsA) && isGlobalOrArgAttr(AttrsB))
329 return MayAlias;
330 return NoAlias;
Hal Finkel7529c552014-09-02 21:43:13 +0000331}
Mehdi Amini46a43552015-03-04 18:43:29 +0000332
Chandler Carruthdab4eae2016-11-23 17:53:26 +0000333AnalysisKey CFLSteensAA::Key;
Chandler Carruthb4faf132016-03-11 10:22:49 +0000334
Sean Silva36e0d012016-08-09 00:28:15 +0000335CFLSteensAAResult CFLSteensAA::run(Function &F, FunctionAnalysisManager &AM) {
Teresa Johnson9c27b592019-09-07 03:09:36 +0000336 auto GetTLI = [&AM](Function &F) -> const TargetLibraryInfo & {
337 return AM.getResult<TargetLibraryAnalysis>(F);
338 };
339 return CFLSteensAAResult(GetTLI);
Chandler Carruth7b560d42015-09-09 17:55:00 +0000340}
341
George Burgess IVbfa401e2016-07-06 00:26:41 +0000342char CFLSteensAAWrapperPass::ID = 0;
343INITIALIZE_PASS(CFLSteensAAWrapperPass, "cfl-steens-aa",
344 "Unification-Based CFL Alias Analysis", false, true)
Chandler Carruth7b560d42015-09-09 17:55:00 +0000345
George Burgess IVbfa401e2016-07-06 00:26:41 +0000346ImmutablePass *llvm::createCFLSteensAAWrapperPass() {
347 return new CFLSteensAAWrapperPass();
Chandler Carruth7b560d42015-09-09 17:55:00 +0000348}
349
George Burgess IVbfa401e2016-07-06 00:26:41 +0000350CFLSteensAAWrapperPass::CFLSteensAAWrapperPass() : ImmutablePass(ID) {
351 initializeCFLSteensAAWrapperPassPass(*PassRegistry::getPassRegistry());
352}
353
354void CFLSteensAAWrapperPass::initializePass() {
Teresa Johnson9c27b592019-09-07 03:09:36 +0000355 auto GetTLI = [this](Function &F) -> const TargetLibraryInfo & {
356 return this->getAnalysis<TargetLibraryInfoWrapperPass>().getTLI(F);
357 };
358 Result.reset(new CFLSteensAAResult(GetTLI));
Chandler Carruth7b560d42015-09-09 17:55:00 +0000359}
360
George Burgess IVbfa401e2016-07-06 00:26:41 +0000361void CFLSteensAAWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
Chandler Carruth7b560d42015-09-09 17:55:00 +0000362 AU.setPreservesAll();
George Burgess IV18b83fe2016-06-01 18:39:54 +0000363 AU.addRequired<TargetLibraryInfoWrapperPass>();
Mehdi Amini46a43552015-03-04 18:43:29 +0000364}