blob: 4943721c4698657dd2328b1084bc51e9761f38e0 [file] [log] [blame]
Johannes Doerfertaade7822019-06-05 03:02:24 +00001//===- Attributor.cpp - Module-wide attribute deduction -------------------===//
2//
3// 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
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements an inter procedural pass that deduces and/or propagating
10// attributes. This is done in an abstract interpretation style fixpoint
11// iteration. See the Attributor.h file comment and the class descriptions in
12// that file for more information.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Transforms/IPO/Attributor.h"
17
Hideto Ueno11d37102019-07-17 15:15:43 +000018#include "llvm/ADT/DepthFirstIterator.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000019#include "llvm/ADT/STLExtras.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000020#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/Statistic.h"
Stefan Stipanovic69ebb022019-07-22 19:36:27 +000023#include "llvm/Analysis/CaptureTracking.h"
Johannes Doerfert924d2132019-08-05 21:34:45 +000024#include "llvm/Analysis/EHPersonalities.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000025#include "llvm/Analysis/GlobalsModRef.h"
Hideto Ueno19c07af2019-07-23 08:16:17 +000026#include "llvm/Analysis/Loads.h"
Stefan Stipanovic431141c2019-09-15 21:47:41 +000027#include "llvm/Analysis/MemoryBuiltins.h"
Hideto Ueno54869ec2019-07-15 06:49:04 +000028#include "llvm/Analysis/ValueTracking.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000029#include "llvm/IR/Argument.h"
30#include "llvm/IR/Attributes.h"
Hideto Ueno11d37102019-07-17 15:15:43 +000031#include "llvm/IR/CFG.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000032#include "llvm/IR/InstIterator.h"
Stefan Stipanovic06263672019-07-11 21:37:40 +000033#include "llvm/IR/IntrinsicInst.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000034#include "llvm/Support/CommandLine.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/raw_ostream.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000037#include "llvm/Transforms/Utils/BasicBlockUtils.h"
38#include "llvm/Transforms/Utils/Local.h"
39
Johannes Doerfertaade7822019-06-05 03:02:24 +000040#include <cassert>
41
42using namespace llvm;
43
44#define DEBUG_TYPE "attributor"
45
46STATISTIC(NumFnWithExactDefinition,
47 "Number of function with exact definitions");
48STATISTIC(NumFnWithoutExactDefinition,
49 "Number of function without exact definitions");
50STATISTIC(NumAttributesTimedOut,
51 "Number of abstract attributes timed out before fixpoint");
52STATISTIC(NumAttributesValidFixpoint,
53 "Number of abstract attributes in a valid fixpoint state");
54STATISTIC(NumAttributesManifested,
55 "Number of abstract attributes manifested in IR");
56
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000057// Some helper macros to deal with statistics tracking.
58//
59// Usage:
60// For simple IR attribute tracking overload trackStatistics in the abstract
Johannes Doerfert17b578b2019-08-14 21:46:25 +000061// attribute and choose the right STATS_DECLTRACK_********* macro,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000062// e.g.,:
63// void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +000064// STATS_DECLTRACK_ARG_ATTR(returned)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000065// }
66// If there is a single "increment" side one can use the macro
Johannes Doerfert17b578b2019-08-14 21:46:25 +000067// STATS_DECLTRACK with a custom message. If there are multiple increment
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000068// sides, STATS_DECL and STATS_TRACK can also be used separatly.
69//
70#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
71 ("Number of " #TYPE " marked '" #NAME "'")
72#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
Johannes Doerferta7a3b3a2019-09-04 19:01:08 +000073#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
74#define STATS_DECL(NAME, TYPE, MSG) \
75 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000076#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
Johannes Doerfert17b578b2019-08-14 21:46:25 +000077#define STATS_DECLTRACK(NAME, TYPE, MSG) \
Johannes Doerfert169af992019-08-20 06:09:56 +000078 { \
79 STATS_DECL(NAME, TYPE, MSG) \
80 STATS_TRACK(NAME, TYPE) \
81 }
Johannes Doerfert17b578b2019-08-14 21:46:25 +000082#define STATS_DECLTRACK_ARG_ATTR(NAME) \
83 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
84#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
85 STATS_DECLTRACK(NAME, CSArguments, \
86 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
87#define STATS_DECLTRACK_FN_ATTR(NAME) \
88 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
89#define STATS_DECLTRACK_CS_ATTR(NAME) \
90 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
91#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
92 STATS_DECLTRACK(NAME, FunctionReturn, \
Johannes Doerfert2db85282019-08-21 20:56:56 +000093 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
Johannes Doerfert17b578b2019-08-14 21:46:25 +000094#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
95 STATS_DECLTRACK(NAME, CSReturn, \
96 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
97#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
98 STATS_DECLTRACK(NAME, Floating, \
99 ("Number of floating values known to be '" #NAME "'"))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000100
Johannes Doerfertaade7822019-06-05 03:02:24 +0000101// TODO: Determine a good default value.
102//
103// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
104// (when run with the first 5 abstract attributes). The results also indicate
105// that we never reach 32 iterations but always find a fixpoint sooner.
106//
107// This will become more evolved once we perform two interleaved fixpoint
108// iterations: bottom-up and top-down.
109static cl::opt<unsigned>
110 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
111 cl::desc("Maximal number of fixpoint iterations."),
112 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000113static cl::opt<bool> VerifyMaxFixpointIterations(
114 "attributor-max-iterations-verify", cl::Hidden,
115 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
116 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000117
118static cl::opt<bool> DisableAttributor(
119 "attributor-disable", cl::Hidden,
120 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000121 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000122
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000123static cl::opt<bool> ManifestInternal(
124 "attributor-manifest-internal", cl::Hidden,
125 cl::desc("Manifest Attributor internal string attributes."),
126 cl::init(false));
127
Johannes Doerfertaade7822019-06-05 03:02:24 +0000128static cl::opt<bool> VerifyAttributor(
129 "attributor-verify", cl::Hidden,
130 cl::desc("Verify the Attributor deduction and "
131 "manifestation of attributes -- may issue false-positive errors"),
132 cl::init(false));
133
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000134static cl::opt<unsigned> DepRecInterval(
135 "attributor-dependence-recompute-interval", cl::Hidden,
136 cl::desc("Number of iterations until dependences are recomputed."),
137 cl::init(4));
138
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000139static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
140 cl::init(true), cl::Hidden);
141
142static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size",
143 cl::init(128), cl::Hidden);
144
Johannes Doerfertaade7822019-06-05 03:02:24 +0000145/// Logic operators for the change status enum class.
146///
147///{
148ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
149 return l == ChangeStatus::CHANGED ? l : r;
150}
151ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
152 return l == ChangeStatus::UNCHANGED ? l : r;
153}
154///}
155
Johannes Doerfertdef99282019-08-14 21:29:37 +0000156/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000157/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000158/// with the "returned" attribute. Once we cannot look through the value any
159/// further, the callback \p VisitValueCB is invoked and passed the current
160/// value, the \p State, and a flag to indicate if we stripped anything. To
161/// limit how much effort is invested, we will never visit more values than
162/// specified by \p MaxValues.
163template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000164static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000165 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000166 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000167 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000168
Johannes Doerfertdef99282019-08-14 21:29:37 +0000169 const AAIsDead *LivenessAA = nullptr;
170 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000171 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000172 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
173 /* TrackDependence */ false);
174 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000175
176 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000177 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000178 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000179 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000180
181 int Iteration = 0;
182 do {
183 Value *V = Worklist.pop_back_val();
184
185 // Check if we should process the current value. To prevent endless
186 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000187 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000188 continue;
189
190 // Make sure we limit the compile time for complex expressions.
191 if (Iteration++ >= MaxValues)
192 return false;
193
194 // Explicitly look through calls with a "returned" attribute if we do
195 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000196 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000197 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000198 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000199 } else {
200 CallSite CS(V);
201 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000202 for (Argument &Arg : CS.getCalledFunction()->args())
203 if (Arg.hasReturnedAttr()) {
204 NewV = CS.getArgOperand(Arg.getArgNo());
205 break;
206 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000207 }
208 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000209 if (NewV && NewV != V) {
210 Worklist.push_back(NewV);
211 continue;
212 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000213
214 // Look through select instructions, visit both potential values.
215 if (auto *SI = dyn_cast<SelectInst>(V)) {
216 Worklist.push_back(SI->getTrueValue());
217 Worklist.push_back(SI->getFalseValue());
218 continue;
219 }
220
Johannes Doerfertdef99282019-08-14 21:29:37 +0000221 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000222 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000223 assert(LivenessAA &&
224 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000225 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
226 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000227 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000228 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000229 continue;
230 }
231 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000232 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000233 continue;
234 }
235
236 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000237 if (!VisitValueCB(*V, State, Iteration > 1))
238 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000239 } while (!Worklist.empty());
240
Johannes Doerfert19b00432019-08-26 17:48:05 +0000241 // If we actually used liveness information so we have to record a dependence.
242 if (AnyDead)
243 A.recordDependence(*LivenessAA, QueryingAA);
244
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000245 // All values have been visited.
246 return true;
247}
248
Johannes Doerfertaade7822019-06-05 03:02:24 +0000249/// Return true if \p New is equal or worse than \p Old.
250static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
251 if (!Old.isIntAttribute())
252 return true;
253
254 return Old.getValueAsInt() >= New.getValueAsInt();
255}
256
257/// Return true if the information provided by \p Attr was added to the
258/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000259/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000260static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000261 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000262
263 if (Attr.isEnumAttribute()) {
264 Attribute::AttrKind Kind = Attr.getKindAsEnum();
265 if (Attrs.hasAttribute(AttrIdx, Kind))
266 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
267 return false;
268 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
269 return true;
270 }
271 if (Attr.isStringAttribute()) {
272 StringRef Kind = Attr.getKindAsString();
273 if (Attrs.hasAttribute(AttrIdx, Kind))
274 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
275 return false;
276 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
277 return true;
278 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000279 if (Attr.isIntAttribute()) {
280 Attribute::AttrKind Kind = Attr.getKindAsEnum();
281 if (Attrs.hasAttribute(AttrIdx, Kind))
282 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
283 return false;
284 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
285 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
286 return true;
287 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000288
289 llvm_unreachable("Expected enum or string attribute!");
290}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000291static const Value *getPointerOperand(const Instruction *I) {
292 if (auto *LI = dyn_cast<LoadInst>(I))
293 if (!LI->isVolatile())
294 return LI->getPointerOperand();
295
296 if (auto *SI = dyn_cast<StoreInst>(I))
297 if (!SI->isVolatile())
298 return SI->getPointerOperand();
299
300 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I))
301 if (!CXI->isVolatile())
302 return CXI->getPointerOperand();
303
304 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I))
305 if (!RMWI->isVolatile())
306 return RMWI->getPointerOperand();
307
308 return nullptr;
309}
310static const Value *getBasePointerOfAccessPointerOperand(const Instruction *I,
311 int64_t &BytesOffset,
312 const DataLayout &DL) {
313 const Value *Ptr = getPointerOperand(I);
314 if (!Ptr)
315 return nullptr;
316
317 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
318 /*AllowNonInbounds*/ false);
319}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000320
Johannes Doerfertece81902019-08-12 22:05:53 +0000321ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000322 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
323 if (getState().isAtFixpoint())
324 return HasChanged;
325
326 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
327
Johannes Doerfertece81902019-08-12 22:05:53 +0000328 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000329
330 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
331 << "\n");
332
333 return HasChanged;
334}
335
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000336ChangeStatus
337IRAttributeManifest::manifestAttrs(Attributor &A, IRPosition &IRP,
338 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000339 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000340 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000341
Johannes Doerfertaade7822019-06-05 03:02:24 +0000342 // In the following some generic code that will manifest attributes in
343 // DeducedAttrs if they improve the current IR. Due to the different
344 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000345
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000346 AttributeList Attrs;
347 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000348 case IRPosition::IRP_INVALID:
349 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000350 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000351 case IRPosition::IRP_ARGUMENT:
352 case IRPosition::IRP_FUNCTION:
353 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000354 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000355 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000356 case IRPosition::IRP_CALL_SITE:
357 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000358 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000359 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000360 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000361 }
362
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000363 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000364 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000365 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000366 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000367 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000368
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000369 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000370 }
371
372 if (HasChanged == ChangeStatus::UNCHANGED)
373 return HasChanged;
374
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000375 switch (PK) {
376 case IRPosition::IRP_ARGUMENT:
377 case IRPosition::IRP_FUNCTION:
378 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000379 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000380 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000381 case IRPosition::IRP_CALL_SITE:
382 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000383 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000384 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000385 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000386 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000387 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000388 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000389 }
390
391 return HasChanged;
392}
393
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000394const IRPosition IRPosition::EmptyKey(255);
395const IRPosition IRPosition::TombstoneKey(256);
396
397SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
398 IRPositions.emplace_back(IRP);
399
400 ImmutableCallSite ICS(&IRP.getAnchorValue());
401 switch (IRP.getPositionKind()) {
402 case IRPosition::IRP_INVALID:
403 case IRPosition::IRP_FLOAT:
404 case IRPosition::IRP_FUNCTION:
405 return;
406 case IRPosition::IRP_ARGUMENT:
407 case IRPosition::IRP_RETURNED:
408 IRPositions.emplace_back(
409 IRPosition::function(*IRP.getAssociatedFunction()));
410 return;
411 case IRPosition::IRP_CALL_SITE:
412 assert(ICS && "Expected call site!");
413 // TODO: We need to look at the operand bundles similar to the redirection
414 // in CallBase.
415 if (!ICS.hasOperandBundles())
416 if (const Function *Callee = ICS.getCalledFunction())
417 IRPositions.emplace_back(IRPosition::function(*Callee));
418 return;
419 case IRPosition::IRP_CALL_SITE_RETURNED:
420 assert(ICS && "Expected call site!");
421 // TODO: We need to look at the operand bundles similar to the redirection
422 // in CallBase.
423 if (!ICS.hasOperandBundles()) {
424 if (const Function *Callee = ICS.getCalledFunction()) {
425 IRPositions.emplace_back(IRPosition::returned(*Callee));
426 IRPositions.emplace_back(IRPosition::function(*Callee));
427 }
428 }
429 IRPositions.emplace_back(
430 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
431 return;
432 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
433 int ArgNo = IRP.getArgNo();
434 assert(ICS && ArgNo >= 0 && "Expected call site!");
435 // TODO: We need to look at the operand bundles similar to the redirection
436 // in CallBase.
437 if (!ICS.hasOperandBundles()) {
438 const Function *Callee = ICS.getCalledFunction();
439 if (Callee && Callee->arg_size() > unsigned(ArgNo))
440 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
441 if (Callee)
442 IRPositions.emplace_back(IRPosition::function(*Callee));
443 }
444 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
445 return;
446 }
447 }
448}
449
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000450bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
451 bool IgnoreSubsumingPositions) const {
452 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000453 for (Attribute::AttrKind AK : AKs)
454 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
455 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000456 // The first position returned by the SubsumingPositionIterator is
457 // always the position itself. If we ignore subsuming positions we
458 // are done after the first iteration.
459 if (IgnoreSubsumingPositions)
460 break;
461 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000462 return false;
463}
464
465void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
466 SmallVectorImpl<Attribute> &Attrs) const {
467 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this))
468 for (Attribute::AttrKind AK : AKs) {
469 const Attribute &Attr = EquivIRP.getAttr(AK);
470 if (Attr.getKindAsEnum() == AK)
471 Attrs.push_back(Attr);
472 }
473}
474
475void IRPosition::verify() {
476 switch (KindOrArgNo) {
477 default:
478 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
479 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
480 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000481 if (isa<Argument>(AnchorVal)) {
482 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000483 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000484 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
485 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000486 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000487 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000488 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000489 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
490 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000491 "Associated value mismatch!");
492 }
493 break;
494 case IRP_INVALID:
495 assert(!AnchorVal && "Expected no value for an invalid position!");
496 break;
497 case IRP_FLOAT:
498 assert((!isa<CallBase>(&getAssociatedValue()) &&
499 !isa<Argument>(&getAssociatedValue())) &&
500 "Expected specialized kind for call base and argument values!");
501 break;
502 case IRP_RETURNED:
503 assert(isa<Function>(AnchorVal) &&
504 "Expected function for a 'returned' position!");
505 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
506 break;
507 case IRP_CALL_SITE_RETURNED:
508 assert((isa<CallBase>(AnchorVal)) &&
509 "Expected call base for 'call site returned' position!");
510 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
511 break;
512 case IRP_CALL_SITE:
513 assert((isa<CallBase>(AnchorVal)) &&
514 "Expected call base for 'call site function' position!");
515 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
516 break;
517 case IRP_FUNCTION:
518 assert(isa<Function>(AnchorVal) &&
519 "Expected function for a 'function' position!");
520 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
521 break;
522 }
523}
524
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000525namespace {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000526/// Helper functions to clamp a state \p S of type \p StateType with the
527/// information in \p R and indicate/return if \p S did change (as-in update is
528/// required to be run again).
529///
530///{
531template <typename StateType>
532ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R);
533
534template <>
535ChangeStatus clampStateAndIndicateChange<IntegerState>(IntegerState &S,
536 const IntegerState &R) {
537 auto Assumed = S.getAssumed();
538 S ^= R;
539 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
540 : ChangeStatus::CHANGED;
541}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000542
543template <>
544ChangeStatus clampStateAndIndicateChange<BooleanState>(BooleanState &S,
545 const BooleanState &R) {
546 return clampStateAndIndicateChange<IntegerState>(S, R);
547}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000548///}
549
550/// Clamp the information known for all returned values of a function
551/// (identified by \p QueryingAA) into \p S.
552template <typename AAType, typename StateType = typename AAType::StateType>
553static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
554 StateType &S) {
555 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
556 << static_cast<const AbstractAttribute &>(QueryingAA)
557 << " into " << S << "\n");
558
559 assert((QueryingAA.getIRPosition().getPositionKind() ==
560 IRPosition::IRP_RETURNED ||
561 QueryingAA.getIRPosition().getPositionKind() ==
562 IRPosition::IRP_CALL_SITE_RETURNED) &&
563 "Can only clamp returned value states for a function returned or call "
564 "site returned position!");
565
566 // Use an optional state as there might not be any return values and we want
567 // to join (IntegerState::operator&) the state of all there are.
568 Optional<StateType> T;
569
570 // Callback for each possibly returned value.
571 auto CheckReturnValue = [&](Value &RV) -> bool {
572 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000573 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
574 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
575 << " @ " << RVPos << "\n");
576 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000577 if (T.hasValue())
578 *T &= AAS;
579 else
580 T = AAS;
581 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
582 << "\n");
583 return T->isValidState();
584 };
585
586 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
587 S.indicatePessimisticFixpoint();
588 else if (T.hasValue())
589 S ^= *T;
590}
591
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000592/// Helper class to compose two generic deduction
593template <typename AAType, typename Base, typename StateType,
594 template <typename...> class F, template <typename...> class G>
595struct AAComposeTwoGenericDeduction
596 : public F<AAType, G<AAType, Base, StateType>, StateType> {
597 AAComposeTwoGenericDeduction(const IRPosition &IRP)
598 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
599
600 /// See AbstractAttribute::updateImpl(...).
601 ChangeStatus updateImpl(Attributor &A) override {
602 return F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A) |
603 G<AAType, Base, StateType>::updateImpl(A);
604 }
605};
606
Johannes Doerfert234eda52019-08-16 19:51:23 +0000607/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000608template <typename AAType, typename Base,
609 typename StateType = typename AAType::StateType>
610struct AAReturnedFromReturnedValues : public Base {
611 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000612
613 /// See AbstractAttribute::updateImpl(...).
614 ChangeStatus updateImpl(Attributor &A) override {
615 StateType S;
616 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000617 // TODO: If we know we visited all returned values, thus no are assumed
618 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000619 return clampStateAndIndicateChange<StateType>(this->getState(), S);
620 }
621};
622
623/// Clamp the information known at all call sites for a given argument
624/// (identified by \p QueryingAA) into \p S.
625template <typename AAType, typename StateType = typename AAType::StateType>
626static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
627 StateType &S) {
628 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
629 << static_cast<const AbstractAttribute &>(QueryingAA)
630 << " into " << S << "\n");
631
632 assert(QueryingAA.getIRPosition().getPositionKind() ==
633 IRPosition::IRP_ARGUMENT &&
634 "Can only clamp call site argument states for an argument position!");
635
636 // Use an optional state as there might not be any return values and we want
637 // to join (IntegerState::operator&) the state of all there are.
638 Optional<StateType> T;
639
640 // The argument number which is also the call site argument number.
641 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
642
Johannes Doerfert661db042019-10-07 23:14:58 +0000643 auto CallSiteCheck = [&](AbstractCallSite ACS) {
644 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
645 // Check if a coresponding argument was found or if it is on not associated
646 // (which can happen for callback calls).
647 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
648 return false;
649
650 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
651 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
652 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000653 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000654 if (T.hasValue())
655 *T &= AAS;
656 else
657 T = AAS;
658 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
659 << "\n");
660 return T->isValidState();
661 };
662
663 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true))
664 S.indicatePessimisticFixpoint();
665 else if (T.hasValue())
666 S ^= *T;
667}
668
669/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000670template <typename AAType, typename Base,
671 typename StateType = typename AAType::StateType>
672struct AAArgumentFromCallSiteArguments : public Base {
673 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000674
675 /// See AbstractAttribute::updateImpl(...).
676 ChangeStatus updateImpl(Attributor &A) override {
677 StateType S;
678 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000679 // TODO: If we know we visited all incoming values, thus no are assumed
680 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000681 return clampStateAndIndicateChange<StateType>(this->getState(), S);
682 }
683};
684
685/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000686template <typename AAType, typename Base,
687 typename StateType = typename AAType::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000688struct AACallSiteReturnedFromReturned : public Base {
689 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000690
691 /// See AbstractAttribute::updateImpl(...).
692 ChangeStatus updateImpl(Attributor &A) override {
693 assert(this->getIRPosition().getPositionKind() ==
694 IRPosition::IRP_CALL_SITE_RETURNED &&
695 "Can only wrap function returned positions for call site returned "
696 "positions!");
697 auto &S = this->getState();
698
699 const Function *AssociatedFunction =
700 this->getIRPosition().getAssociatedFunction();
701 if (!AssociatedFunction)
702 return S.indicatePessimisticFixpoint();
703
704 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000705 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000706 return clampStateAndIndicateChange(
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000707 S, static_cast<const typename AAType::StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000708 }
709};
710
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000711/// Helper class for generic deduction using must-be-executed-context
712/// Base class is required to have `followUse` method.
713
714/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
715/// \param U Underlying use.
716/// \param I The user of the \p U.
717/// `followUse` returns true if the value should be tracked transitively.
718
719template <typename AAType, typename Base,
720 typename StateType = typename AAType::StateType>
721struct AAFromMustBeExecutedContext : public Base {
722 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
723
724 void initialize(Attributor &A) override {
725 Base::initialize(A);
726 IRPosition &IRP = this->getIRPosition();
727 Instruction *CtxI = IRP.getCtxI();
728
729 if (!CtxI)
730 return;
731
732 for (const Use &U : IRP.getAssociatedValue().uses())
733 Uses.insert(&U);
734 }
735
736 /// See AbstractAttribute::updateImpl(...).
737 ChangeStatus updateImpl(Attributor &A) override {
738 auto BeforeState = this->getState();
739 auto &S = this->getState();
740 Instruction *CtxI = this->getIRPosition().getCtxI();
741 if (!CtxI)
742 return ChangeStatus::UNCHANGED;
743
744 MustBeExecutedContextExplorer &Explorer =
745 A.getInfoCache().getMustBeExecutedContextExplorer();
746
747 SetVector<const Use *> NextUses;
748
749 for (const Use *U : Uses) {
750 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
751 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
752 bool Found = EIt.count(UserI);
753 while (!Found && ++EIt != EEnd)
754 Found = EIt.getCurrentInst() == UserI;
755 if (Found && Base::followUse(A, U, UserI))
756 for (const Use &Us : UserI->uses())
757 NextUses.insert(&Us);
758 }
759 }
760 for (const Use *U : NextUses)
761 Uses.insert(U);
762
763 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
764 }
765
766private:
767 /// Container for (transitive) uses of the associated value.
768 SetVector<const Use *> Uses;
769};
770
771template <typename AAType, typename Base,
772 typename StateType = typename AAType::StateType>
773using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
774 AAComposeTwoGenericDeduction<AAType, Base, StateType,
775 AAFromMustBeExecutedContext,
776 AAArgumentFromCallSiteArguments>;
777
778template <typename AAType, typename Base,
779 typename StateType = typename AAType::StateType>
780using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
781 AAComposeTwoGenericDeduction<AAType, Base, StateType,
782 AAFromMustBeExecutedContext,
783 AACallSiteReturnedFromReturned>;
784
Stefan Stipanovic53605892019-06-27 11:27:54 +0000785/// -----------------------NoUnwind Function Attribute--------------------------
786
Johannes Doerfert344d0382019-08-07 22:34:26 +0000787struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000788 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000789
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000790 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000791 return getAssumed() ? "nounwind" : "may-unwind";
792 }
793
794 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000795 ChangeStatus updateImpl(Attributor &A) override {
796 auto Opcodes = {
797 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
798 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
799 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
800
801 auto CheckForNoUnwind = [&](Instruction &I) {
802 if (!I.mayThrow())
803 return true;
804
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000805 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
806 const auto &NoUnwindAA =
807 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
808 return NoUnwindAA.isAssumedNoUnwind();
809 }
810 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000811 };
812
813 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
814 return indicatePessimisticFixpoint();
815
816 return ChangeStatus::UNCHANGED;
817 }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000818};
819
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000820struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000821 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000822
823 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000824 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000825};
826
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000827/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000828struct AANoUnwindCallSite final : AANoUnwindImpl {
829 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
830
831 /// See AbstractAttribute::initialize(...).
832 void initialize(Attributor &A) override {
833 AANoUnwindImpl::initialize(A);
834 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000835 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000836 indicatePessimisticFixpoint();
837 }
838
839 /// See AbstractAttribute::updateImpl(...).
840 ChangeStatus updateImpl(Attributor &A) override {
841 // TODO: Once we have call site specific value information we can provide
842 // call site specific liveness information and then it makes
843 // sense to specialize attributes for call sites arguments instead of
844 // redirecting requests to the callee argument.
845 Function *F = getAssociatedFunction();
846 const IRPosition &FnPos = IRPosition::function(*F);
847 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
848 return clampStateAndIndicateChange(
849 getState(),
850 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
851 }
852
853 /// See AbstractAttribute::trackStatistics()
854 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
855};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000856
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000857/// --------------------- Function Return Values -------------------------------
858
859/// "Attribute" that collects all potential returned values and the return
860/// instructions that they arise from.
861///
862/// If there is a unique returned value R, the manifest method will:
863/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +0000864class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000865
866 /// Mapping of values potentially returned by the associated function to the
867 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +0000868 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000869
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000870 /// Mapping to remember the number of returned values for a call site such
871 /// that we can avoid updates if nothing changed.
872 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
873
874 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000875 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000876
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000877 /// State flags
878 ///
879 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000880 bool IsFixed = false;
881 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000882 ///}
883
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000884public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000885 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000886
887 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +0000888 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000889 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000890 IsFixed = false;
891 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000892 ReturnedValues.clear();
893
Johannes Doerfertdef99282019-08-14 21:29:37 +0000894 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000895 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000896 indicatePessimisticFixpoint();
897 return;
898 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000899
900 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000901 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000902
903 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000904 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000905 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000906 auto &ReturnInstSet = ReturnedValues[&Arg];
907 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
908 ReturnInstSet.insert(cast<ReturnInst>(RI));
909
910 indicateOptimisticFixpoint();
911 return;
912 }
913 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000914
915 if (!F->hasExactDefinition())
916 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000917 }
918
919 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000920 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000921
922 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000923 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000924
925 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000926 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000927
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000928 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +0000929 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000930
Johannes Doerfertdef99282019-08-14 21:29:37 +0000931 llvm::iterator_range<iterator> returned_values() override {
932 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
933 }
934
935 llvm::iterator_range<const_iterator> returned_values() const override {
936 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
937 }
938
Johannes Doerfert695089e2019-08-23 15:23:49 +0000939 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000940 return UnresolvedCalls;
941 }
942
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000943 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000944 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000945 return isValidState() ? ReturnedValues.size() : -1;
946 }
947
948 /// Return an assumed unique return value if a single candidate is found. If
949 /// there cannot be one, return a nullptr. If it is not clear yet, return the
950 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000951 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000952
Johannes Doerfert14a04932019-08-07 22:27:24 +0000953 /// See AbstractState::checkForAllReturnedValues(...).
954 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +0000955 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +0000956 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000957
958 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000959 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000960
961 /// See AbstractState::isAtFixpoint().
962 bool isAtFixpoint() const override { return IsFixed; }
963
964 /// See AbstractState::isValidState().
965 bool isValidState() const override { return IsValidState; }
966
967 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000968 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000969 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000970 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000971 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000972
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000973 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000974 IsFixed = true;
975 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000976 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000977 }
978};
979
980ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
981 ChangeStatus Changed = ChangeStatus::UNCHANGED;
982
983 // Bookkeeping.
984 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000985 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
986 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000987
988 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +0000989 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000990
991 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
992 return Changed;
993
994 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000995 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
996 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000997
Johannes Doerfert23400e612019-08-23 17:41:37 +0000998 // Callback to replace the uses of CB with the constant C.
999 auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
1000 if (CB.getNumUses() == 0)
1001 return ChangeStatus::UNCHANGED;
1002 CB.replaceAllUsesWith(&C);
1003 return ChangeStatus::CHANGED;
1004 };
1005
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001006 // If the assumed unique return value is an argument, annotate it.
1007 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001008 getIRPosition() = IRPosition::argument(*UniqueRVArg);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001009 Changed = IRAttribute::manifest(A);
1010 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
1011 // We can replace the returned value with the unique returned constant.
1012 Value &AnchorValue = getAnchorValue();
1013 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1014 for (const Use &U : F->uses())
1015 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001016 if (CB->isCallee(&U)) {
1017 Constant *RVCCast =
1018 ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
1019 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1020 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001021 } else {
1022 assert(isa<CallBase>(AnchorValue) &&
1023 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001024 Constant *RVCCast =
1025 ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
1026 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001027 }
1028 if (Changed == ChangeStatus::CHANGED)
1029 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1030 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001031 }
1032
1033 return Changed;
1034}
1035
1036const std::string AAReturnedValuesImpl::getAsStr() const {
1037 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001038 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001039 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001040}
1041
Johannes Doerfert14a04932019-08-07 22:27:24 +00001042Optional<Value *>
1043AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1044 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001045 // undef values that can also be present, it is assumed to be the actual
1046 // return value and forwarded to the caller of this method. If there are
1047 // multiple, a nullptr is returned indicating there cannot be a unique
1048 // returned value.
1049 Optional<Value *> UniqueRV;
1050
Johannes Doerfert14a04932019-08-07 22:27:24 +00001051 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001052 // If we found a second returned value and neither the current nor the saved
1053 // one is an undef, there is no unique returned value. Undefs are special
1054 // since we can pretend they have any value.
1055 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1056 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1057 UniqueRV = nullptr;
1058 return false;
1059 }
1060
1061 // Do not overwrite a value with an undef.
1062 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1063 UniqueRV = &RV;
1064
1065 return true;
1066 };
1067
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001068 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001069 UniqueRV = nullptr;
1070
1071 return UniqueRV;
1072}
1073
Johannes Doerfert14a04932019-08-07 22:27:24 +00001074bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001075 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001076 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001077 if (!isValidState())
1078 return false;
1079
1080 // Check all returned values but ignore call sites as long as we have not
1081 // encountered an overdefined one during an update.
1082 for (auto &It : ReturnedValues) {
1083 Value *RV = It.first;
1084
Johannes Doerfertdef99282019-08-14 21:29:37 +00001085 CallBase *CB = dyn_cast<CallBase>(RV);
1086 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001087 continue;
1088
Johannes Doerfert695089e2019-08-23 15:23:49 +00001089 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001090 return false;
1091 }
1092
1093 return true;
1094}
1095
Johannes Doerfertece81902019-08-12 22:05:53 +00001096ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001097 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1098 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001099
Johannes Doerfertdef99282019-08-14 21:29:37 +00001100 // State used in the value traversals starting in returned values.
1101 struct RVState {
1102 // The map in which we collect return values -> return instrs.
1103 decltype(ReturnedValues) &RetValsMap;
1104 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001105 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001106 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001107 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001108 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001109
Johannes Doerfertdef99282019-08-14 21:29:37 +00001110 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001111 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001112 auto Size = RVS.RetValsMap[&Val].size();
1113 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1114 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1115 RVS.Changed |= Inserted;
1116 LLVM_DEBUG({
1117 if (Inserted)
1118 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1119 << " => " << RVS.RetInsts.size() << "\n";
1120 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001121 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001122 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001123
Johannes Doerfertdef99282019-08-14 21:29:37 +00001124 // Helper method to invoke the generic value traversal.
1125 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1126 IRPosition RetValPos = IRPosition::value(RV);
1127 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1128 RVS, VisitValueCB);
1129 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001130
Johannes Doerfertdef99282019-08-14 21:29:37 +00001131 // Callback for all "return intructions" live in the associated function.
1132 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1133 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001134 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001135 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001136 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1137 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001138
Johannes Doerfertdef99282019-08-14 21:29:37 +00001139 // Start by discovering returned values from all live returned instructions in
1140 // the associated function.
1141 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1142 return indicatePessimisticFixpoint();
1143
1144 // Once returned values "directly" present in the code are handled we try to
1145 // resolve returned calls.
1146 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001147 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001148 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1149 << " by #" << It.second.size() << " RIs\n");
1150 CallBase *CB = dyn_cast<CallBase>(It.first);
1151 if (!CB || UnresolvedCalls.count(CB))
1152 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001153
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001154 if (!CB->getCalledFunction()) {
1155 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1156 << "\n");
1157 UnresolvedCalls.insert(CB);
1158 continue;
1159 }
1160
1161 // TODO: use the function scope once we have call site AAReturnedValues.
1162 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1163 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001164 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
1165 << static_cast<const AbstractAttribute &>(RetValAA)
1166 << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001167
1168 // Skip dead ends, thus if we do not know anything about the returned
1169 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001170 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001171 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1172 << "\n");
1173 UnresolvedCalls.insert(CB);
1174 continue;
1175 }
1176
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001177 // Do not try to learn partial information. If the callee has unresolved
1178 // return values we will treat the call as unresolved/opaque.
1179 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1180 if (!RetValAAUnresolvedCalls.empty()) {
1181 UnresolvedCalls.insert(CB);
1182 continue;
1183 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001184
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001185 // Now check if we can track transitively returned values. If possible, thus
1186 // if all return value can be represented in the current scope, do so.
1187 bool Unresolved = false;
1188 for (auto &RetValAAIt : RetValAA.returned_values()) {
1189 Value *RetVal = RetValAAIt.first;
1190 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1191 isa<Constant>(RetVal))
1192 continue;
1193 // Anything that did not fit in the above categories cannot be resolved,
1194 // mark the call as unresolved.
1195 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1196 "cannot be translated: "
1197 << *RetVal << "\n");
1198 UnresolvedCalls.insert(CB);
1199 Unresolved = true;
1200 break;
1201 }
1202
1203 if (Unresolved)
1204 continue;
1205
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001206 // Now track transitively returned values.
1207 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1208 if (NumRetAA == RetValAA.getNumReturnValues()) {
1209 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1210 "changed since it was seen last\n");
1211 continue;
1212 }
1213 NumRetAA = RetValAA.getNumReturnValues();
1214
Johannes Doerfertdef99282019-08-14 21:29:37 +00001215 for (auto &RetValAAIt : RetValAA.returned_values()) {
1216 Value *RetVal = RetValAAIt.first;
1217 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1218 // Arguments are mapped to call site operands and we begin the traversal
1219 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001220 bool Unused = false;
1221 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001222 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1223 continue;
1224 } else if (isa<CallBase>(RetVal)) {
1225 // Call sites are resolved by the callee attribute over time, no need to
1226 // do anything for us.
1227 continue;
1228 } else if (isa<Constant>(RetVal)) {
1229 // Constants are valid everywhere, we can simply take them.
1230 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1231 continue;
1232 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001233 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001234 }
1235
Johannes Doerfertdef99282019-08-14 21:29:37 +00001236 // To avoid modifications to the ReturnedValues map while we iterate over it
1237 // we kept record of potential new entries in a copy map, NewRVsMap.
1238 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001239 assert(!It.second.empty() && "Entry does not add anything.");
1240 auto &ReturnInsts = ReturnedValues[It.first];
1241 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001242 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001243 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1244 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001245 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001246 }
1247 }
1248
Johannes Doerfertdef99282019-08-14 21:29:37 +00001249 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1250 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001251}
1252
Johannes Doerfertdef99282019-08-14 21:29:37 +00001253struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1254 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1255
1256 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001257 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001258};
1259
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001260/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001261struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1262 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1263
1264 /// See AbstractAttribute::initialize(...).
1265 void initialize(Attributor &A) override {
1266 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001267 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001268 // sense to specialize attributes for call sites instead of
1269 // redirecting requests to the callee.
1270 llvm_unreachable("Abstract attributes for returned values are not "
1271 "supported for call sites yet!");
1272 }
1273
1274 /// See AbstractAttribute::updateImpl(...).
1275 ChangeStatus updateImpl(Attributor &A) override {
1276 return indicatePessimisticFixpoint();
1277 }
1278
1279 /// See AbstractAttribute::trackStatistics()
1280 void trackStatistics() const override {}
1281};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001282
Stefan Stipanovic06263672019-07-11 21:37:40 +00001283/// ------------------------ NoSync Function Attribute -------------------------
1284
Johannes Doerfert344d0382019-08-07 22:34:26 +00001285struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001286 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001287
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001288 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001289 return getAssumed() ? "nosync" : "may-sync";
1290 }
1291
1292 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001293 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001294
Stefan Stipanovic06263672019-07-11 21:37:40 +00001295 /// Helper function used to determine whether an instruction is non-relaxed
1296 /// atomic. In other words, if an atomic instruction does not have unordered
1297 /// or monotonic ordering
1298 static bool isNonRelaxedAtomic(Instruction *I);
1299
1300 /// Helper function used to determine whether an instruction is volatile.
1301 static bool isVolatile(Instruction *I);
1302
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001303 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1304 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001305 static bool isNoSyncIntrinsic(Instruction *I);
1306};
1307
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001308bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001309 if (!I->isAtomic())
1310 return false;
1311
1312 AtomicOrdering Ordering;
1313 switch (I->getOpcode()) {
1314 case Instruction::AtomicRMW:
1315 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1316 break;
1317 case Instruction::Store:
1318 Ordering = cast<StoreInst>(I)->getOrdering();
1319 break;
1320 case Instruction::Load:
1321 Ordering = cast<LoadInst>(I)->getOrdering();
1322 break;
1323 case Instruction::Fence: {
1324 auto *FI = cast<FenceInst>(I);
1325 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1326 return false;
1327 Ordering = FI->getOrdering();
1328 break;
1329 }
1330 case Instruction::AtomicCmpXchg: {
1331 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1332 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1333 // Only if both are relaxed, than it can be treated as relaxed.
1334 // Otherwise it is non-relaxed.
1335 if (Success != AtomicOrdering::Unordered &&
1336 Success != AtomicOrdering::Monotonic)
1337 return true;
1338 if (Failure != AtomicOrdering::Unordered &&
1339 Failure != AtomicOrdering::Monotonic)
1340 return true;
1341 return false;
1342 }
1343 default:
1344 llvm_unreachable(
1345 "New atomic operations need to be known in the attributor.");
1346 }
1347
1348 // Relaxed.
1349 if (Ordering == AtomicOrdering::Unordered ||
1350 Ordering == AtomicOrdering::Monotonic)
1351 return false;
1352 return true;
1353}
1354
1355/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1356/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001357bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001358 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1359 switch (II->getIntrinsicID()) {
1360 /// Element wise atomic memory intrinsics are can only be unordered,
1361 /// therefore nosync.
1362 case Intrinsic::memset_element_unordered_atomic:
1363 case Intrinsic::memmove_element_unordered_atomic:
1364 case Intrinsic::memcpy_element_unordered_atomic:
1365 return true;
1366 case Intrinsic::memset:
1367 case Intrinsic::memmove:
1368 case Intrinsic::memcpy:
1369 if (!cast<MemIntrinsic>(II)->isVolatile())
1370 return true;
1371 return false;
1372 default:
1373 return false;
1374 }
1375 }
1376 return false;
1377}
1378
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001379bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001380 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1381 "Calls should not be checked here");
1382
1383 switch (I->getOpcode()) {
1384 case Instruction::AtomicRMW:
1385 return cast<AtomicRMWInst>(I)->isVolatile();
1386 case Instruction::Store:
1387 return cast<StoreInst>(I)->isVolatile();
1388 case Instruction::Load:
1389 return cast<LoadInst>(I)->isVolatile();
1390 case Instruction::AtomicCmpXchg:
1391 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1392 default:
1393 return false;
1394 }
1395}
1396
Johannes Doerfertece81902019-08-12 22:05:53 +00001397ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001398
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001399 auto CheckRWInstForNoSync = [&](Instruction &I) {
1400 /// We are looking for volatile instructions or Non-Relaxed atomics.
1401 /// FIXME: We should ipmrove the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001402
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001403 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1404 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001405
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001406 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1407 if (ICS.hasFnAttr(Attribute::NoSync))
1408 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001409
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001410 const auto &NoSyncAA =
1411 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1412 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001413 return true;
1414 return false;
1415 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001416
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001417 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1418 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001419
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001420 return false;
1421 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001422
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001423 auto CheckForNoSync = [&](Instruction &I) {
1424 // At this point we handled all read/write effects and they are all
1425 // nosync, so they can be skipped.
1426 if (I.mayReadOrWriteMemory())
1427 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001428
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001429 // non-convergent and readnone imply nosync.
1430 return !ImmutableCallSite(&I).isConvergent();
1431 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001432
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001433 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1434 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001435 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001436
Stefan Stipanovic06263672019-07-11 21:37:40 +00001437 return ChangeStatus::UNCHANGED;
1438}
1439
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001440struct AANoSyncFunction final : public AANoSyncImpl {
1441 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1442
1443 /// See AbstractAttribute::trackStatistics()
1444 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1445};
1446
1447/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001448struct AANoSyncCallSite final : AANoSyncImpl {
1449 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1450
1451 /// See AbstractAttribute::initialize(...).
1452 void initialize(Attributor &A) override {
1453 AANoSyncImpl::initialize(A);
1454 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001455 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001456 indicatePessimisticFixpoint();
1457 }
1458
1459 /// See AbstractAttribute::updateImpl(...).
1460 ChangeStatus updateImpl(Attributor &A) override {
1461 // TODO: Once we have call site specific value information we can provide
1462 // call site specific liveness information and then it makes
1463 // sense to specialize attributes for call sites arguments instead of
1464 // redirecting requests to the callee argument.
1465 Function *F = getAssociatedFunction();
1466 const IRPosition &FnPos = IRPosition::function(*F);
1467 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1468 return clampStateAndIndicateChange(
1469 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1470 }
1471
1472 /// See AbstractAttribute::trackStatistics()
1473 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1474};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001475
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001476/// ------------------------ No-Free Attributes ----------------------------
1477
Johannes Doerfert344d0382019-08-07 22:34:26 +00001478struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001479 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001480
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001481 /// See AbstractAttribute::updateImpl(...).
1482 ChangeStatus updateImpl(Attributor &A) override {
1483 auto CheckForNoFree = [&](Instruction &I) {
1484 ImmutableCallSite ICS(&I);
1485 if (ICS.hasFnAttr(Attribute::NoFree))
1486 return true;
1487
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001488 const auto &NoFreeAA =
1489 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1490 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001491 };
1492
1493 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1494 return indicatePessimisticFixpoint();
1495 return ChangeStatus::UNCHANGED;
1496 }
1497
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001498 /// See AbstractAttribute::getAsStr().
1499 const std::string getAsStr() const override {
1500 return getAssumed() ? "nofree" : "may-free";
1501 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001502};
1503
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001504struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001505 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001506
1507 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001508 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001509};
1510
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001511/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001512struct AANoFreeCallSite final : AANoFreeImpl {
1513 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1514
1515 /// See AbstractAttribute::initialize(...).
1516 void initialize(Attributor &A) override {
1517 AANoFreeImpl::initialize(A);
1518 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001519 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001520 indicatePessimisticFixpoint();
1521 }
1522
1523 /// See AbstractAttribute::updateImpl(...).
1524 ChangeStatus updateImpl(Attributor &A) override {
1525 // TODO: Once we have call site specific value information we can provide
1526 // call site specific liveness information and then it makes
1527 // sense to specialize attributes for call sites arguments instead of
1528 // redirecting requests to the callee argument.
1529 Function *F = getAssociatedFunction();
1530 const IRPosition &FnPos = IRPosition::function(*F);
1531 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1532 return clampStateAndIndicateChange(
1533 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1534 }
1535
1536 /// See AbstractAttribute::trackStatistics()
1537 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1538};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001539
Hideto Ueno54869ec2019-07-15 06:49:04 +00001540/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001541static int64_t getKnownNonNullAndDerefBytesForUse(
1542 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1543 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
1544 // TODO: Add GEP support
1545 TrackUse = false;
1546
1547 const Function *F = I->getFunction();
1548 bool NullPointerIsDefined = F ? F->nullPointerIsDefined() : true;
1549 const DataLayout &DL = A.getInfoCache().getDL();
1550 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1551 if (ICS.isBundleOperand(U))
1552 return 0;
1553
1554 if (ICS.isCallee(U)) {
1555 IsNonNull |= !NullPointerIsDefined;
1556 return 0;
1557 }
1558
1559 unsigned ArgNo = ICS.getArgumentNo(U);
1560 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
1561 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP);
1562 IsNonNull |= DerefAA.isKnownNonNull();
1563 return DerefAA.getKnownDereferenceableBytes();
1564 }
1565
1566 int64_t Offset;
1567 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
1568 if (Base == &AssociatedValue) {
1569 int64_t DerefBytes =
1570 Offset +
1571 (int64_t)DL.getTypeStoreSize(
1572 getPointerOperand(I)->getType()->getPointerElementType());
1573
1574 IsNonNull |= !NullPointerIsDefined;
1575 return DerefBytes;
1576 }
1577 }
1578
1579 return 0;
1580}
Johannes Doerfert344d0382019-08-07 22:34:26 +00001581struct AANonNullImpl : AANonNull {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001582 AANonNullImpl(const IRPosition &IRP) : AANonNull(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001583
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001584 /// See AbstractAttribute::initialize(...).
1585 void initialize(Attributor &A) override {
1586 if (hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
1587 indicateOptimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001588 else
1589 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001590 }
1591
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001592 /// See AAFromMustBeExecutedContext
1593 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1594 bool IsNonNull = false;
1595 bool TrackUse = false;
1596 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1597 IsNonNull, TrackUse);
1598 takeKnownMaximum(IsNonNull);
1599 return TrackUse;
1600 }
1601
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001602 /// See AbstractAttribute::getAsStr().
1603 const std::string getAsStr() const override {
1604 return getAssumed() ? "nonnull" : "may-null";
1605 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001606};
1607
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001608/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001609struct AANonNullFloating
1610 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1611 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1612 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001613
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001614 /// See AbstractAttribute::initialize(...).
1615 void initialize(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001616 Base::initialize(A);
Hideto Ueno54869ec2019-07-15 06:49:04 +00001617
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001618 if (isAtFixpoint())
1619 return;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001620
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001621 const IRPosition &IRP = getIRPosition();
1622 const Value &V = IRP.getAssociatedValue();
1623 const DataLayout &DL = A.getDataLayout();
Hideto Ueno54869ec2019-07-15 06:49:04 +00001624
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001625 // TODO: This context sensitive query should be removed once we can do
1626 // context sensitive queries in the genericValueTraversal below.
1627 if (isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, IRP.getCtxI(),
1628 /* TODO: DT */ nullptr))
1629 indicateOptimisticFixpoint();
1630 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001631
1632 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001633 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001634 ChangeStatus Change = Base::updateImpl(A);
1635 if (isKnownNonNull())
1636 return Change;
1637
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001638 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001639
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001640 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
1641 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001642 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1643 if (!Stripped && this == &AA) {
1644 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr,
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001645 /* TODO: CtxI */ nullptr,
1646 /* TODO: DT */ nullptr))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001647 T.indicatePessimisticFixpoint();
1648 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001649 // Use abstract attribute information.
1650 const AANonNull::StateType &NS =
1651 static_cast<const AANonNull::StateType &>(AA.getState());
1652 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001653 }
1654 return T.isValidState();
1655 };
1656
1657 StateType T;
1658 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1659 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001660 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001661
1662 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001663 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001664
1665 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001666 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001667};
1668
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001669/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001670struct AANonNullReturned final
1671 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001672 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001673 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001674
1675 /// See AbstractAttribute::trackStatistics()
1676 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1677};
1678
Hideto Ueno54869ec2019-07-15 06:49:04 +00001679/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001680struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001681 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1682 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001683 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001684 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1685 AANonNullImpl>(
1686 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001687
1688 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001689 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001690};
1691
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001692struct AANonNullCallSiteArgument final : AANonNullFloating {
1693 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001694
1695 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001696 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001697};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001698
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001699/// NonNull attribute for a call site return position.
1700struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001701 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1702 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001703 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001704 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1705 AANonNullImpl>(
1706 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001707
1708 /// See AbstractAttribute::trackStatistics()
1709 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1710};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001711
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001712/// ------------------------ No-Recurse Attributes ----------------------------
1713
1714struct AANoRecurseImpl : public AANoRecurse {
1715 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1716
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001717 /// See AbstractAttribute::getAsStr()
1718 const std::string getAsStr() const override {
1719 return getAssumed() ? "norecurse" : "may-recurse";
1720 }
1721};
1722
1723struct AANoRecurseFunction final : AANoRecurseImpl {
1724 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1725
Hideto Ueno63f60662019-09-21 15:13:19 +00001726 /// See AbstractAttribute::initialize(...).
1727 void initialize(Attributor &A) override {
1728 AANoRecurseImpl::initialize(A);
1729 if (const Function *F = getAnchorScope())
1730 if (A.getInfoCache().getSccSize(*F) == 1)
1731 return;
1732 indicatePessimisticFixpoint();
1733 }
1734
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001735 /// See AbstractAttribute::updateImpl(...).
1736 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00001737
1738 auto CheckForNoRecurse = [&](Instruction &I) {
1739 ImmutableCallSite ICS(&I);
1740 if (ICS.hasFnAttr(Attribute::NoRecurse))
1741 return true;
1742
1743 const auto &NoRecurseAA =
1744 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
1745 if (!NoRecurseAA.isAssumedNoRecurse())
1746 return false;
1747
1748 // Recursion to the same function
1749 if (ICS.getCalledFunction() == getAnchorScope())
1750 return false;
1751
1752 return true;
1753 };
1754
1755 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
1756 return indicatePessimisticFixpoint();
1757 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001758 }
1759
1760 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1761};
1762
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001763/// NoRecurse attribute deduction for a call sites.
1764struct AANoRecurseCallSite final : AANoRecurseImpl {
1765 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1766
1767 /// See AbstractAttribute::initialize(...).
1768 void initialize(Attributor &A) override {
1769 AANoRecurseImpl::initialize(A);
1770 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001771 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001772 indicatePessimisticFixpoint();
1773 }
1774
1775 /// See AbstractAttribute::updateImpl(...).
1776 ChangeStatus updateImpl(Attributor &A) override {
1777 // TODO: Once we have call site specific value information we can provide
1778 // call site specific liveness information and then it makes
1779 // sense to specialize attributes for call sites arguments instead of
1780 // redirecting requests to the callee argument.
1781 Function *F = getAssociatedFunction();
1782 const IRPosition &FnPos = IRPosition::function(*F);
1783 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
1784 return clampStateAndIndicateChange(
1785 getState(),
1786 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
1787 }
1788
1789 /// See AbstractAttribute::trackStatistics()
1790 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
1791};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001792
Hideto Ueno11d37102019-07-17 15:15:43 +00001793/// ------------------------ Will-Return Attributes ----------------------------
1794
Hideto Ueno11d37102019-07-17 15:15:43 +00001795// Helper function that checks whether a function has any cycle.
1796// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001797static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00001798 SmallPtrSet<BasicBlock *, 32> Visited;
1799
1800 // Traverse BB by dfs and check whether successor is already visited.
1801 for (BasicBlock *BB : depth_first(&F)) {
1802 Visited.insert(BB);
1803 for (auto *SuccBB : successors(BB)) {
1804 if (Visited.count(SuccBB))
1805 return true;
1806 }
1807 }
1808 return false;
1809}
1810
1811// Helper function that checks the function have a loop which might become an
1812// endless loop
1813// FIXME: Any cycle is regarded as endless loop for now.
1814// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001815static bool containsPossiblyEndlessLoop(Function *F) {
1816 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00001817}
1818
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001819struct AAWillReturnImpl : public AAWillReturn {
1820 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00001821
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001822 /// See AbstractAttribute::initialize(...).
1823 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001824 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00001825
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001826 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001827 if (containsPossiblyEndlessLoop(F))
1828 indicatePessimisticFixpoint();
1829 }
Hideto Ueno11d37102019-07-17 15:15:43 +00001830
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001831 /// See AbstractAttribute::updateImpl(...).
1832 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001833 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001834 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
1835 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
1836 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001837 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001838 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001839 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001840 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
1841 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001842 };
1843
1844 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
1845 return indicatePessimisticFixpoint();
1846
1847 return ChangeStatus::UNCHANGED;
1848 }
1849
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001850 /// See AbstractAttribute::getAsStr()
1851 const std::string getAsStr() const override {
1852 return getAssumed() ? "willreturn" : "may-noreturn";
1853 }
1854};
1855
1856struct AAWillReturnFunction final : AAWillReturnImpl {
1857 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1858
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001859 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001860 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001861};
Hideto Ueno11d37102019-07-17 15:15:43 +00001862
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001863/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001864struct AAWillReturnCallSite final : AAWillReturnImpl {
1865 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
1866
1867 /// See AbstractAttribute::initialize(...).
1868 void initialize(Attributor &A) override {
1869 AAWillReturnImpl::initialize(A);
1870 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001871 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001872 indicatePessimisticFixpoint();
1873 }
1874
1875 /// See AbstractAttribute::updateImpl(...).
1876 ChangeStatus updateImpl(Attributor &A) override {
1877 // TODO: Once we have call site specific value information we can provide
1878 // call site specific liveness information and then it makes
1879 // sense to specialize attributes for call sites arguments instead of
1880 // redirecting requests to the callee argument.
1881 Function *F = getAssociatedFunction();
1882 const IRPosition &FnPos = IRPosition::function(*F);
1883 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
1884 return clampStateAndIndicateChange(
1885 getState(),
1886 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
1887 }
1888
1889 /// See AbstractAttribute::trackStatistics()
1890 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
1891};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001892
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001893/// ------------------------ NoAlias Argument Attribute ------------------------
1894
Johannes Doerfert344d0382019-08-07 22:34:26 +00001895struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001896 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001897
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001898 const std::string getAsStr() const override {
1899 return getAssumed() ? "noalias" : "may-alias";
1900 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001901};
1902
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001903/// NoAlias attribute for a floating value.
1904struct AANoAliasFloating final : AANoAliasImpl {
1905 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1906
Hideto Uenocbab3342019-08-29 05:52:00 +00001907 /// See AbstractAttribute::initialize(...).
1908 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001909 AANoAliasImpl::initialize(A);
1910 if (isa<AllocaInst>(getAnchorValue()))
1911 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001912 }
1913
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001914 /// See AbstractAttribute::updateImpl(...).
1915 ChangeStatus updateImpl(Attributor &A) override {
1916 // TODO: Implement this.
1917 return indicatePessimisticFixpoint();
1918 }
1919
1920 /// See AbstractAttribute::trackStatistics()
1921 void trackStatistics() const override {
1922 STATS_DECLTRACK_FLOATING_ATTR(noalias)
1923 }
1924};
1925
1926/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00001927struct AANoAliasArgument final
1928 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
1929 AANoAliasArgument(const IRPosition &IRP)
1930 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001931
1932 /// See AbstractAttribute::trackStatistics()
1933 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
1934};
1935
1936struct AANoAliasCallSiteArgument final : AANoAliasImpl {
1937 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1938
Hideto Uenocbab3342019-08-29 05:52:00 +00001939 /// See AbstractAttribute::initialize(...).
1940 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00001941 // See callsite argument attribute and callee argument attribute.
1942 ImmutableCallSite ICS(&getAnchorValue());
1943 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
1944 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001945 }
1946
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001947 /// See AbstractAttribute::updateImpl(...).
1948 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001949 // We can deduce "noalias" if the following conditions hold.
1950 // (i) Associated value is assumed to be noalias in the definition.
1951 // (ii) Associated value is assumed to be no-capture in all the uses
1952 // possibly executed before this callsite.
1953 // (iii) There is no other pointer argument which could alias with the
1954 // value.
1955
1956 const Value &V = getAssociatedValue();
1957 const IRPosition IRP = IRPosition::value(V);
1958
1959 // (i) Check whether noalias holds in the definition.
1960
1961 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
1962
1963 if (!NoAliasAA.isAssumedNoAlias())
1964 return indicatePessimisticFixpoint();
1965
1966 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
1967 << " is assumed NoAlias in the definition\n");
1968
1969 // (ii) Check whether the value is captured in the scope using AANoCapture.
1970 // FIXME: This is conservative though, it is better to look at CFG and
1971 // check only uses possibly executed before this callsite.
1972
1973 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
1974 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned())
1975 return indicatePessimisticFixpoint();
1976
1977 // (iii) Check there is no other pointer argument which could alias with the
1978 // value.
1979 ImmutableCallSite ICS(&getAnchorValue());
1980 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
1981 if (getArgNo() == (int)i)
1982 continue;
1983 const Value *ArgOp = ICS.getArgOperand(i);
1984 if (!ArgOp->getType()->isPointerTy())
1985 continue;
1986
Hideto Ueno30d86f12019-09-17 06:53:27 +00001987 if (const Function *F = getAnchorScope()) {
1988 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
1989 LLVM_DEBUG(dbgs()
1990 << "[Attributor][NoAliasCSArg] Check alias between "
1991 "callsite arguments "
1992 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
1993 << getAssociatedValue() << " " << *ArgOp << "\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001994
Hideto Ueno30d86f12019-09-17 06:53:27 +00001995 if (AAR->isNoAlias(&getAssociatedValue(), ArgOp))
1996 continue;
1997 }
1998 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001999 return indicatePessimisticFixpoint();
2000 }
2001
2002 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002003 }
2004
2005 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002006 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002007};
2008
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002009/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002010struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002011 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002012
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002013 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002014 virtual ChangeStatus updateImpl(Attributor &A) override {
2015
2016 auto CheckReturnValue = [&](Value &RV) -> bool {
2017 if (Constant *C = dyn_cast<Constant>(&RV))
2018 if (C->isNullValue() || isa<UndefValue>(C))
2019 return true;
2020
2021 /// For now, we can only deduce noalias if we have call sites.
2022 /// FIXME: add more support.
2023 ImmutableCallSite ICS(&RV);
2024 if (!ICS)
2025 return false;
2026
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002027 const IRPosition &RVPos = IRPosition::value(RV);
2028 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002029 if (!NoAliasAA.isAssumedNoAlias())
2030 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002031
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002032 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2033 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002034 };
2035
2036 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2037 return indicatePessimisticFixpoint();
2038
2039 return ChangeStatus::UNCHANGED;
2040 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002041
2042 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002043 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002044};
2045
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002046/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002047struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2048 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2049
2050 /// See AbstractAttribute::initialize(...).
2051 void initialize(Attributor &A) override {
2052 AANoAliasImpl::initialize(A);
2053 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002054 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002055 indicatePessimisticFixpoint();
2056 }
2057
2058 /// See AbstractAttribute::updateImpl(...).
2059 ChangeStatus updateImpl(Attributor &A) override {
2060 // TODO: Once we have call site specific value information we can provide
2061 // call site specific liveness information and then it makes
2062 // sense to specialize attributes for call sites arguments instead of
2063 // redirecting requests to the callee argument.
2064 Function *F = getAssociatedFunction();
2065 const IRPosition &FnPos = IRPosition::returned(*F);
2066 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2067 return clampStateAndIndicateChange(
2068 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2069 }
2070
2071 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002072 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002073};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002074
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002075/// -------------------AAIsDead Function Attribute-----------------------
2076
Johannes Doerfert344d0382019-08-07 22:34:26 +00002077struct AAIsDeadImpl : public AAIsDead {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002078 AAIsDeadImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002079
Johannes Doerfertece81902019-08-12 22:05:53 +00002080 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002081 const Function *F = getAssociatedFunction();
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002082 if (F && !F->isDeclaration())
2083 exploreFromEntry(A, F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002084 }
2085
2086 void exploreFromEntry(Attributor &A, const Function *F) {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002087 ToBeExploredPaths.insert(&(F->getEntryBlock().front()));
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002088
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002089 for (size_t i = 0; i < ToBeExploredPaths.size(); ++i)
Johannes Doerfert4361da22019-08-04 18:38:53 +00002090 if (const Instruction *NextNoReturnI =
2091 findNextNoReturn(A, ToBeExploredPaths[i]))
2092 NoReturnCalls.insert(NextNoReturnI);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00002093
2094 // Mark the block live after we looked for no-return instructions.
2095 assumeLive(A, F->getEntryBlock());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002096 }
2097
Johannes Doerfert4361da22019-08-04 18:38:53 +00002098 /// Find the next assumed noreturn instruction in the block of \p I starting
2099 /// from, thus including, \p I.
2100 ///
2101 /// The caller is responsible to monitor the ToBeExploredPaths set as new
2102 /// instructions discovered in other basic block will be placed in there.
2103 ///
2104 /// \returns The next assumed noreturn instructions in the block of \p I
2105 /// starting from, thus including, \p I.
2106 const Instruction *findNextNoReturn(Attributor &A, const Instruction *I);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002107
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002108 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002109 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002110 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002111 std::to_string(getAssociatedFunction()->size()) + "][#NRI " +
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002112 std::to_string(NoReturnCalls.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002113 }
2114
2115 /// See AbstractAttribute::manifest(...).
2116 ChangeStatus manifest(Attributor &A) override {
2117 assert(getState().isValidState() &&
2118 "Attempted to manifest an invalid state!");
2119
2120 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002121 Function &F = *getAssociatedFunction();
2122
2123 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002124 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002125 return ChangeStatus::CHANGED;
2126 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002127
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002128 // Flag to determine if we can change an invoke to a call assuming the
2129 // callee is nounwind. This is not possible if the personality of the
2130 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002131 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002132
Johannes Doerfert4361da22019-08-04 18:38:53 +00002133 for (const Instruction *NRC : NoReturnCalls) {
2134 Instruction *I = const_cast<Instruction *>(NRC);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002135 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002136 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00002137 // TODO: mark stuff before unreachable instructions as dead.
2138 if (isa_and_nonnull<UnreachableInst>(SplitPos))
2139 continue;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002140
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002141 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002142 // If we keep the invoke the split position is at the beginning of the
2143 // normal desitination block (it invokes a noreturn function after all).
2144 BasicBlock *NormalDestBB = II->getNormalDest();
2145 SplitPos = &NormalDestBB->front();
2146
Johannes Doerfert4361da22019-08-04 18:38:53 +00002147 /// Invoke is replaced with a call and unreachable is placed after it if
2148 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
2149 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002150 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00002151 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002152 const IRPosition &IPos = IRPosition::callsite_function(*II);
2153 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2154 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00002155 LLVM_DEBUG(dbgs()
2156 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002157 // We do not need an invoke (II) but instead want a call followed
2158 // by an unreachable. However, we do not remove II as other
2159 // abstract attributes might have it cached as part of their
2160 // results. Given that we modify the CFG anyway, we simply keep II
2161 // around but in a new dead block. To avoid II being live through
2162 // a different edge we have to ensure the block we place it in is
2163 // only reached from the current block of II and then not reached
2164 // at all when we insert the unreachable.
2165 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
2166 CallInst *CI = createCallMatchingInvoke(II);
2167 CI->insertBefore(II);
2168 CI->takeName(II);
2169 II->replaceAllUsesWith(CI);
2170 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002171 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002172 }
2173 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002174
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002175 if (SplitPos == &NormalDestBB->front()) {
2176 // If this is an invoke of a noreturn function the edge to the normal
2177 // destination block is dead but not necessarily the block itself.
2178 // TODO: We need to move to an edge based system during deduction and
2179 // also manifest.
2180 assert(!NormalDestBB->isLandingPad() &&
2181 "Expected the normal destination not to be a landingpad!");
2182 BasicBlock *SplitBB =
2183 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2184 // The split block is live even if it contains only an unreachable
2185 // instruction at the end.
2186 assumeLive(A, *SplitBB);
2187 SplitPos = SplitBB->getTerminator();
2188 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002189 }
2190
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002191 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002192 SplitBlock(BB, SplitPos);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002193 changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
2194 HasChanged = ChangeStatus::CHANGED;
2195 }
2196
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002197 for (BasicBlock &BB : F)
2198 if (!AssumedLiveBlocks.count(&BB))
2199 A.deleteAfterManifest(BB);
2200
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002201 return HasChanged;
2202 }
2203
2204 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002205 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002206
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002207 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002208 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002209 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002210 "BB must be in the same anchor scope function.");
2211
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002212 if (!getAssumed())
2213 return false;
2214 return !AssumedLiveBlocks.count(BB);
2215 }
2216
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002217 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002218 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002219 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002220 }
2221
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002222 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002223 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002224 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002225 "Instruction must be in the same anchor scope function.");
2226
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002227 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002228 return false;
2229
2230 // If it is not in AssumedLiveBlocks then it for sure dead.
2231 // Otherwise, it can still be after noreturn call in a live block.
2232 if (!AssumedLiveBlocks.count(I->getParent()))
2233 return true;
2234
2235 // If it is not after a noreturn call, than it is live.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002236 return isAfterNoReturn(I);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002237 }
2238
2239 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002240 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002241 return getKnown() && isAssumedDead(I);
2242 }
2243
2244 /// Check if instruction is after noreturn call, in other words, assumed dead.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002245 bool isAfterNoReturn(const Instruction *I) const;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002246
Johannes Doerfert924d2132019-08-05 21:34:45 +00002247 /// Determine if \p F might catch asynchronous exceptions.
2248 static bool mayCatchAsynchronousExceptions(const Function &F) {
2249 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2250 }
2251
Johannes Doerfert2f622062019-09-04 16:35:20 +00002252 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2253 /// that internal function called from \p BB should now be looked at.
2254 void assumeLive(Attributor &A, const BasicBlock &BB) {
2255 if (!AssumedLiveBlocks.insert(&BB).second)
2256 return;
2257
2258 // We assume that all of BB is (probably) live now and if there are calls to
2259 // internal functions we will assume that those are now live as well. This
2260 // is a performance optimization for blocks with calls to a lot of internal
2261 // functions. It can however cause dead functions to be treated as live.
2262 for (const Instruction &I : BB)
2263 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2264 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00002265 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00002266 A.markLiveInternalFunction(*F);
2267 }
2268
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002269 /// Collection of to be explored paths.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002270 SmallSetVector<const Instruction *, 8> ToBeExploredPaths;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002271
2272 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002273 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002274
2275 /// Collection of calls with noreturn attribute, assumed or knwon.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002276 SmallSetVector<const Instruction *, 4> NoReturnCalls;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002277};
2278
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002279struct AAIsDeadFunction final : public AAIsDeadImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002280 AAIsDeadFunction(const IRPosition &IRP) : AAIsDeadImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002281
2282 /// See AbstractAttribute::trackStatistics()
2283 void trackStatistics() const override {
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002284 STATS_DECL(PartiallyDeadBlocks, Function,
2285 "Number of basic blocks classified as partially dead");
2286 BUILD_STAT_NAME(PartiallyDeadBlocks, Function) += NoReturnCalls.size();
2287 }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002288};
2289
2290bool AAIsDeadImpl::isAfterNoReturn(const Instruction *I) const {
Johannes Doerfert4361da22019-08-04 18:38:53 +00002291 const Instruction *PrevI = I->getPrevNode();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002292 while (PrevI) {
2293 if (NoReturnCalls.count(PrevI))
2294 return true;
2295 PrevI = PrevI->getPrevNode();
2296 }
2297 return false;
2298}
2299
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002300const Instruction *AAIsDeadImpl::findNextNoReturn(Attributor &A,
2301 const Instruction *I) {
Johannes Doerfert4361da22019-08-04 18:38:53 +00002302 const BasicBlock *BB = I->getParent();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002303 const Function &F = *BB->getParent();
2304
2305 // Flag to determine if we can change an invoke to a call assuming the callee
2306 // is nounwind. This is not possible if the personality of the function allows
2307 // to catch asynchronous exceptions.
2308 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002309
2310 // TODO: We should have a function that determines if an "edge" is dead.
2311 // Edges could be from an instruction to the next or from a terminator
2312 // to the successor. For now, we need to special case the unwind block
2313 // of InvokeInst below.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002314
2315 while (I) {
2316 ImmutableCallSite ICS(I);
2317
2318 if (ICS) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002319 const IRPosition &IPos = IRPosition::callsite_function(ICS);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002320 // Regarless of the no-return property of an invoke instruction we only
2321 // learn that the regular successor is not reachable through this
2322 // instruction but the unwind block might still be.
2323 if (auto *Invoke = dyn_cast<InvokeInst>(I)) {
2324 // Use nounwind to justify the unwind block is dead as well.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002325 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2326 if (!Invoke2CallAllowed || !AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002327 assumeLive(A, *Invoke->getUnwindDest());
Johannes Doerfert4361da22019-08-04 18:38:53 +00002328 ToBeExploredPaths.insert(&Invoke->getUnwindDest()->front());
2329 }
2330 }
2331
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002332 const auto &NoReturnAA = A.getAAFor<AANoReturn>(*this, IPos);
2333 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert4361da22019-08-04 18:38:53 +00002334 return I;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002335 }
2336
2337 I = I->getNextNode();
2338 }
2339
2340 // get new paths (reachable blocks).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002341 for (const BasicBlock *SuccBB : successors(BB)) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002342 assumeLive(A, *SuccBB);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002343 ToBeExploredPaths.insert(&SuccBB->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002344 }
2345
Johannes Doerfert4361da22019-08-04 18:38:53 +00002346 // No noreturn instruction found.
2347 return nullptr;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002348}
2349
Johannes Doerfertece81902019-08-12 22:05:53 +00002350ChangeStatus AAIsDeadImpl::updateImpl(Attributor &A) {
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002351 ChangeStatus Status = ChangeStatus::UNCHANGED;
2352
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002353 // Temporary collection to iterate over existing noreturn instructions. This
2354 // will alow easier modification of NoReturnCalls collection
Johannes Doerfert4361da22019-08-04 18:38:53 +00002355 SmallVector<const Instruction *, 8> NoReturnChanged;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002356
Johannes Doerfert4361da22019-08-04 18:38:53 +00002357 for (const Instruction *I : NoReturnCalls)
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002358 NoReturnChanged.push_back(I);
2359
Johannes Doerfert4361da22019-08-04 18:38:53 +00002360 for (const Instruction *I : NoReturnChanged) {
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002361 size_t Size = ToBeExploredPaths.size();
2362
Johannes Doerfert4361da22019-08-04 18:38:53 +00002363 const Instruction *NextNoReturnI = findNextNoReturn(A, I);
2364 if (NextNoReturnI != I) {
2365 Status = ChangeStatus::CHANGED;
2366 NoReturnCalls.remove(I);
2367 if (NextNoReturnI)
2368 NoReturnCalls.insert(NextNoReturnI);
2369 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002370
Johannes Doerfert4361da22019-08-04 18:38:53 +00002371 // Explore new paths.
2372 while (Size != ToBeExploredPaths.size()) {
2373 Status = ChangeStatus::CHANGED;
2374 if (const Instruction *NextNoReturnI =
2375 findNextNoReturn(A, ToBeExploredPaths[Size++]))
2376 NoReturnCalls.insert(NextNoReturnI);
2377 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002378 }
2379
Johannes Doerfertdef99282019-08-14 21:29:37 +00002380 LLVM_DEBUG(dbgs() << "[AAIsDead] AssumedLiveBlocks: "
2381 << AssumedLiveBlocks.size() << " Total number of blocks: "
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002382 << getAssociatedFunction()->size() << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002383
Johannes Doerfertd6207812019-08-07 22:32:38 +00002384 // If we know everything is live there is no need to query for liveness.
2385 if (NoReturnCalls.empty() &&
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002386 getAssociatedFunction()->size() == AssumedLiveBlocks.size()) {
Johannes Doerfertd6207812019-08-07 22:32:38 +00002387 // Indicating a pessimistic fixpoint will cause the state to be "invalid"
2388 // which will cause the Attributor to not return the AAIsDead on request,
2389 // which will prevent us from querying isAssumedDead().
2390 indicatePessimisticFixpoint();
2391 assert(!isValidState() && "Expected an invalid state!");
Johannes Doerfert62a9c1d2019-08-29 01:26:58 +00002392 Status = ChangeStatus::CHANGED;
Johannes Doerfertd6207812019-08-07 22:32:38 +00002393 }
2394
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002395 return Status;
2396}
2397
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002398/// Liveness information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002399struct AAIsDeadCallSite final : AAIsDeadImpl {
2400 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadImpl(IRP) {}
2401
2402 /// See AbstractAttribute::initialize(...).
2403 void initialize(Attributor &A) override {
2404 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002405 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002406 // sense to specialize attributes for call sites instead of
2407 // redirecting requests to the callee.
2408 llvm_unreachable("Abstract attributes for liveness are not "
2409 "supported for call sites yet!");
2410 }
2411
2412 /// See AbstractAttribute::updateImpl(...).
2413 ChangeStatus updateImpl(Attributor &A) override {
2414 return indicatePessimisticFixpoint();
2415 }
2416
2417 /// See AbstractAttribute::trackStatistics()
2418 void trackStatistics() const override {}
2419};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002420
Hideto Ueno19c07af2019-07-23 08:16:17 +00002421/// -------------------- Dereferenceable Argument Attribute --------------------
2422
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002423template <>
2424ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
2425 const DerefState &R) {
2426 ChangeStatus CS0 = clampStateAndIndicateChange<IntegerState>(
2427 S.DerefBytesState, R.DerefBytesState);
2428 ChangeStatus CS1 =
2429 clampStateAndIndicateChange<IntegerState>(S.GlobalState, R.GlobalState);
2430 return CS0 | CS1;
2431}
2432
Hideto Ueno70576ca2019-08-22 14:18:29 +00002433struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002434 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00002435 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002436
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002437 void initialize(Attributor &A) override {
2438 SmallVector<Attribute, 4> Attrs;
2439 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
2440 Attrs);
2441 for (const Attribute &Attr : Attrs)
2442 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
2443
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002444 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002445
2446 const IRPosition &IRP = this->getIRPosition();
2447 bool IsFnInterface = IRP.isFnInterfaceKind();
2448 const Function *FnScope = IRP.getAnchorScope();
2449 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
2450 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002451 }
2452
Hideto Ueno19c07af2019-07-23 08:16:17 +00002453 /// See AbstractAttribute::getState()
2454 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00002455 StateType &getState() override { return *this; }
2456 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002457 /// }
2458
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002459 /// See AAFromMustBeExecutedContext
2460 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
2461 bool IsNonNull = false;
2462 bool TrackUse = false;
2463 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
2464 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
2465 takeKnownDerefBytesMaximum(DerefBytes);
2466 return TrackUse;
2467 }
2468
Johannes Doerferteccdf082019-08-05 23:35:12 +00002469 void getDeducedAttributes(LLVMContext &Ctx,
2470 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002471 // TODO: Add *_globally support
2472 if (isAssumedNonNull())
2473 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
2474 Ctx, getAssumedDereferenceableBytes()));
2475 else
2476 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
2477 Ctx, getAssumedDereferenceableBytes()));
2478 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002479
2480 /// See AbstractAttribute::getAsStr().
2481 const std::string getAsStr() const override {
2482 if (!getAssumedDereferenceableBytes())
2483 return "unknown-dereferenceable";
2484 return std::string("dereferenceable") +
2485 (isAssumedNonNull() ? "" : "_or_null") +
2486 (isAssumedGlobal() ? "_globally" : "") + "<" +
2487 std::to_string(getKnownDereferenceableBytes()) + "-" +
2488 std::to_string(getAssumedDereferenceableBytes()) + ">";
2489 }
2490};
2491
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002492/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002493struct AADereferenceableFloating
2494 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
2495 using Base =
2496 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
2497 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00002498
2499 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002500 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002501 ChangeStatus Change = Base::updateImpl(A);
2502
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002503 const DataLayout &DL = A.getDataLayout();
2504
2505 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
2506 unsigned IdxWidth =
2507 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
2508 APInt Offset(IdxWidth, 0);
2509 const Value *Base =
2510 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
2511
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002512 const auto &AA =
2513 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002514 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002515 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002516 // Use IR information if we did not strip anything.
2517 // TODO: track globally.
2518 bool CanBeNull;
2519 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
2520 T.GlobalState.indicatePessimisticFixpoint();
2521 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002522 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002523 DerefBytes = DS.DerefBytesState.getAssumed();
2524 T.GlobalState &= DS.GlobalState;
2525 }
2526
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002527 // For now we do not try to "increase" dereferenceability due to negative
2528 // indices as we first have to come up with code to deal with loops and
2529 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00002530 int64_t OffsetSExt = Offset.getSExtValue();
2531 if (OffsetSExt < 0)
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002532 Offset = 0;
2533
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002534 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00002535 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002536
Johannes Doerfert785fad32019-08-23 17:29:23 +00002537 if (this == &AA) {
2538 if (!Stripped) {
2539 // If nothing was stripped IR information is all we got.
2540 T.takeKnownDerefBytesMaximum(
2541 std::max(int64_t(0), DerefBytes - OffsetSExt));
2542 T.indicatePessimisticFixpoint();
2543 } else if (OffsetSExt > 0) {
2544 // If something was stripped but there is circular reasoning we look
2545 // for the offset. If it is positive we basically decrease the
2546 // dereferenceable bytes in a circluar loop now, which will simply
2547 // drive them down to the known value in a very slow way which we
2548 // can accelerate.
2549 T.indicatePessimisticFixpoint();
2550 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002551 }
2552
2553 return T.isValidState();
2554 };
2555
2556 DerefState T;
2557 if (!genericValueTraversal<AADereferenceable, DerefState>(
2558 A, getIRPosition(), *this, T, VisitValueCB))
2559 return indicatePessimisticFixpoint();
2560
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002561 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002562 }
2563
2564 /// See AbstractAttribute::trackStatistics()
2565 void trackStatistics() const override {
2566 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
2567 }
2568};
2569
2570/// Dereferenceable attribute for a return value.
2571struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002572 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2573 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002574 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002575 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2576 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002577
2578 /// See AbstractAttribute::trackStatistics()
2579 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002580 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002581 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002582};
2583
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002584/// Dereferenceable attribute for an argument
2585struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002586 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2587 AADereferenceable, AADereferenceableImpl, DerefState> {
2588 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2589 AADereferenceable, AADereferenceableImpl, DerefState>;
2590 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002591
2592 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002593 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00002594 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
2595 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002596};
2597
Hideto Ueno19c07af2019-07-23 08:16:17 +00002598/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002599struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002600 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002601 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002602
2603 /// See AbstractAttribute::trackStatistics()
2604 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002605 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002606 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002607};
2608
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002609/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002610struct AADereferenceableCallSiteReturned final
2611 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2612 AADereferenceable, AADereferenceableImpl> {
2613 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2614 AADereferenceable, AADereferenceableImpl>;
2615 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002616
2617 /// See AbstractAttribute::initialize(...).
2618 void initialize(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002619 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002620 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002621 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002622 indicatePessimisticFixpoint();
2623 }
2624
2625 /// See AbstractAttribute::updateImpl(...).
2626 ChangeStatus updateImpl(Attributor &A) override {
2627 // TODO: Once we have call site specific value information we can provide
2628 // call site specific liveness information and then it makes
2629 // sense to specialize attributes for call sites arguments instead of
2630 // redirecting requests to the callee argument.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002631
2632 ChangeStatus Change = Base::updateImpl(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002633 Function *F = getAssociatedFunction();
2634 const IRPosition &FnPos = IRPosition::returned(*F);
2635 auto &FnAA = A.getAAFor<AADereferenceable>(*this, FnPos);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002636 return Change |
2637 clampStateAndIndicateChange(
2638 getState(), static_cast<const DerefState &>(FnAA.getState()));
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002639 }
2640
2641 /// See AbstractAttribute::trackStatistics()
2642 void trackStatistics() const override {
2643 STATS_DECLTRACK_CS_ATTR(dereferenceable);
2644 }
2645};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002646
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002647// ------------------------ Align Argument Attribute ------------------------
2648
Johannes Doerfert344d0382019-08-07 22:34:26 +00002649struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002650 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002651
2652 // Max alignemnt value allowed in IR
2653 static const unsigned MAX_ALIGN = 1U << 29;
2654
Johannes Doerfert234eda52019-08-16 19:51:23 +00002655 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002656 void initialize(Attributor &A) override {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002657 takeAssumedMinimum(MAX_ALIGN);
2658
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002659 SmallVector<Attribute, 4> Attrs;
2660 getAttrs({Attribute::Alignment}, Attrs);
2661 for (const Attribute &Attr : Attrs)
2662 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002663
2664 if (getIRPosition().isFnInterfaceKind() &&
2665 (!getAssociatedFunction() ||
2666 !getAssociatedFunction()->hasExactDefinition()))
2667 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002668 }
2669
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002670 /// See AbstractAttribute::manifest(...).
2671 ChangeStatus manifest(Attributor &A) override {
2672 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2673
2674 // Check for users that allow alignment annotations.
2675 Value &AnchorVal = getIRPosition().getAnchorValue();
2676 for (const Use &U : AnchorVal.uses()) {
2677 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
2678 if (SI->getPointerOperand() == &AnchorVal)
2679 if (SI->getAlignment() < getAssumedAlign()) {
2680 STATS_DECLTRACK(AAAlign, Store,
2681 "Number of times alignemnt added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00002682 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002683 Changed = ChangeStatus::CHANGED;
2684 }
2685 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
2686 if (LI->getPointerOperand() == &AnchorVal)
2687 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00002688 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002689 STATS_DECLTRACK(AAAlign, Load,
2690 "Number of times alignemnt added to a load");
2691 Changed = ChangeStatus::CHANGED;
2692 }
2693 }
2694 }
2695
Johannes Doerfert81df4522019-08-30 15:22:28 +00002696 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002697 }
2698
Johannes Doerfert81df4522019-08-30 15:22:28 +00002699 // TODO: Provide a helper to determine the implied ABI alignment and check in
2700 // the existing manifest method and a new one for AAAlignImpl that value
2701 // to avoid making the alignment explicit if it did not improve.
2702
2703 /// See AbstractAttribute::getDeducedAttributes
2704 virtual void
2705 getDeducedAttributes(LLVMContext &Ctx,
2706 SmallVectorImpl<Attribute> &Attrs) const override {
2707 if (getAssumedAlign() > 1)
2708 Attrs.emplace_back(Attribute::getWithAlignment(Ctx, getAssumedAlign()));
2709 }
2710
2711 /// See AbstractAttribute::getAsStr().
2712 const std::string getAsStr() const override {
2713 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
2714 "-" + std::to_string(getAssumedAlign()) + ">")
2715 : "unknown-align";
2716 }
2717};
2718
2719/// Align attribute for a floating value.
2720struct AAAlignFloating : AAAlignImpl {
2721 AAAlignFloating(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2722
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002723 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00002724 ChangeStatus updateImpl(Attributor &A) override {
2725 const DataLayout &DL = A.getDataLayout();
2726
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002727 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
2728 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002729 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
2730 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002731 // Use only IR information if we did not strip anything.
2732 T.takeKnownMaximum(V.getPointerAlignment(DL));
2733 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002734 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002735 // Use abstract attribute information.
2736 const AAAlign::StateType &DS =
2737 static_cast<const AAAlign::StateType &>(AA.getState());
2738 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00002739 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002740 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002741 };
2742
2743 StateType T;
2744 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
2745 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002746 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002747
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00002748 // TODO: If we know we visited all incoming values, thus no are assumed
2749 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00002750 return clampStateAndIndicateChange(getState(), T);
2751 }
2752
2753 /// See AbstractAttribute::trackStatistics()
2754 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
2755};
2756
2757/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002758struct AAAlignReturned final
2759 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002760 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002761 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002762
2763 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002764 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002765};
2766
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002767/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002768struct AAAlignArgument final
2769 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002770 AAAlignArgument(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002771 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002772
2773 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00002774 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002775};
2776
Johannes Doerfert234eda52019-08-16 19:51:23 +00002777struct AAAlignCallSiteArgument final : AAAlignFloating {
2778 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002779
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002780 /// See AbstractAttribute::manifest(...).
2781 ChangeStatus manifest(Attributor &A) override {
2782 return AAAlignImpl::manifest(A);
2783 }
2784
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002785 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002786 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002787};
2788
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002789/// Align attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002790struct AAAlignCallSiteReturned final : AAAlignImpl {
2791 AAAlignCallSiteReturned(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2792
2793 /// See AbstractAttribute::initialize(...).
2794 void initialize(Attributor &A) override {
2795 AAAlignImpl::initialize(A);
2796 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002797 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002798 indicatePessimisticFixpoint();
2799 }
2800
2801 /// See AbstractAttribute::updateImpl(...).
2802 ChangeStatus updateImpl(Attributor &A) override {
2803 // TODO: Once we have call site specific value information we can provide
2804 // call site specific liveness information and then it makes
2805 // sense to specialize attributes for call sites arguments instead of
2806 // redirecting requests to the callee argument.
2807 Function *F = getAssociatedFunction();
2808 const IRPosition &FnPos = IRPosition::returned(*F);
2809 auto &FnAA = A.getAAFor<AAAlign>(*this, FnPos);
2810 return clampStateAndIndicateChange(
2811 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
2812 }
2813
2814 /// See AbstractAttribute::trackStatistics()
2815 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
2816};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002817
Johannes Doerferte83f3032019-08-05 23:22:05 +00002818/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00002819struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002820 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00002821
Johannes Doerferte83f3032019-08-05 23:22:05 +00002822 /// See AbstractAttribute::getAsStr().
2823 const std::string getAsStr() const override {
2824 return getAssumed() ? "noreturn" : "may-return";
2825 }
2826
Johannes Doerferte83f3032019-08-05 23:22:05 +00002827 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00002828 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00002829 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002830 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00002831 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00002832 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00002833 return ChangeStatus::UNCHANGED;
2834 }
2835};
2836
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002837struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002838 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002839
2840 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002841 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002842};
2843
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002844/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002845struct AANoReturnCallSite final : AANoReturnImpl {
2846 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
2847
2848 /// See AbstractAttribute::initialize(...).
2849 void initialize(Attributor &A) override {
2850 AANoReturnImpl::initialize(A);
2851 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002852 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002853 indicatePessimisticFixpoint();
2854 }
2855
2856 /// See AbstractAttribute::updateImpl(...).
2857 ChangeStatus updateImpl(Attributor &A) override {
2858 // TODO: Once we have call site specific value information we can provide
2859 // call site specific liveness information and then it makes
2860 // sense to specialize attributes for call sites arguments instead of
2861 // redirecting requests to the callee argument.
2862 Function *F = getAssociatedFunction();
2863 const IRPosition &FnPos = IRPosition::function(*F);
2864 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
2865 return clampStateAndIndicateChange(
2866 getState(),
2867 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
2868 }
2869
2870 /// See AbstractAttribute::trackStatistics()
2871 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
2872};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002873
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002874/// ----------------------- Variable Capturing ---------------------------------
2875
2876/// A class to hold the state of for no-capture attributes.
2877struct AANoCaptureImpl : public AANoCapture {
2878 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
2879
2880 /// See AbstractAttribute::initialize(...).
2881 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002882 AANoCapture::initialize(A);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002883
2884 const IRPosition &IRP = getIRPosition();
2885 const Function *F =
2886 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
2887
2888 // Check what state the associated function can actually capture.
2889 if (F)
2890 determineFunctionCaptureCapabilities(*F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002891 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002892 indicatePessimisticFixpoint();
2893 }
2894
2895 /// See AbstractAttribute::updateImpl(...).
2896 ChangeStatus updateImpl(Attributor &A) override;
2897
2898 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
2899 virtual void
2900 getDeducedAttributes(LLVMContext &Ctx,
2901 SmallVectorImpl<Attribute> &Attrs) const override {
2902 if (!isAssumedNoCaptureMaybeReturned())
2903 return;
2904
Hideto Ueno37367642019-09-11 06:52:11 +00002905 if (getArgNo() >= 0) {
2906 if (isAssumedNoCapture())
2907 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
2908 else if (ManifestInternal)
2909 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
2910 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002911 }
2912
2913 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
2914 /// depending on the ability of the function associated with \p IRP to capture
2915 /// state in memory and through "returning/throwing", respectively.
2916 static void determineFunctionCaptureCapabilities(const Function &F,
2917 IntegerState &State) {
2918 // TODO: Once we have memory behavior attributes we should use them here.
2919
2920 // If we know we cannot communicate or write to memory, we do not care about
2921 // ptr2int anymore.
2922 if (F.onlyReadsMemory() && F.doesNotThrow() &&
2923 F.getReturnType()->isVoidTy()) {
2924 State.addKnownBits(NO_CAPTURE);
2925 return;
2926 }
2927
2928 // A function cannot capture state in memory if it only reads memory, it can
2929 // however return/throw state and the state might be influenced by the
2930 // pointer value, e.g., loading from a returned pointer might reveal a bit.
2931 if (F.onlyReadsMemory())
2932 State.addKnownBits(NOT_CAPTURED_IN_MEM);
2933
2934 // A function cannot communicate state back if it does not through
2935 // exceptions and doesn not return values.
2936 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
2937 State.addKnownBits(NOT_CAPTURED_IN_RET);
2938 }
2939
2940 /// See AbstractState::getAsStr().
2941 const std::string getAsStr() const override {
2942 if (isKnownNoCapture())
2943 return "known not-captured";
2944 if (isAssumedNoCapture())
2945 return "assumed not-captured";
2946 if (isKnownNoCaptureMaybeReturned())
2947 return "known not-captured-maybe-returned";
2948 if (isAssumedNoCaptureMaybeReturned())
2949 return "assumed not-captured-maybe-returned";
2950 return "assumed-captured";
2951 }
2952};
2953
2954/// Attributor-aware capture tracker.
2955struct AACaptureUseTracker final : public CaptureTracker {
2956
2957 /// Create a capture tracker that can lookup in-flight abstract attributes
2958 /// through the Attributor \p A.
2959 ///
2960 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
2961 /// search is stopped. If a use leads to a return instruction,
2962 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
2963 /// If a use leads to a ptr2int which may capture the value,
2964 /// \p CapturedInInteger is set. If a use is found that is currently assumed
2965 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
2966 /// set. All values in \p PotentialCopies are later tracked as well. For every
2967 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
2968 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
2969 /// conservatively set to true.
2970 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
2971 const AAIsDead &IsDeadAA, IntegerState &State,
2972 SmallVectorImpl<const Value *> &PotentialCopies,
2973 unsigned &RemainingUsesToExplore)
2974 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
2975 PotentialCopies(PotentialCopies),
2976 RemainingUsesToExplore(RemainingUsesToExplore) {}
2977
2978 /// Determine if \p V maybe captured. *Also updates the state!*
2979 bool valueMayBeCaptured(const Value *V) {
2980 if (V->getType()->isPointerTy()) {
2981 PointerMayBeCaptured(V, this);
2982 } else {
2983 State.indicatePessimisticFixpoint();
2984 }
2985 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
2986 }
2987
2988 /// See CaptureTracker::tooManyUses().
2989 void tooManyUses() override {
2990 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
2991 }
2992
2993 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
2994 if (CaptureTracker::isDereferenceableOrNull(O, DL))
2995 return true;
2996 const auto &DerefAA =
2997 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
2998 return DerefAA.getAssumedDereferenceableBytes();
2999 }
3000
3001 /// See CaptureTracker::captured(...).
3002 bool captured(const Use *U) override {
3003 Instruction *UInst = cast<Instruction>(U->getUser());
3004 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3005 << "\n");
3006
3007 // Because we may reuse the tracker multiple times we keep track of the
3008 // number of explored uses ourselves as well.
3009 if (RemainingUsesToExplore-- == 0) {
3010 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3011 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3012 /* Return */ true);
3013 }
3014
3015 // Deal with ptr2int by following uses.
3016 if (isa<PtrToIntInst>(UInst)) {
3017 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3018 return valueMayBeCaptured(UInst);
3019 }
3020
3021 // Explicitly catch return instructions.
3022 if (isa<ReturnInst>(UInst))
3023 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3024 /* Return */ true);
3025
3026 // For now we only use special logic for call sites. However, the tracker
3027 // itself knows about a lot of other non-capturing cases already.
3028 CallSite CS(UInst);
3029 if (!CS || !CS.isArgOperand(U))
3030 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3031 /* Return */ true);
3032
3033 unsigned ArgNo = CS.getArgumentNo(U);
3034 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3035 // If we have a abstract no-capture attribute for the argument we can use
3036 // it to justify a non-capture attribute here. This allows recursion!
3037 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3038 if (ArgNoCaptureAA.isAssumedNoCapture())
3039 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3040 /* Return */ false);
3041 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3042 addPotentialCopy(CS);
3043 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3044 /* Return */ false);
3045 }
3046
3047 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3048 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3049 /* Return */ true);
3050 }
3051
3052 /// Register \p CS as potential copy of the value we are checking.
3053 void addPotentialCopy(CallSite CS) {
3054 PotentialCopies.push_back(CS.getInstruction());
3055 }
3056
3057 /// See CaptureTracker::shouldExplore(...).
3058 bool shouldExplore(const Use *U) override {
3059 // Check liveness.
3060 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3061 }
3062
3063 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3064 /// \p CapturedInRet, then return the appropriate value for use in the
3065 /// CaptureTracker::captured() interface.
3066 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3067 bool CapturedInRet) {
3068 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3069 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3070 if (CapturedInMem)
3071 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3072 if (CapturedInInt)
3073 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3074 if (CapturedInRet)
3075 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3076 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3077 }
3078
3079private:
3080 /// The attributor providing in-flight abstract attributes.
3081 Attributor &A;
3082
3083 /// The abstract attribute currently updated.
3084 AANoCapture &NoCaptureAA;
3085
3086 /// The abstract liveness state.
3087 const AAIsDead &IsDeadAA;
3088
3089 /// The state currently updated.
3090 IntegerState &State;
3091
3092 /// Set of potential copies of the tracked value.
3093 SmallVectorImpl<const Value *> &PotentialCopies;
3094
3095 /// Global counter to limit the number of explored uses.
3096 unsigned &RemainingUsesToExplore;
3097};
3098
3099ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
3100 const IRPosition &IRP = getIRPosition();
3101 const Value *V =
3102 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
3103 if (!V)
3104 return indicatePessimisticFixpoint();
3105
3106 const Function *F =
3107 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
3108 assert(F && "Expected a function!");
3109 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(*F));
3110
3111 AANoCapture::StateType T;
3112 // TODO: Once we have memory behavior attributes we should use them here
3113 // similar to the reasoning in
3114 // AANoCaptureImpl::determineFunctionCaptureCapabilities(...).
3115
3116 // TODO: Use the AAReturnedValues to learn if the argument can return or
3117 // not.
3118
3119 // Use the CaptureTracker interface and logic with the specialized tracker,
3120 // defined in AACaptureUseTracker, that can look at in-flight abstract
3121 // attributes and directly updates the assumed state.
3122 SmallVector<const Value *, 4> PotentialCopies;
3123 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
3124 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
3125 RemainingUsesToExplore);
3126
3127 // Check all potential copies of the associated value until we can assume
3128 // none will be captured or we have to assume at least one might be.
3129 unsigned Idx = 0;
3130 PotentialCopies.push_back(V);
3131 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
3132 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
3133
3134 AAAlign::StateType &S = getState();
3135 auto Assumed = S.getAssumed();
3136 S.intersectAssumedBits(T.getAssumed());
3137 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3138 : ChangeStatus::CHANGED;
3139}
3140
3141/// NoCapture attribute for function arguments.
3142struct AANoCaptureArgument final : AANoCaptureImpl {
3143 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3144
3145 /// See AbstractAttribute::trackStatistics()
3146 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
3147};
3148
3149/// NoCapture attribute for call site arguments.
3150struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
3151 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3152
3153 /// See AbstractAttribute::updateImpl(...).
3154 ChangeStatus updateImpl(Attributor &A) override {
3155 // TODO: Once we have call site specific value information we can provide
3156 // call site specific liveness information and then it makes
3157 // sense to specialize attributes for call sites arguments instead of
3158 // redirecting requests to the callee argument.
3159 Argument *Arg = getAssociatedArgument();
3160 if (!Arg)
3161 return indicatePessimisticFixpoint();
3162 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3163 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
3164 return clampStateAndIndicateChange(
3165 getState(),
3166 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3167 }
3168
3169 /// See AbstractAttribute::trackStatistics()
3170 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
3171};
3172
3173/// NoCapture attribute for floating values.
3174struct AANoCaptureFloating final : AANoCaptureImpl {
3175 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3176
3177 /// See AbstractAttribute::trackStatistics()
3178 void trackStatistics() const override {
3179 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
3180 }
3181};
3182
3183/// NoCapture attribute for function return value.
3184struct AANoCaptureReturned final : AANoCaptureImpl {
3185 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
3186 llvm_unreachable("NoCapture is not applicable to function returns!");
3187 }
3188
3189 /// See AbstractAttribute::initialize(...).
3190 void initialize(Attributor &A) override {
3191 llvm_unreachable("NoCapture is not applicable to function returns!");
3192 }
3193
3194 /// See AbstractAttribute::updateImpl(...).
3195 ChangeStatus updateImpl(Attributor &A) override {
3196 llvm_unreachable("NoCapture is not applicable to function returns!");
3197 }
3198
3199 /// See AbstractAttribute::trackStatistics()
3200 void trackStatistics() const override {}
3201};
3202
3203/// NoCapture attribute deduction for a call site return value.
3204struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
3205 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3206
3207 /// See AbstractAttribute::trackStatistics()
3208 void trackStatistics() const override {
3209 STATS_DECLTRACK_CSRET_ATTR(nocapture)
3210 }
3211};
3212
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003213/// ------------------ Value Simplify Attribute ----------------------------
3214struct AAValueSimplifyImpl : AAValueSimplify {
3215 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
3216
3217 /// See AbstractAttribute::getAsStr().
3218 const std::string getAsStr() const override {
3219 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
3220 : "not-simple";
3221 }
3222
3223 /// See AbstractAttribute::trackStatistics()
3224 void trackStatistics() const override {}
3225
3226 /// See AAValueSimplify::getAssumedSimplifiedValue()
3227 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
3228 if (!getAssumed())
3229 return const_cast<Value *>(&getAssociatedValue());
3230 return SimplifiedAssociatedValue;
3231 }
3232 void initialize(Attributor &A) override {}
3233
3234 /// Helper function for querying AAValueSimplify and updating candicate.
3235 /// \param QueryingValue Value trying to unify with SimplifiedValue
3236 /// \param AccumulatedSimplifiedValue Current simplification result.
3237 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
3238 Value &QueryingValue,
3239 Optional<Value *> &AccumulatedSimplifiedValue) {
3240 // FIXME: Add a typecast support.
3241
3242 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
3243 QueryingAA, IRPosition::value(QueryingValue));
3244
3245 Optional<Value *> QueryingValueSimplified =
3246 ValueSimpifyAA.getAssumedSimplifiedValue(A);
3247
3248 if (!QueryingValueSimplified.hasValue())
3249 return true;
3250
3251 if (!QueryingValueSimplified.getValue())
3252 return false;
3253
3254 Value &QueryingValueSimplifiedUnwrapped =
3255 *QueryingValueSimplified.getValue();
3256
3257 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
3258 return true;
3259
3260 if (AccumulatedSimplifiedValue.hasValue())
3261 return AccumulatedSimplifiedValue == QueryingValueSimplified;
3262
3263 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3264 << " is assumed to be "
3265 << QueryingValueSimplifiedUnwrapped << "\n");
3266
3267 AccumulatedSimplifiedValue = QueryingValueSimplified;
3268 return true;
3269 }
3270
3271 /// See AbstractAttribute::manifest(...).
3272 ChangeStatus manifest(Attributor &A) override {
3273 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3274
3275 if (!SimplifiedAssociatedValue.hasValue() ||
3276 !SimplifiedAssociatedValue.getValue())
3277 return Changed;
3278
3279 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
3280 // We can replace the AssociatedValue with the constant.
3281 Value &V = getAssociatedValue();
3282 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
3283 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
3284 << "\n");
3285 V.replaceAllUsesWith(C);
3286 Changed = ChangeStatus::CHANGED;
3287 }
3288 }
3289
3290 return Changed | AAValueSimplify::manifest(A);
3291 }
3292
3293protected:
3294 // An assumed simplified value. Initially, it is set to Optional::None, which
3295 // means that the value is not clear under current assumption. If in the
3296 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3297 // returns orignal associated value.
3298 Optional<Value *> SimplifiedAssociatedValue;
3299};
3300
3301struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
3302 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3303
3304 /// See AbstractAttribute::updateImpl(...).
3305 ChangeStatus updateImpl(Attributor &A) override {
3306 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3307
Johannes Doerfert661db042019-10-07 23:14:58 +00003308 auto PredForCallSite = [&](AbstractCallSite ACS) {
3309 // Check if we have an associated argument or not (which can happen for
3310 // callback calls).
3311 if (Value *ArgOp = ACS.getCallArgOperand(getArgNo()))
3312 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
3313 return false;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003314 };
3315
3316 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
3317 return indicatePessimisticFixpoint();
3318
3319 // If a candicate was found in this update, return CHANGED.
3320 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3321 ? ChangeStatus::UNCHANGED
3322 : ChangeStatus ::CHANGED;
3323 }
3324
3325 /// See AbstractAttribute::trackStatistics()
3326 void trackStatistics() const override {
3327 STATS_DECLTRACK_ARG_ATTR(value_simplify)
3328 }
3329};
3330
3331struct AAValueSimplifyReturned : AAValueSimplifyImpl {
3332 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3333
3334 /// See AbstractAttribute::updateImpl(...).
3335 ChangeStatus updateImpl(Attributor &A) override {
3336 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3337
3338 auto PredForReturned = [&](Value &V) {
3339 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3340 };
3341
3342 if (!A.checkForAllReturnedValues(PredForReturned, *this))
3343 return indicatePessimisticFixpoint();
3344
3345 // If a candicate was found in this update, return CHANGED.
3346 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3347 ? ChangeStatus::UNCHANGED
3348 : ChangeStatus ::CHANGED;
3349 }
3350 /// See AbstractAttribute::trackStatistics()
3351 void trackStatistics() const override {
3352 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
3353 }
3354};
3355
3356struct AAValueSimplifyFloating : AAValueSimplifyImpl {
3357 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3358
3359 /// See AbstractAttribute::initialize(...).
3360 void initialize(Attributor &A) override {
3361 Value &V = getAnchorValue();
3362
3363 // TODO: add other stuffs
3364 if (isa<Constant>(V) || isa<UndefValue>(V))
3365 indicatePessimisticFixpoint();
3366 }
3367
3368 /// See AbstractAttribute::updateImpl(...).
3369 ChangeStatus updateImpl(Attributor &A) override {
3370 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3371
3372 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
3373 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
3374 if (!Stripped && this == &AA) {
3375 // TODO: Look the instruction and check recursively.
3376 LLVM_DEBUG(
3377 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
3378 << V << "\n");
3379 indicatePessimisticFixpoint();
3380 return false;
3381 }
3382 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3383 };
3384
3385 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
3386 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
3387 VisitValueCB))
3388 return indicatePessimisticFixpoint();
3389
3390 // If a candicate was found in this update, return CHANGED.
3391
3392 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3393 ? ChangeStatus::UNCHANGED
3394 : ChangeStatus ::CHANGED;
3395 }
3396
3397 /// See AbstractAttribute::trackStatistics()
3398 void trackStatistics() const override {
3399 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
3400 }
3401};
3402
3403struct AAValueSimplifyFunction : AAValueSimplifyImpl {
3404 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3405
3406 /// See AbstractAttribute::initialize(...).
3407 void initialize(Attributor &A) override {
3408 SimplifiedAssociatedValue = &getAnchorValue();
3409 indicateOptimisticFixpoint();
3410 }
3411 /// See AbstractAttribute::initialize(...).
3412 ChangeStatus updateImpl(Attributor &A) override {
3413 llvm_unreachable(
3414 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
3415 }
3416 /// See AbstractAttribute::trackStatistics()
3417 void trackStatistics() const override {
3418 STATS_DECLTRACK_FN_ATTR(value_simplify)
3419 }
3420};
3421
3422struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
3423 AAValueSimplifyCallSite(const IRPosition &IRP)
3424 : AAValueSimplifyFunction(IRP) {}
3425 /// See AbstractAttribute::trackStatistics()
3426 void trackStatistics() const override {
3427 STATS_DECLTRACK_CS_ATTR(value_simplify)
3428 }
3429};
3430
3431struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
3432 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
3433 : AAValueSimplifyReturned(IRP) {}
3434
3435 void trackStatistics() const override {
3436 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
3437 }
3438};
3439struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
3440 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
3441 : AAValueSimplifyFloating(IRP) {}
3442
3443 void trackStatistics() const override {
3444 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
3445 }
3446};
3447
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003448/// ----------------------- Heap-To-Stack Conversion ---------------------------
3449struct AAHeapToStackImpl : public AAHeapToStack {
3450 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
3451
3452 const std::string getAsStr() const override {
3453 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
3454 }
3455
3456 ChangeStatus manifest(Attributor &A) override {
3457 assert(getState().isValidState() &&
3458 "Attempted to manifest an invalid state!");
3459
3460 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
3461 Function *F = getAssociatedFunction();
3462 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3463
3464 for (Instruction *MallocCall : MallocCalls) {
3465 // This malloc cannot be replaced.
3466 if (BadMallocCalls.count(MallocCall))
3467 continue;
3468
3469 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
3470 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
3471 A.deleteAfterManifest(*FreeCall);
3472 HasChanged = ChangeStatus::CHANGED;
3473 }
3474
3475 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
3476 << "\n");
3477
3478 Constant *Size;
3479 if (isCallocLikeFn(MallocCall, TLI)) {
3480 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
3481 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
3482 APInt TotalSize = SizeT->getValue() * Num->getValue();
3483 Size =
3484 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
3485 } else {
3486 Size = cast<ConstantInt>(MallocCall->getOperand(0));
3487 }
3488
3489 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
3490 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
3491 Size, "", MallocCall->getNextNode());
3492
3493 if (AI->getType() != MallocCall->getType())
3494 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
3495 AI->getNextNode());
3496
3497 MallocCall->replaceAllUsesWith(AI);
3498
3499 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
3500 auto *NBB = II->getNormalDest();
3501 BranchInst::Create(NBB, MallocCall->getParent());
3502 A.deleteAfterManifest(*MallocCall);
3503 } else {
3504 A.deleteAfterManifest(*MallocCall);
3505 }
3506
3507 if (isCallocLikeFn(MallocCall, TLI)) {
3508 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
3509 AI->getNextNode());
3510 Value *Ops[] = {
3511 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
3512 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
3513
3514 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
3515 Module *M = F->getParent();
3516 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
3517 CallInst::Create(Fn, Ops, "", BI->getNextNode());
3518 }
3519 HasChanged = ChangeStatus::CHANGED;
3520 }
3521
3522 return HasChanged;
3523 }
3524
3525 /// Collection of all malloc calls in a function.
3526 SmallSetVector<Instruction *, 4> MallocCalls;
3527
3528 /// Collection of malloc calls that cannot be converted.
3529 DenseSet<const Instruction *> BadMallocCalls;
3530
3531 /// A map for each malloc call to the set of associated free calls.
3532 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
3533
3534 ChangeStatus updateImpl(Attributor &A) override;
3535};
3536
3537ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
3538 const Function *F = getAssociatedFunction();
3539 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3540
3541 auto UsesCheck = [&](Instruction &I) {
3542 SmallPtrSet<const Use *, 8> Visited;
3543 SmallVector<const Use *, 8> Worklist;
3544
3545 for (Use &U : I.uses())
3546 Worklist.push_back(&U);
3547
3548 while (!Worklist.empty()) {
3549 const Use *U = Worklist.pop_back_val();
3550 if (!Visited.insert(U).second)
3551 continue;
3552
3553 auto *UserI = U->getUser();
3554
3555 if (isa<LoadInst>(UserI) || isa<StoreInst>(UserI))
3556 continue;
3557
3558 // NOTE: Right now, if a function that has malloc pointer as an argument
3559 // frees memory, we assume that the malloc pointer is freed.
3560
3561 // TODO: Add nofree callsite argument attribute to indicate that pointer
3562 // argument is not freed.
3563 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3564 if (!CB->isArgOperand(U))
3565 continue;
3566
3567 if (CB->isLifetimeStartOrEnd())
3568 continue;
3569
3570 // Record malloc.
3571 if (isFreeCall(UserI, TLI)) {
3572 FreesForMalloc[&I].insert(
3573 cast<Instruction>(const_cast<User *>(UserI)));
3574 continue;
3575 }
3576
3577 // If a function does not free memory we are fine
3578 const auto &NoFreeAA =
3579 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(*CB));
3580
3581 unsigned ArgNo = U - CB->arg_begin();
3582 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
3583 *this, IRPosition::callsite_argument(*CB, ArgNo));
3584
3585 if (!NoCaptureAA.isAssumedNoCapture() || !NoFreeAA.isAssumedNoFree()) {
3586 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
3587 return false;
3588 }
3589 continue;
3590 }
3591
3592 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI)) {
3593 for (Use &U : UserI->uses())
3594 Worklist.push_back(&U);
3595 continue;
3596 }
3597
3598 // Unknown user.
3599 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
3600 return false;
3601 }
3602 return true;
3603 };
3604
3605 auto MallocCallocCheck = [&](Instruction &I) {
3606 if (isMallocLikeFn(&I, TLI)) {
3607 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
3608 if (!Size->getValue().sle(MaxHeapToStackSize))
3609 return true;
3610 } else if (isCallocLikeFn(&I, TLI)) {
3611 bool Overflow = false;
3612 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
3613 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
3614 if (!(Size->getValue().umul_ov(Num->getValue(), Overflow))
3615 .sle(MaxHeapToStackSize))
3616 if (!Overflow)
3617 return true;
3618 } else {
3619 BadMallocCalls.insert(&I);
3620 return true;
3621 }
3622
3623 if (BadMallocCalls.count(&I))
3624 return true;
3625
3626 if (UsesCheck(I))
3627 MallocCalls.insert(&I);
3628 else
3629 BadMallocCalls.insert(&I);
3630 return true;
3631 };
3632
3633 size_t NumBadMallocs = BadMallocCalls.size();
3634
3635 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
3636
3637 if (NumBadMallocs != BadMallocCalls.size())
3638 return ChangeStatus::CHANGED;
3639
3640 return ChangeStatus::UNCHANGED;
3641}
3642
3643struct AAHeapToStackFunction final : public AAHeapToStackImpl {
3644 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
3645
3646 /// See AbstractAttribute::trackStatistics()
3647 void trackStatistics() const override {
3648 STATS_DECL(MallocCalls, Function,
3649 "Number of MallocCalls converted to allocas");
3650 BUILD_STAT_NAME(MallocCalls, Function) += MallocCalls.size();
3651 }
3652};
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +00003653} // namespace
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003654
Johannes Doerfert1097fab2019-10-07 21:07:57 +00003655/// -------------------- Memory Behavior Attributes ----------------------------
3656/// Includes read-none, read-only, and write-only.
3657/// ----------------------------------------------------------------------------
3658struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
3659 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
3660
3661 /// See AbstractAttribute::initialize(...).
3662 void initialize(Attributor &A) override {
3663 intersectAssumedBits(BEST_STATE);
3664 getKnownStateFromValue(getIRPosition(), getState());
3665 IRAttribute::initialize(A);
3666 }
3667
3668 /// Return the memory behavior information encoded in the IR for \p IRP.
3669 static void getKnownStateFromValue(const IRPosition &IRP,
3670 IntegerState &State) {
3671 SmallVector<Attribute, 2> Attrs;
3672 IRP.getAttrs(AttrKinds, Attrs);
3673 for (const Attribute &Attr : Attrs) {
3674 switch (Attr.getKindAsEnum()) {
3675 case Attribute::ReadNone:
3676 State.addKnownBits(NO_ACCESSES);
3677 break;
3678 case Attribute::ReadOnly:
3679 State.addKnownBits(NO_WRITES);
3680 break;
3681 case Attribute::WriteOnly:
3682 State.addKnownBits(NO_READS);
3683 break;
3684 default:
3685 llvm_unreachable("Unexpcted attribute!");
3686 }
3687 }
3688
3689 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
3690 if (!I->mayReadFromMemory())
3691 State.addKnownBits(NO_READS);
3692 if (!I->mayWriteToMemory())
3693 State.addKnownBits(NO_WRITES);
3694 }
3695 }
3696
3697 /// See AbstractAttribute::getDeducedAttributes(...).
3698 void getDeducedAttributes(LLVMContext &Ctx,
3699 SmallVectorImpl<Attribute> &Attrs) const override {
3700 assert(Attrs.size() == 0);
3701 if (isAssumedReadNone())
3702 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
3703 else if (isAssumedReadOnly())
3704 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
3705 else if (isAssumedWriteOnly())
3706 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
3707 assert(Attrs.size() <= 1);
3708 }
3709
3710 /// See AbstractAttribute::manifest(...).
3711 ChangeStatus manifest(Attributor &A) override {
3712 IRPosition &IRP = getIRPosition();
3713
3714 // Check if we would improve the existing attributes first.
3715 SmallVector<Attribute, 4> DeducedAttrs;
3716 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
3717 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
3718 return IRP.hasAttr(Attr.getKindAsEnum(),
3719 /* IgnoreSubsumingPositions */ true);
3720 }))
3721 return ChangeStatus::UNCHANGED;
3722
3723 // Clear existing attributes.
3724 IRP.removeAttrs(AttrKinds);
3725
3726 // Use the generic manifest method.
3727 return IRAttribute::manifest(A);
3728 }
3729
3730 /// See AbstractState::getAsStr().
3731 const std::string getAsStr() const override {
3732 if (isAssumedReadNone())
3733 return "readnone";
3734 if (isAssumedReadOnly())
3735 return "readonly";
3736 if (isAssumedWriteOnly())
3737 return "writeonly";
3738 return "may-read/write";
3739 }
3740
3741 /// The set of IR attributes AAMemoryBehavior deals with.
3742 static const Attribute::AttrKind AttrKinds[3];
3743};
3744
3745const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
3746 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
3747
3748/// Memory behavior attribute for a floating value.
3749struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
3750 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
3751
3752 /// See AbstractAttribute::initialize(...).
3753 void initialize(Attributor &A) override {
3754 AAMemoryBehaviorImpl::initialize(A);
3755 // Initialize the use vector with all direct uses of the associated value.
3756 for (const Use &U : getAssociatedValue().uses())
3757 Uses.insert(&U);
3758 }
3759
3760 /// See AbstractAttribute::updateImpl(...).
3761 ChangeStatus updateImpl(Attributor &A) override;
3762
3763 /// See AbstractAttribute::trackStatistics()
3764 void trackStatistics() const override {
3765 if (isAssumedReadNone())
3766 STATS_DECLTRACK_FLOATING_ATTR(readnone)
3767 else if (isAssumedReadOnly())
3768 STATS_DECLTRACK_FLOATING_ATTR(readonly)
3769 else if (isAssumedWriteOnly())
3770 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
3771 }
3772
3773private:
3774 /// Return true if users of \p UserI might access the underlying
3775 /// variable/location described by \p U and should therefore be analyzed.
3776 bool followUsersOfUseIn(Attributor &A, const Use *U,
3777 const Instruction *UserI);
3778
3779 /// Update the state according to the effect of use \p U in \p UserI.
3780 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
3781
3782protected:
3783 /// Container for (transitive) uses of the associated argument.
3784 SetVector<const Use *> Uses;
3785};
3786
3787/// Memory behavior attribute for function argument.
3788struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
3789 AAMemoryBehaviorArgument(const IRPosition &IRP)
3790 : AAMemoryBehaviorFloating(IRP) {}
3791
3792 /// See AbstractAttribute::initialize(...).
3793 void initialize(Attributor &A) override {
3794 AAMemoryBehaviorFloating::initialize(A);
3795
3796 // TODO: From readattrs.ll: "inalloca parameters are always
3797 // considered written"
3798 if (hasAttr({Attribute::InAlloca}))
3799 removeAssumedBits(NO_WRITES);
3800
3801 // Initialize the use vector with all direct uses of the associated value.
3802 Argument *Arg = getAssociatedArgument();
3803 if (!Arg || !Arg->getParent()->hasExactDefinition())
3804 indicatePessimisticFixpoint();
3805 }
3806
3807 /// See AbstractAttribute::trackStatistics()
3808 void trackStatistics() const override {
3809 if (isAssumedReadNone())
3810 STATS_DECLTRACK_ARG_ATTR(readnone)
3811 else if (isAssumedReadOnly())
3812 STATS_DECLTRACK_ARG_ATTR(readonly)
3813 else if (isAssumedWriteOnly())
3814 STATS_DECLTRACK_ARG_ATTR(writeonly)
3815 }
3816};
3817
3818struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
3819 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
3820 : AAMemoryBehaviorArgument(IRP) {}
3821
3822 /// See AbstractAttribute::updateImpl(...).
3823 ChangeStatus updateImpl(Attributor &A) override {
3824 // TODO: Once we have call site specific value information we can provide
3825 // call site specific liveness liveness information and then it makes
3826 // sense to specialize attributes for call sites arguments instead of
3827 // redirecting requests to the callee argument.
3828 Argument *Arg = getAssociatedArgument();
3829 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3830 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
3831 return clampStateAndIndicateChange(
3832 getState(),
3833 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3834 }
3835
3836 /// See AbstractAttribute::trackStatistics()
3837 void trackStatistics() const override {
3838 if (isAssumedReadNone())
3839 STATS_DECLTRACK_CSARG_ATTR(readnone)
3840 else if (isAssumedReadOnly())
3841 STATS_DECLTRACK_CSARG_ATTR(readonly)
3842 else if (isAssumedWriteOnly())
3843 STATS_DECLTRACK_CSARG_ATTR(writeonly)
3844 }
3845};
3846
3847/// Memory behavior attribute for a call site return position.
3848struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
3849 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
3850 : AAMemoryBehaviorFloating(IRP) {}
3851
3852 /// See AbstractAttribute::manifest(...).
3853 ChangeStatus manifest(Attributor &A) override {
3854 // We do not annotate returned values.
3855 return ChangeStatus::UNCHANGED;
3856 }
3857
3858 /// See AbstractAttribute::trackStatistics()
3859 void trackStatistics() const override {}
3860};
3861
3862/// An AA to represent the memory behavior function attributes.
3863struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
3864 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
3865
3866 /// See AbstractAttribute::updateImpl(Attributor &A).
3867 virtual ChangeStatus updateImpl(Attributor &A) override;
3868
3869 /// See AbstractAttribute::manifest(...).
3870 ChangeStatus manifest(Attributor &A) override {
3871 Function &F = cast<Function>(getAnchorValue());
3872 if (isAssumedReadNone()) {
3873 F.removeFnAttr(Attribute::ArgMemOnly);
3874 F.removeFnAttr(Attribute::InaccessibleMemOnly);
3875 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
3876 }
3877 return AAMemoryBehaviorImpl::manifest(A);
3878 }
3879
3880 /// See AbstractAttribute::trackStatistics()
3881 void trackStatistics() const override {
3882 if (isAssumedReadNone())
3883 STATS_DECLTRACK_FN_ATTR(readnone)
3884 else if (isAssumedReadOnly())
3885 STATS_DECLTRACK_FN_ATTR(readonly)
3886 else if (isAssumedWriteOnly())
3887 STATS_DECLTRACK_FN_ATTR(writeonly)
3888 }
3889};
3890
3891/// AAMemoryBehavior attribute for call sites.
3892struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
3893 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
3894
3895 /// See AbstractAttribute::initialize(...).
3896 void initialize(Attributor &A) override {
3897 AAMemoryBehaviorImpl::initialize(A);
3898 Function *F = getAssociatedFunction();
3899 if (!F || !F->hasExactDefinition())
3900 indicatePessimisticFixpoint();
3901 }
3902
3903 /// See AbstractAttribute::updateImpl(...).
3904 ChangeStatus updateImpl(Attributor &A) override {
3905 // TODO: Once we have call site specific value information we can provide
3906 // call site specific liveness liveness information and then it makes
3907 // sense to specialize attributes for call sites arguments instead of
3908 // redirecting requests to the callee argument.
3909 Function *F = getAssociatedFunction();
3910 const IRPosition &FnPos = IRPosition::function(*F);
3911 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3912 return clampStateAndIndicateChange(
3913 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
3914 }
3915
3916 /// See AbstractAttribute::trackStatistics()
3917 void trackStatistics() const override {
3918 if (isAssumedReadNone())
3919 STATS_DECLTRACK_CS_ATTR(readnone)
3920 else if (isAssumedReadOnly())
3921 STATS_DECLTRACK_CS_ATTR(readonly)
3922 else if (isAssumedWriteOnly())
3923 STATS_DECLTRACK_CS_ATTR(writeonly)
3924 }
3925};
3926
3927ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
3928
3929 // The current assumed state used to determine a change.
3930 auto AssumedState = getAssumed();
3931
3932 auto CheckRWInst = [&](Instruction &I) {
3933 // If the instruction has an own memory behavior state, use it to restrict
3934 // the local state. No further analysis is required as the other memory
3935 // state is as optimistic as it gets.
3936 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
3937 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3938 *this, IRPosition::callsite_function(ICS));
3939 intersectAssumedBits(MemBehaviorAA.getAssumed());
3940 return !isAtFixpoint();
3941 }
3942
3943 // Remove access kind modifiers if necessary.
3944 if (I.mayReadFromMemory())
3945 removeAssumedBits(NO_READS);
3946 if (I.mayWriteToMemory())
3947 removeAssumedBits(NO_WRITES);
3948 return !isAtFixpoint();
3949 };
3950
3951 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
3952 return indicatePessimisticFixpoint();
3953
3954 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
3955 : ChangeStatus::UNCHANGED;
3956}
3957
3958ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
3959
3960 const IRPosition &IRP = getIRPosition();
3961 const IRPosition &FnPos = IRPosition::function_scope(IRP);
3962 AAMemoryBehavior::StateType &S = getState();
3963
3964 // First, check the function scope. We take the known information and we avoid
3965 // work if the assumed information implies the current assumed information for
3966 // this attribute.
3967 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3968 S.addKnownBits(FnMemAA.getKnown());
3969 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
3970 return ChangeStatus::UNCHANGED;
3971
3972 // Make sure the value is not captured (except through "return"), if
3973 // it is, any information derived would be irrelevant anyway as we cannot
3974 // check the potential aliases introduced by the capture.
3975 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
3976 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned())
3977 return indicatePessimisticFixpoint();
3978
3979 // The current assumed state used to determine a change.
3980 auto AssumedState = S.getAssumed();
3981
3982 // Liveness information to exclude dead users.
3983 // TODO: Take the FnPos once we have call site specific liveness information.
3984 const auto &LivenessAA = A.getAAFor<AAIsDead>(
3985 *this, IRPosition::function(*IRP.getAssociatedFunction()));
3986
3987 // Visit and expand uses until all are analyzed or a fixpoint is reached.
3988 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
3989 const Use *U = Uses[i];
3990 Instruction *UserI = cast<Instruction>(U->getUser());
3991 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
3992 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
3993 << "]\n");
3994 if (LivenessAA.isAssumedDead(UserI))
3995 continue;
3996
3997 // Check if the users of UserI should also be visited.
3998 if (followUsersOfUseIn(A, U, UserI))
3999 for (const Use &UserIUse : UserI->uses())
4000 Uses.insert(&UserIUse);
4001
4002 // If UserI might touch memory we analyze the use in detail.
4003 if (UserI->mayReadOrWriteMemory())
4004 analyzeUseIn(A, U, UserI);
4005 }
4006
4007 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4008 : ChangeStatus::UNCHANGED;
4009}
4010
4011bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
4012 const Instruction *UserI) {
4013 // The loaded value is unrelated to the pointer argument, no need to
4014 // follow the users of the load.
4015 if (isa<LoadInst>(UserI))
4016 return false;
4017
4018 // By default we follow all uses assuming UserI might leak information on U,
4019 // we have special handling for call sites operands though.
4020 ImmutableCallSite ICS(UserI);
4021 if (!ICS || !ICS.isArgOperand(U))
4022 return true;
4023
4024 // If the use is a call argument known not to be captured, the users of
4025 // the call do not need to be visited because they have to be unrelated to
4026 // the input. Note that this check is not trivial even though we disallow
4027 // general capturing of the underlying argument. The reason is that the
4028 // call might the argument "through return", which we allow and for which we
4029 // need to check call users.
4030 unsigned ArgNo = ICS.getArgumentNo(U);
4031 const auto &ArgNoCaptureAA =
4032 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
4033 return !ArgNoCaptureAA.isAssumedNoCapture();
4034}
4035
4036void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
4037 const Instruction *UserI) {
4038 assert(UserI->mayReadOrWriteMemory());
4039
4040 switch (UserI->getOpcode()) {
4041 default:
4042 // TODO: Handle all atomics and other side-effect operations we know of.
4043 break;
4044 case Instruction::Load:
4045 // Loads cause the NO_READS property to disappear.
4046 removeAssumedBits(NO_READS);
4047 return;
4048
4049 case Instruction::Store:
4050 // Stores cause the NO_WRITES property to disappear if the use is the
4051 // pointer operand. Note that we do assume that capturing was taken care of
4052 // somewhere else.
4053 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
4054 removeAssumedBits(NO_WRITES);
4055 return;
4056
4057 case Instruction::Call:
4058 case Instruction::CallBr:
4059 case Instruction::Invoke: {
4060 // For call sites we look at the argument memory behavior attribute (this
4061 // could be recursive!) in order to restrict our own state.
4062 ImmutableCallSite ICS(UserI);
4063
4064 // Give up on operand bundles.
4065 if (ICS.isBundleOperand(U)) {
4066 indicatePessimisticFixpoint();
4067 return;
4068 }
4069
4070 // Calling a function does read the function pointer, maybe write it if the
4071 // function is self-modifying.
4072 if (ICS.isCallee(U)) {
4073 removeAssumedBits(NO_READS);
4074 break;
4075 }
4076
4077 // Adjust the possible access behavior based on the information on the
4078 // argument.
4079 unsigned ArgNo = ICS.getArgumentNo(U);
4080 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
4081 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4082 // "assumed" has at most the same bits as the MemBehaviorAA assumed
4083 // and at least "known".
4084 intersectAssumedBits(MemBehaviorAA.getAssumed());
4085 return;
4086 }
4087 };
4088
4089 // Generally, look at the "may-properties" and adjust the assumed state if we
4090 // did not trigger special handling before.
4091 if (UserI->mayReadFromMemory())
4092 removeAssumedBits(NO_READS);
4093 if (UserI->mayWriteToMemory())
4094 removeAssumedBits(NO_WRITES);
4095}
4096
Johannes Doerfertaade7822019-06-05 03:02:24 +00004097/// ----------------------------------------------------------------------------
4098/// Attributor
4099/// ----------------------------------------------------------------------------
4100
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004101bool Attributor::isAssumedDead(const AbstractAttribute &AA,
4102 const AAIsDead *LivenessAA) {
4103 const Instruction *CtxI = AA.getIRPosition().getCtxI();
4104 if (!CtxI)
4105 return false;
4106
4107 if (!LivenessAA)
4108 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00004109 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
4110 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00004111
4112 // Don't check liveness for AAIsDead.
4113 if (&AA == LivenessAA)
4114 return false;
4115
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004116 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004117 return false;
4118
Johannes Doerfert19b00432019-08-26 17:48:05 +00004119 // We actually used liveness information so we have to record a dependence.
4120 recordDependence(*LivenessAA, AA);
4121
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004122 return true;
4123}
4124
Johannes Doerfert661db042019-10-07 23:14:58 +00004125bool Attributor::checkForAllCallSites(
4126 const function_ref<bool(AbstractCallSite)> &Pred,
4127 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004128 // We can try to determine information from
4129 // the call sites. However, this is only possible all call sites are known,
4130 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004131 const IRPosition &IRP = QueryingAA.getIRPosition();
4132 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00004133 if (!AssociatedFunction) {
4134 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
4135 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004136 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00004137 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004138
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004139 if (RequireAllCallSites && !AssociatedFunction->hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004140 LLVM_DEBUG(
4141 dbgs()
Johannes Doerfert5304b722019-08-14 22:04:28 +00004142 << "[Attributor] Function " << AssociatedFunction->getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00004143 << " has no internal linkage, hence not all call sites are known\n");
4144 return false;
4145 }
4146
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004147 for (const Use &U : AssociatedFunction->uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00004148 AbstractCallSite ACS(&U);
4149 if (!ACS) {
4150 LLVM_DEBUG(dbgs() << "[Attributor] Function "
4151 << AssociatedFunction->getName()
4152 << " has non call site use " << *U.get() << " in "
4153 << *U.getUser() << "\n");
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004154 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00004155 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004156
Johannes Doerfert661db042019-10-07 23:14:58 +00004157 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004158 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004159
Johannes Doerfert661db042019-10-07 23:14:58 +00004160 const auto &LivenessAA =
4161 getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*Caller),
4162 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004163
4164 // Skip dead calls.
Johannes Doerfert19b00432019-08-26 17:48:05 +00004165 if (LivenessAA.isAssumedDead(I)) {
4166 // We actually used liveness information so we have to record a
4167 // dependence.
4168 recordDependence(LivenessAA, QueryingAA);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004169 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004170 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004171
Johannes Doerfert661db042019-10-07 23:14:58 +00004172 const Use *EffectiveUse =
4173 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
4174 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004175 if (!RequireAllCallSites)
4176 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00004177 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004178 << " is an invalid use of "
4179 << AssociatedFunction->getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004180 return false;
4181 }
4182
Johannes Doerfert661db042019-10-07 23:14:58 +00004183 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00004184 continue;
4185
Johannes Doerfert5304b722019-08-14 22:04:28 +00004186 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00004187 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004188 return false;
4189 }
4190
4191 return true;
4192}
4193
Johannes Doerfert14a04932019-08-07 22:27:24 +00004194bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004195 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00004196 &Pred,
4197 const AbstractAttribute &QueryingAA) {
4198
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004199 const IRPosition &IRP = QueryingAA.getIRPosition();
4200 // Since we need to provide return instructions we have to have an exact
4201 // definition.
4202 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004203 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004204 return false;
4205
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004206 // If this is a call site query we use the call site specific return values
4207 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004208 // TODO: use the function scope once we have call site AAReturnedValues.
4209 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004210 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004211 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004212 return false;
4213
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004214 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00004215}
4216
4217bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004218 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00004219 const AbstractAttribute &QueryingAA) {
4220
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004221 const IRPosition &IRP = QueryingAA.getIRPosition();
4222 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004223 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004224 return false;
4225
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004226 // TODO: use the function scope once we have call site AAReturnedValues.
4227 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004228 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004229 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004230 return false;
4231
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004232 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004233 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00004234 return Pred(RV);
4235 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00004236}
4237
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004238static bool
4239checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
4240 const function_ref<bool(Instruction &)> &Pred,
4241 const AAIsDead *LivenessAA, bool &AnyDead,
4242 const ArrayRef<unsigned> &Opcodes) {
4243 for (unsigned Opcode : Opcodes) {
4244 for (Instruction *I : OpcodeInstMap[Opcode]) {
4245 // Skip dead instructions.
4246 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
4247 AnyDead = true;
4248 continue;
4249 }
4250
4251 if (!Pred(*I))
4252 return false;
4253 }
4254 }
4255 return true;
4256}
4257
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004258bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004259 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004260 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004261
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004262 const IRPosition &IRP = QueryingAA.getIRPosition();
4263 // Since we need to provide instructions we have to have an exact definition.
4264 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004265 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004266 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004267
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004268 // TODO: use the function scope once we have call site AAReturnedValues.
4269 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004270 const auto &LivenessAA =
4271 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
4272 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004273
4274 auto &OpcodeInstMap =
4275 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004276 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
4277 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004278 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004279
Johannes Doerfert19b00432019-08-26 17:48:05 +00004280 // If we actually used liveness information so we have to record a dependence.
4281 if (AnyDead)
4282 recordDependence(LivenessAA, QueryingAA);
4283
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004284 return true;
4285}
4286
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004287bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004288 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004289 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004290
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004291 const Function *AssociatedFunction =
4292 QueryingAA.getIRPosition().getAssociatedFunction();
4293 if (!AssociatedFunction)
4294 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004295
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004296 // TODO: use the function scope once we have call site AAReturnedValues.
4297 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
4298 const auto &LivenessAA =
4299 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004300 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004301
4302 for (Instruction *I :
4303 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004304 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00004305 if (LivenessAA.isAssumedDead(I)) {
4306 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004307 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004308 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004309
4310 if (!Pred(*I))
4311 return false;
4312 }
4313
Johannes Doerfert19b00432019-08-26 17:48:05 +00004314 // If we actually used liveness information so we have to record a dependence.
4315 if (AnyDead)
4316 recordDependence(LivenessAA, QueryingAA);
4317
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004318 return true;
4319}
4320
Johannes Doerfert2f622062019-09-04 16:35:20 +00004321ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004322 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
4323 << AllAbstractAttributes.size()
4324 << " abstract attributes.\n");
4325
Stefan Stipanovic53605892019-06-27 11:27:54 +00004326 // Now that all abstract attributes are collected and initialized we start
4327 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00004328
4329 unsigned IterationCounter = 1;
4330
4331 SmallVector<AbstractAttribute *, 64> ChangedAAs;
4332 SetVector<AbstractAttribute *> Worklist;
4333 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
4334
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004335 bool RecomputeDependences = false;
4336
Johannes Doerfertaade7822019-06-05 03:02:24 +00004337 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004338 // Remember the size to determine new attributes.
4339 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004340 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
4341 << ", Worklist size: " << Worklist.size() << "\n");
4342
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004343 // If dependences (=QueryMap) are recomputed we have to look at all abstract
4344 // attributes again, regardless of what changed in the last iteration.
4345 if (RecomputeDependences) {
4346 LLVM_DEBUG(
4347 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
4348 QueryMap.clear();
4349 ChangedAAs.clear();
4350 Worklist.insert(AllAbstractAttributes.begin(),
4351 AllAbstractAttributes.end());
4352 }
4353
Johannes Doerfertaade7822019-06-05 03:02:24 +00004354 // Add all abstract attributes that are potentially dependent on one that
4355 // changed to the work list.
4356 for (AbstractAttribute *ChangedAA : ChangedAAs) {
4357 auto &QuerriedAAs = QueryMap[ChangedAA];
4358 Worklist.insert(QuerriedAAs.begin(), QuerriedAAs.end());
4359 }
4360
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004361 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
4362 << ", Worklist+Dependent size: " << Worklist.size()
4363 << "\n");
4364
Johannes Doerfertaade7822019-06-05 03:02:24 +00004365 // Reset the changed set.
4366 ChangedAAs.clear();
4367
4368 // Update all abstract attribute in the work list and record the ones that
4369 // changed.
4370 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004371 if (!isAssumedDead(*AA, nullptr))
4372 if (AA->update(*this) == ChangeStatus::CHANGED)
4373 ChangedAAs.push_back(AA);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004374
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004375 // Check if we recompute the dependences in the next iteration.
4376 RecomputeDependences = (DepRecomputeInterval > 0 &&
4377 IterationCounter % DepRecomputeInterval == 0);
4378
Johannes Doerfert9543f142019-08-23 15:24:57 +00004379 // Add attributes to the changed set if they have been created in the last
4380 // iteration.
4381 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
4382 AllAbstractAttributes.end());
4383
Johannes Doerfertaade7822019-06-05 03:02:24 +00004384 // Reset the work list and repopulate with the changed abstract attributes.
4385 // Note that dependent ones are added above.
4386 Worklist.clear();
4387 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
4388
Johannes Doerfertbf112132019-08-29 01:29:44 +00004389 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
4390 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004391
Johannes Doerfertaade7822019-06-05 03:02:24 +00004392 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
4393 << IterationCounter << "/" << MaxFixpointIterations
4394 << " iterations\n");
4395
Johannes Doerfertbf112132019-08-29 01:29:44 +00004396 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004397
Johannes Doerfertaade7822019-06-05 03:02:24 +00004398 bool FinishedAtFixpoint = Worklist.empty();
4399
4400 // Reset abstract arguments not settled in a sound fixpoint by now. This
4401 // happens when we stopped the fixpoint iteration early. Note that only the
4402 // ones marked as "changed" *and* the ones transitively depending on them
4403 // need to be reverted to a pessimistic state. Others might not be in a
4404 // fixpoint state but we can use the optimistic results for them anyway.
4405 SmallPtrSet<AbstractAttribute *, 32> Visited;
4406 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
4407 AbstractAttribute *ChangedAA = ChangedAAs[u];
4408 if (!Visited.insert(ChangedAA).second)
4409 continue;
4410
4411 AbstractState &State = ChangedAA->getState();
4412 if (!State.isAtFixpoint()) {
4413 State.indicatePessimisticFixpoint();
4414
4415 NumAttributesTimedOut++;
4416 }
4417
4418 auto &QuerriedAAs = QueryMap[ChangedAA];
4419 ChangedAAs.append(QuerriedAAs.begin(), QuerriedAAs.end());
4420 }
4421
4422 LLVM_DEBUG({
4423 if (!Visited.empty())
4424 dbgs() << "\n[Attributor] Finalized " << Visited.size()
4425 << " abstract attributes.\n";
4426 });
4427
4428 unsigned NumManifested = 0;
4429 unsigned NumAtFixpoint = 0;
4430 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
4431 for (AbstractAttribute *AA : AllAbstractAttributes) {
4432 AbstractState &State = AA->getState();
4433
4434 // If there is not already a fixpoint reached, we can now take the
4435 // optimistic state. This is correct because we enforced a pessimistic one
4436 // on abstract attributes that were transitively dependent on a changed one
4437 // already above.
4438 if (!State.isAtFixpoint())
4439 State.indicateOptimisticFixpoint();
4440
4441 // If the state is invalid, we do not try to manifest it.
4442 if (!State.isValidState())
4443 continue;
4444
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004445 // Skip dead code.
4446 if (isAssumedDead(*AA, nullptr))
4447 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004448 // Manifest the state and record if we changed the IR.
4449 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00004450 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
4451 AA->trackStatistics();
4452
Johannes Doerfertaade7822019-06-05 03:02:24 +00004453 ManifestChange = ManifestChange | LocalChange;
4454
4455 NumAtFixpoint++;
4456 NumManifested += (LocalChange == ChangeStatus::CHANGED);
4457 }
4458
4459 (void)NumManifested;
4460 (void)NumAtFixpoint;
4461 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
4462 << " arguments while " << NumAtFixpoint
4463 << " were in a valid fixpoint state\n");
4464
4465 // If verification is requested, we finished this run at a fixpoint, and the
4466 // IR was changed, we re-run the whole fixpoint analysis, starting at
4467 // re-initialization of the arguments. This re-run should not result in an IR
4468 // change. Though, the (virtual) state of attributes at the end of the re-run
4469 // might be more optimistic than the known state or the IR state if the better
4470 // state cannot be manifested.
4471 if (VerifyAttributor && FinishedAtFixpoint &&
4472 ManifestChange == ChangeStatus::CHANGED) {
4473 VerifyAttributor = false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00004474 ChangeStatus VerifyStatus = run(M);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004475 if (VerifyStatus != ChangeStatus::UNCHANGED)
4476 llvm_unreachable(
4477 "Attributor verification failed, re-run did result in an IR change "
4478 "even after a fixpoint was reached in the original run. (False "
4479 "positives possible!)");
4480 VerifyAttributor = true;
4481 }
4482
4483 NumAttributesManifested += NumManifested;
4484 NumAttributesValidFixpoint += NumAtFixpoint;
4485
Fangrui Songf1826172019-08-20 07:21:43 +00004486 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004487 assert(
4488 NumFinalAAs == AllAbstractAttributes.size() &&
4489 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00004490
4491 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00004492 {
4493 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
4494 << ToBeDeletedFunctions.size() << " functions and "
4495 << ToBeDeletedBlocks.size() << " blocks and "
4496 << ToBeDeletedInsts.size() << " instructions\n");
4497 for (Instruction *I : ToBeDeletedInsts) {
4498 if (!I->use_empty())
4499 I->replaceAllUsesWith(UndefValue::get(I->getType()));
4500 I->eraseFromParent();
4501 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004502
Johannes Doerfert2f622062019-09-04 16:35:20 +00004503 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
4504 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
4505 ToBeDeletedBBs.reserve(NumDeadBlocks);
4506 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
4507 DeleteDeadBlocks(ToBeDeletedBBs);
4508 STATS_DECLTRACK(AAIsDead, BasicBlock,
4509 "Number of dead basic blocks deleted.");
4510 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004511
Johannes Doerfert2f622062019-09-04 16:35:20 +00004512 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
4513 for (Function *Fn : ToBeDeletedFunctions) {
4514 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
4515 Fn->eraseFromParent();
4516 STATS_TRACK(AAIsDead, Function);
4517 }
4518
4519 // Identify dead internal functions and delete them. This happens outside
4520 // the other fixpoint analysis as we might treat potentially dead functions
4521 // as live to lower the number of iterations. If they happen to be dead, the
4522 // below fixpoint loop will identify and eliminate them.
4523 SmallVector<Function *, 8> InternalFns;
4524 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004525 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00004526 InternalFns.push_back(&F);
4527
4528 bool FoundDeadFn = true;
4529 while (FoundDeadFn) {
4530 FoundDeadFn = false;
4531 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
4532 Function *F = InternalFns[u];
4533 if (!F)
4534 continue;
4535
4536 const auto *LivenessAA =
4537 lookupAAFor<AAIsDead>(IRPosition::function(*F));
4538 if (LivenessAA &&
Johannes Doerfert661db042019-10-07 23:14:58 +00004539 !checkForAllCallSites([](AbstractCallSite ACS) { return false; },
Johannes Doerfert2f622062019-09-04 16:35:20 +00004540 *LivenessAA, true))
4541 continue;
4542
4543 STATS_TRACK(AAIsDead, Function);
4544 F->replaceAllUsesWith(UndefValue::get(F->getType()));
4545 F->eraseFromParent();
4546 InternalFns[u] = nullptr;
4547 FoundDeadFn = true;
4548 }
4549 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00004550 }
4551
Johannes Doerfertbf112132019-08-29 01:29:44 +00004552 if (VerifyMaxFixpointIterations &&
4553 IterationCounter != MaxFixpointIterations) {
4554 errs() << "\n[Attributor] Fixpoint iteration done after: "
4555 << IterationCounter << "/" << MaxFixpointIterations
4556 << " iterations\n";
4557 llvm_unreachable("The fixpoint was not reached with exactly the number of "
4558 "specified iterations!");
4559 }
4560
Johannes Doerfertaade7822019-06-05 03:02:24 +00004561 return ManifestChange;
4562}
4563
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004564void Attributor::initializeInformationCache(Function &F) {
4565
4566 // Walk all instructions to find interesting instructions that might be
4567 // queried by abstract attributes during their initialization or update.
4568 // This has to happen before we create attributes.
4569 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
4570 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
4571
4572 for (Instruction &I : instructions(&F)) {
4573 bool IsInterestingOpcode = false;
4574
4575 // To allow easy access to all instructions in a function with a given
4576 // opcode we store them in the InfoCache. As not all opcodes are interesting
4577 // to concrete attributes we only cache the ones that are as identified in
4578 // the following switch.
4579 // Note: There are no concrete attributes now so this is initially empty.
4580 switch (I.getOpcode()) {
4581 default:
4582 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
4583 "New call site/base instruction type needs to be known int the "
4584 "Attributor.");
4585 break;
4586 case Instruction::Load:
4587 // The alignment of a pointer is interesting for loads.
4588 case Instruction::Store:
4589 // The alignment of a pointer is interesting for stores.
4590 case Instruction::Call:
4591 case Instruction::CallBr:
4592 case Instruction::Invoke:
4593 case Instruction::CleanupRet:
4594 case Instruction::CatchSwitch:
4595 case Instruction::Resume:
4596 case Instruction::Ret:
4597 IsInterestingOpcode = true;
4598 }
4599 if (IsInterestingOpcode)
4600 InstOpcodeMap[I.getOpcode()].push_back(&I);
4601 if (I.mayReadOrWriteMemory())
4602 ReadOrWriteInsts.push_back(&I);
4603 }
4604}
4605
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004606void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00004607 if (!VisitedFunctions.insert(&F).second)
4608 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004609
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004610 IRPosition FPos = IRPosition::function(F);
4611
Johannes Doerfert305b9612019-08-04 18:40:01 +00004612 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00004613 // We need dead instruction detection because we do not want to deal with
4614 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004615 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00004616
4617 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004618 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00004619
Stefan Stipanovic53605892019-06-27 11:27:54 +00004620 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004621 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00004622
Stefan Stipanovic06263672019-07-11 21:37:40 +00004623 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004624 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00004625
Hideto Ueno65bbaf92019-07-12 17:38:51 +00004626 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004627 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00004628
Johannes Doerferte83f3032019-08-05 23:22:05 +00004629 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004630 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00004631
Hideto Ueno63f60662019-09-21 15:13:19 +00004632 // Every function might be "no-recurse".
4633 getOrCreateAAFor<AANoRecurse>(FPos);
4634
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004635 // Every function might be "readnone/readonly/writeonly/...".
4636 getOrCreateAAFor<AAMemoryBehavior>(FPos);
4637
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004638 // Every function might be applicable for Heap-To-Stack conversion.
4639 if (EnableHeapToStack)
4640 getOrCreateAAFor<AAHeapToStack>(FPos);
4641
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00004642 // Return attributes are only appropriate if the return type is non void.
4643 Type *ReturnType = F.getReturnType();
4644 if (!ReturnType->isVoidTy()) {
4645 // Argument attribute "returned" --- Create only one per function even
4646 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004647 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00004648
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004649 IRPosition RetPos = IRPosition::returned(F);
4650
4651 // Every function might be simplified.
4652 getOrCreateAAFor<AAValueSimplify>(RetPos);
4653
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004654 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004655
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004656 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004657 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004658
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004659 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004660 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004661
4662 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004663 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004664
4665 // Every function with pointer return type might be marked
4666 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004667 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004668 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004669 }
4670
Hideto Ueno54869ec2019-07-15 06:49:04 +00004671 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004672 IRPosition ArgPos = IRPosition::argument(Arg);
4673
4674 // Every argument might be simplified.
4675 getOrCreateAAFor<AAValueSimplify>(ArgPos);
4676
Hideto Ueno19c07af2019-07-23 08:16:17 +00004677 if (Arg.getType()->isPointerTy()) {
4678 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004679 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004680
Hideto Uenocbab3342019-08-29 05:52:00 +00004681 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004682 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00004683
Hideto Ueno19c07af2019-07-23 08:16:17 +00004684 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004685 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004686
4687 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004688 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004689
4690 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004691 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004692
4693 // Every argument with pointer type might be marked
4694 // "readnone/readonly/writeonly/..."
4695 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004696 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00004697 }
4698
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004699 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004700 CallSite CS(&I);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004701 if (CS.getCalledFunction()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004702 for (int i = 0, e = CS.getCalledFunction()->arg_size(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004703
4704 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
4705
4706 // Call site argument might be simplified.
4707 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
4708
Hideto Ueno54869ec2019-07-15 06:49:04 +00004709 if (!CS.getArgument(i)->getType()->isPointerTy())
4710 continue;
4711
4712 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004713 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004714
Hideto Uenocbab3342019-08-29 05:52:00 +00004715 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004716 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00004717
Hideto Ueno19c07af2019-07-23 08:16:17 +00004718 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004719 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004720
4721 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004722 getOrCreateAAFor<AAAlign>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00004723 }
4724 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004725 return true;
4726 };
4727
4728 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
4729 bool Success, AnyDead = false;
4730 Success = checkForAllInstructionsImpl(
4731 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
4732 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
4733 (unsigned)Instruction::Call});
4734 (void)Success;
4735 assert(Success && !AnyDead && "Expected the check call to be successful!");
4736
4737 auto LoadStorePred = [&](Instruction &I) -> bool {
4738 if (isa<LoadInst>(I))
4739 getOrCreateAAFor<AAAlign>(
4740 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
4741 else
4742 getOrCreateAAFor<AAAlign>(
4743 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
4744 return true;
4745 };
4746 Success = checkForAllInstructionsImpl(
4747 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
4748 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
4749 (void)Success;
4750 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00004751}
4752
4753/// Helpers to ease debugging through output streams and print calls.
4754///
4755///{
4756raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
4757 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
4758}
4759
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004760raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004761 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004762 case IRPosition::IRP_INVALID:
4763 return OS << "inv";
4764 case IRPosition::IRP_FLOAT:
4765 return OS << "flt";
4766 case IRPosition::IRP_RETURNED:
4767 return OS << "fn_ret";
4768 case IRPosition::IRP_CALL_SITE_RETURNED:
4769 return OS << "cs_ret";
4770 case IRPosition::IRP_FUNCTION:
4771 return OS << "fn";
4772 case IRPosition::IRP_CALL_SITE:
4773 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004774 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00004775 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004776 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00004777 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00004778 }
4779 llvm_unreachable("Unknown attribute position!");
4780}
4781
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004782raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004783 const Value &AV = Pos.getAssociatedValue();
4784 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004785 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
4786}
4787
Johannes Doerfertacc80792019-08-12 22:07:34 +00004788raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerState &S) {
4789 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
4790 << static_cast<const AbstractState &>(S);
4791}
4792
Johannes Doerfertaade7822019-06-05 03:02:24 +00004793raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
4794 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
4795}
4796
4797raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
4798 AA.print(OS);
4799 return OS;
4800}
4801
4802void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004803 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
4804 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00004805}
4806///}
4807
4808/// ----------------------------------------------------------------------------
4809/// Pass (Manager) Boilerplate
4810/// ----------------------------------------------------------------------------
4811
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004812static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004813 if (DisableAttributor)
4814 return false;
4815
4816 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
4817 << " functions.\n");
4818
4819 // Create an Attributor and initially empty information cache that is filled
4820 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00004821 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004822 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004823
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004824 for (Function &F : M)
4825 A.initializeInformationCache(F);
4826
Johannes Doerfertaade7822019-06-05 03:02:24 +00004827 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004828 if (F.hasExactDefinition())
4829 NumFnWithExactDefinition++;
4830 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00004831 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004832
4833 // For now we ignore naked and optnone functions.
4834 if (F.hasFnAttribute(Attribute::Naked) ||
4835 F.hasFnAttribute(Attribute::OptimizeNone))
4836 continue;
4837
Johannes Doerfert2f622062019-09-04 16:35:20 +00004838 // We look at internal functions only on-demand but if any use is not a
4839 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004840 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00004841 if (llvm::all_of(F.uses(), [](const Use &U) {
4842 return ImmutableCallSite(U.getUser()) &&
4843 ImmutableCallSite(U.getUser()).isCallee(&U);
4844 }))
4845 continue;
4846 }
4847
Johannes Doerfertaade7822019-06-05 03:02:24 +00004848 // Populate the Attributor with abstract attribute opportunities in the
4849 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004850 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004851 }
4852
Johannes Doerfert2f622062019-09-04 16:35:20 +00004853 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004854}
4855
4856PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00004857 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004858 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004859 // FIXME: Think about passes we will preserve and add them here.
4860 return PreservedAnalyses::none();
4861 }
4862 return PreservedAnalyses::all();
4863}
4864
4865namespace {
4866
4867struct AttributorLegacyPass : public ModulePass {
4868 static char ID;
4869
4870 AttributorLegacyPass() : ModulePass(ID) {
4871 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
4872 }
4873
4874 bool runOnModule(Module &M) override {
4875 if (skipModule(M))
4876 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004877
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004878 AnalysisGetter AG;
4879 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004880 }
4881
4882 void getAnalysisUsage(AnalysisUsage &AU) const override {
4883 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004884 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004885 }
4886};
4887
4888} // end anonymous namespace
4889
4890Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
4891
4892char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004893
4894const char AAReturnedValues::ID = 0;
4895const char AANoUnwind::ID = 0;
4896const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00004897const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004898const char AANonNull::ID = 0;
4899const char AANoRecurse::ID = 0;
4900const char AAWillReturn::ID = 0;
4901const char AANoAlias::ID = 0;
4902const char AANoReturn::ID = 0;
4903const char AAIsDead::ID = 0;
4904const char AADereferenceable::ID = 0;
4905const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004906const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004907const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004908const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004909const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004910
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004911// Macro magic to create the static generator function for attributes that
4912// follow the naming scheme.
4913
4914#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
4915 case IRPosition::PK: \
4916 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
4917
4918#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
4919 case IRPosition::PK: \
4920 AA = new CLASS##SUFFIX(IRP); \
4921 break;
4922
4923#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4924 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4925 CLASS *AA = nullptr; \
4926 switch (IRP.getPositionKind()) { \
4927 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4928 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
4929 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
4930 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
4931 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
4932 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
4933 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4934 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4935 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004936 return *AA; \
4937 }
4938
4939#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4940 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4941 CLASS *AA = nullptr; \
4942 switch (IRP.getPositionKind()) { \
4943 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4944 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
4945 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
4946 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4947 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4948 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
4949 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4950 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4951 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004952 return *AA; \
4953 }
4954
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004955#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4956 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4957 CLASS *AA = nullptr; \
4958 switch (IRP.getPositionKind()) { \
4959 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4960 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4961 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4962 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4963 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4964 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
4965 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4966 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4967 } \
4968 return *AA; \
4969 }
4970
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004971#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4972 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4973 CLASS *AA = nullptr; \
4974 switch (IRP.getPositionKind()) { \
4975 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4976 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
4977 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
4978 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
4979 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
4980 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
4981 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
4982 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4983 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004984 return *AA; \
4985 }
4986
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004987#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4988 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4989 CLASS *AA = nullptr; \
4990 switch (IRP.getPositionKind()) { \
4991 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4992 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
4993 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4994 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4995 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4996 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4997 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4998 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4999 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005000 return *AA; \
5001 }
5002
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005003CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
5004CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
5005CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
5006CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
5007CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
5008CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
5009CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
5010CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
5011
5012CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
5013CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
5014CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
5015CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005016CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005017
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005018CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
5019
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005020CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
5021
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005022CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
5023
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005024#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005025#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005026#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005027#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005028#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005029#undef SWITCH_PK_CREATE
5030#undef SWITCH_PK_INV
5031
Johannes Doerfertaade7822019-06-05 03:02:24 +00005032INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
5033 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005034INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00005035INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
5036 "Deduce and propagate attributes", false, false)