blob: ef6c82c00c894e70d29c7befe26fcd2b9b596d03 [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
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000142static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
143 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000144
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)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000715/// U - Underlying use.
716/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000717/// `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) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +00001000 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +00001001 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);
Johannes Doerfert72adda12019-10-10 05:33:21 +00001910 Value &Val = getAssociatedValue();
1911 if (isa<AllocaInst>(Val))
1912 indicateOptimisticFixpoint();
1913 if (isa<ConstantPointerNull>(Val) &&
1914 Val.getType()->getPointerAddressSpace() == 0)
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001915 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001916 }
1917
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001918 /// See AbstractAttribute::updateImpl(...).
1919 ChangeStatus updateImpl(Attributor &A) override {
1920 // TODO: Implement this.
1921 return indicatePessimisticFixpoint();
1922 }
1923
1924 /// See AbstractAttribute::trackStatistics()
1925 void trackStatistics() const override {
1926 STATS_DECLTRACK_FLOATING_ATTR(noalias)
1927 }
1928};
1929
1930/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00001931struct AANoAliasArgument final
1932 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
1933 AANoAliasArgument(const IRPosition &IRP)
1934 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>(IRP) {}
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001935
1936 /// See AbstractAttribute::trackStatistics()
1937 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
1938};
1939
1940struct AANoAliasCallSiteArgument final : AANoAliasImpl {
1941 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
1942
Hideto Uenocbab3342019-08-29 05:52:00 +00001943 /// See AbstractAttribute::initialize(...).
1944 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00001945 // See callsite argument attribute and callee argument attribute.
1946 ImmutableCallSite ICS(&getAnchorValue());
1947 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
1948 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00001949 }
1950
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001951 /// See AbstractAttribute::updateImpl(...).
1952 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001953 // We can deduce "noalias" if the following conditions hold.
1954 // (i) Associated value is assumed to be noalias in the definition.
1955 // (ii) Associated value is assumed to be no-capture in all the uses
1956 // possibly executed before this callsite.
1957 // (iii) There is no other pointer argument which could alias with the
1958 // value.
1959
1960 const Value &V = getAssociatedValue();
1961 const IRPosition IRP = IRPosition::value(V);
1962
1963 // (i) Check whether noalias holds in the definition.
1964
1965 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
1966
1967 if (!NoAliasAA.isAssumedNoAlias())
1968 return indicatePessimisticFixpoint();
1969
1970 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
1971 << " is assumed NoAlias in the definition\n");
1972
1973 // (ii) Check whether the value is captured in the scope using AANoCapture.
1974 // FIXME: This is conservative though, it is better to look at CFG and
1975 // check only uses possibly executed before this callsite.
1976
1977 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert72adda12019-10-10 05:33:21 +00001978 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
1979 LLVM_DEBUG(
1980 dbgs() << "[Attributor][AANoAliasCSArg] " << V
1981 << " cannot be noalias as it is potentially captured\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001982 return indicatePessimisticFixpoint();
Johannes Doerfert72adda12019-10-10 05:33:21 +00001983 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00001984
1985 // (iii) Check there is no other pointer argument which could alias with the
1986 // value.
1987 ImmutableCallSite ICS(&getAnchorValue());
1988 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
1989 if (getArgNo() == (int)i)
1990 continue;
1991 const Value *ArgOp = ICS.getArgOperand(i);
1992 if (!ArgOp->getType()->isPointerTy())
1993 continue;
1994
Hideto Ueno30d86f12019-09-17 06:53:27 +00001995 if (const Function *F = getAnchorScope()) {
1996 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
Johannes Doerfert72adda12019-10-10 05:33:21 +00001997 bool IsAliasing = AAR->isNoAlias(&getAssociatedValue(), ArgOp);
Hideto Ueno30d86f12019-09-17 06:53:27 +00001998 LLVM_DEBUG(dbgs()
1999 << "[Attributor][NoAliasCSArg] Check alias between "
2000 "callsite arguments "
2001 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
Johannes Doerfert72adda12019-10-10 05:33:21 +00002002 << getAssociatedValue() << " " << *ArgOp << " => "
2003 << (IsAliasing ? "" : "no-") << "alias \n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002004
Johannes Doerfert72adda12019-10-10 05:33:21 +00002005 if (IsAliasing)
Hideto Ueno30d86f12019-09-17 06:53:27 +00002006 continue;
2007 }
2008 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002009 return indicatePessimisticFixpoint();
2010 }
2011
2012 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002013 }
2014
2015 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002016 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002017};
2018
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002019/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002020struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002021 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002022
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002023 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002024 virtual ChangeStatus updateImpl(Attributor &A) override {
2025
2026 auto CheckReturnValue = [&](Value &RV) -> bool {
2027 if (Constant *C = dyn_cast<Constant>(&RV))
2028 if (C->isNullValue() || isa<UndefValue>(C))
2029 return true;
2030
2031 /// For now, we can only deduce noalias if we have call sites.
2032 /// FIXME: add more support.
2033 ImmutableCallSite ICS(&RV);
2034 if (!ICS)
2035 return false;
2036
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002037 const IRPosition &RVPos = IRPosition::value(RV);
2038 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002039 if (!NoAliasAA.isAssumedNoAlias())
2040 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002041
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002042 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2043 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002044 };
2045
2046 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2047 return indicatePessimisticFixpoint();
2048
2049 return ChangeStatus::UNCHANGED;
2050 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002051
2052 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002053 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002054};
2055
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002056/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002057struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2058 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2059
2060 /// See AbstractAttribute::initialize(...).
2061 void initialize(Attributor &A) override {
2062 AANoAliasImpl::initialize(A);
2063 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002064 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002065 indicatePessimisticFixpoint();
2066 }
2067
2068 /// See AbstractAttribute::updateImpl(...).
2069 ChangeStatus updateImpl(Attributor &A) override {
2070 // TODO: Once we have call site specific value information we can provide
2071 // call site specific liveness information and then it makes
2072 // sense to specialize attributes for call sites arguments instead of
2073 // redirecting requests to the callee argument.
2074 Function *F = getAssociatedFunction();
2075 const IRPosition &FnPos = IRPosition::returned(*F);
2076 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2077 return clampStateAndIndicateChange(
2078 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2079 }
2080
2081 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002082 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002083};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002084
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002085/// -------------------AAIsDead Function Attribute-----------------------
2086
Johannes Doerfert344d0382019-08-07 22:34:26 +00002087struct AAIsDeadImpl : public AAIsDead {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002088 AAIsDeadImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002089
Johannes Doerfertece81902019-08-12 22:05:53 +00002090 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002091 const Function *F = getAssociatedFunction();
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002092 if (F && !F->isDeclaration())
2093 exploreFromEntry(A, F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002094 }
2095
2096 void exploreFromEntry(Attributor &A, const Function *F) {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002097 ToBeExploredPaths.insert(&(F->getEntryBlock().front()));
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002098
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002099 for (size_t i = 0; i < ToBeExploredPaths.size(); ++i)
Johannes Doerfert4361da22019-08-04 18:38:53 +00002100 if (const Instruction *NextNoReturnI =
2101 findNextNoReturn(A, ToBeExploredPaths[i]))
2102 NoReturnCalls.insert(NextNoReturnI);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00002103
2104 // Mark the block live after we looked for no-return instructions.
2105 assumeLive(A, F->getEntryBlock());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002106 }
2107
Johannes Doerfert4361da22019-08-04 18:38:53 +00002108 /// Find the next assumed noreturn instruction in the block of \p I starting
2109 /// from, thus including, \p I.
2110 ///
2111 /// The caller is responsible to monitor the ToBeExploredPaths set as new
2112 /// instructions discovered in other basic block will be placed in there.
2113 ///
2114 /// \returns The next assumed noreturn instructions in the block of \p I
2115 /// starting from, thus including, \p I.
2116 const Instruction *findNextNoReturn(Attributor &A, const Instruction *I);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002117
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002118 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002119 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002120 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002121 std::to_string(getAssociatedFunction()->size()) + "][#NRI " +
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002122 std::to_string(NoReturnCalls.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002123 }
2124
2125 /// See AbstractAttribute::manifest(...).
2126 ChangeStatus manifest(Attributor &A) override {
2127 assert(getState().isValidState() &&
2128 "Attempted to manifest an invalid state!");
2129
2130 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002131 Function &F = *getAssociatedFunction();
2132
2133 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002134 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002135 return ChangeStatus::CHANGED;
2136 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002137
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002138 // Flag to determine if we can change an invoke to a call assuming the
2139 // callee is nounwind. This is not possible if the personality of the
2140 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002141 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002142
Johannes Doerfert4361da22019-08-04 18:38:53 +00002143 for (const Instruction *NRC : NoReturnCalls) {
2144 Instruction *I = const_cast<Instruction *>(NRC);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002145 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002146 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00002147 // TODO: mark stuff before unreachable instructions as dead.
2148 if (isa_and_nonnull<UnreachableInst>(SplitPos))
2149 continue;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002150
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002151 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002152 // If we keep the invoke the split position is at the beginning of the
2153 // normal desitination block (it invokes a noreturn function after all).
2154 BasicBlock *NormalDestBB = II->getNormalDest();
2155 SplitPos = &NormalDestBB->front();
2156
Johannes Doerfert4361da22019-08-04 18:38:53 +00002157 /// Invoke is replaced with a call and unreachable is placed after it if
2158 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
2159 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002160 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00002161 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002162 const IRPosition &IPos = IRPosition::callsite_function(*II);
2163 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2164 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00002165 LLVM_DEBUG(dbgs()
2166 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002167 // We do not need an invoke (II) but instead want a call followed
2168 // by an unreachable. However, we do not remove II as other
2169 // abstract attributes might have it cached as part of their
2170 // results. Given that we modify the CFG anyway, we simply keep II
2171 // around but in a new dead block. To avoid II being live through
2172 // a different edge we have to ensure the block we place it in is
2173 // only reached from the current block of II and then not reached
2174 // at all when we insert the unreachable.
2175 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
2176 CallInst *CI = createCallMatchingInvoke(II);
2177 CI->insertBefore(II);
2178 CI->takeName(II);
2179 II->replaceAllUsesWith(CI);
2180 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002181 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002182 }
2183 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002184
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002185 if (SplitPos == &NormalDestBB->front()) {
2186 // If this is an invoke of a noreturn function the edge to the normal
2187 // destination block is dead but not necessarily the block itself.
2188 // TODO: We need to move to an edge based system during deduction and
2189 // also manifest.
2190 assert(!NormalDestBB->isLandingPad() &&
2191 "Expected the normal destination not to be a landingpad!");
2192 BasicBlock *SplitBB =
2193 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2194 // The split block is live even if it contains only an unreachable
2195 // instruction at the end.
2196 assumeLive(A, *SplitBB);
2197 SplitPos = SplitBB->getTerminator();
2198 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002199 }
2200
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002201 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002202 SplitBlock(BB, SplitPos);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002203 changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
2204 HasChanged = ChangeStatus::CHANGED;
2205 }
2206
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002207 for (BasicBlock &BB : F)
2208 if (!AssumedLiveBlocks.count(&BB))
2209 A.deleteAfterManifest(BB);
2210
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002211 return HasChanged;
2212 }
2213
2214 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002215 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002216
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002217 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002218 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002219 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002220 "BB must be in the same anchor scope function.");
2221
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002222 if (!getAssumed())
2223 return false;
2224 return !AssumedLiveBlocks.count(BB);
2225 }
2226
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002227 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002228 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002229 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002230 }
2231
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002232 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002233 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002234 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002235 "Instruction must be in the same anchor scope function.");
2236
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002237 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002238 return false;
2239
2240 // If it is not in AssumedLiveBlocks then it for sure dead.
2241 // Otherwise, it can still be after noreturn call in a live block.
2242 if (!AssumedLiveBlocks.count(I->getParent()))
2243 return true;
2244
2245 // If it is not after a noreturn call, than it is live.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002246 return isAfterNoReturn(I);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002247 }
2248
2249 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002250 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002251 return getKnown() && isAssumedDead(I);
2252 }
2253
2254 /// Check if instruction is after noreturn call, in other words, assumed dead.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002255 bool isAfterNoReturn(const Instruction *I) const;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002256
Johannes Doerfert924d2132019-08-05 21:34:45 +00002257 /// Determine if \p F might catch asynchronous exceptions.
2258 static bool mayCatchAsynchronousExceptions(const Function &F) {
2259 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2260 }
2261
Johannes Doerfert2f622062019-09-04 16:35:20 +00002262 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2263 /// that internal function called from \p BB should now be looked at.
2264 void assumeLive(Attributor &A, const BasicBlock &BB) {
2265 if (!AssumedLiveBlocks.insert(&BB).second)
2266 return;
2267
2268 // We assume that all of BB is (probably) live now and if there are calls to
2269 // internal functions we will assume that those are now live as well. This
2270 // is a performance optimization for blocks with calls to a lot of internal
2271 // functions. It can however cause dead functions to be treated as live.
2272 for (const Instruction &I : BB)
2273 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2274 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00002275 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00002276 A.markLiveInternalFunction(*F);
2277 }
2278
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002279 /// Collection of to be explored paths.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002280 SmallSetVector<const Instruction *, 8> ToBeExploredPaths;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002281
2282 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002283 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002284
2285 /// Collection of calls with noreturn attribute, assumed or knwon.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002286 SmallSetVector<const Instruction *, 4> NoReturnCalls;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002287};
2288
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002289struct AAIsDeadFunction final : public AAIsDeadImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002290 AAIsDeadFunction(const IRPosition &IRP) : AAIsDeadImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002291
2292 /// See AbstractAttribute::trackStatistics()
2293 void trackStatistics() const override {
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002294 STATS_DECL(PartiallyDeadBlocks, Function,
2295 "Number of basic blocks classified as partially dead");
2296 BUILD_STAT_NAME(PartiallyDeadBlocks, Function) += NoReturnCalls.size();
2297 }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002298};
2299
2300bool AAIsDeadImpl::isAfterNoReturn(const Instruction *I) const {
Johannes Doerfert4361da22019-08-04 18:38:53 +00002301 const Instruction *PrevI = I->getPrevNode();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002302 while (PrevI) {
2303 if (NoReturnCalls.count(PrevI))
2304 return true;
2305 PrevI = PrevI->getPrevNode();
2306 }
2307 return false;
2308}
2309
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002310const Instruction *AAIsDeadImpl::findNextNoReturn(Attributor &A,
2311 const Instruction *I) {
Johannes Doerfert4361da22019-08-04 18:38:53 +00002312 const BasicBlock *BB = I->getParent();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002313 const Function &F = *BB->getParent();
2314
2315 // Flag to determine if we can change an invoke to a call assuming the callee
2316 // is nounwind. This is not possible if the personality of the function allows
2317 // to catch asynchronous exceptions.
2318 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002319
2320 // TODO: We should have a function that determines if an "edge" is dead.
2321 // Edges could be from an instruction to the next or from a terminator
2322 // to the successor. For now, we need to special case the unwind block
2323 // of InvokeInst below.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002324
2325 while (I) {
2326 ImmutableCallSite ICS(I);
2327
2328 if (ICS) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002329 const IRPosition &IPos = IRPosition::callsite_function(ICS);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002330 // Regarless of the no-return property of an invoke instruction we only
2331 // learn that the regular successor is not reachable through this
2332 // instruction but the unwind block might still be.
2333 if (auto *Invoke = dyn_cast<InvokeInst>(I)) {
2334 // Use nounwind to justify the unwind block is dead as well.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002335 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2336 if (!Invoke2CallAllowed || !AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002337 assumeLive(A, *Invoke->getUnwindDest());
Johannes Doerfert4361da22019-08-04 18:38:53 +00002338 ToBeExploredPaths.insert(&Invoke->getUnwindDest()->front());
2339 }
2340 }
2341
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002342 const auto &NoReturnAA = A.getAAFor<AANoReturn>(*this, IPos);
2343 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert4361da22019-08-04 18:38:53 +00002344 return I;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002345 }
2346
2347 I = I->getNextNode();
2348 }
2349
2350 // get new paths (reachable blocks).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002351 for (const BasicBlock *SuccBB : successors(BB)) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002352 assumeLive(A, *SuccBB);
Johannes Doerfert4361da22019-08-04 18:38:53 +00002353 ToBeExploredPaths.insert(&SuccBB->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002354 }
2355
Johannes Doerfert4361da22019-08-04 18:38:53 +00002356 // No noreturn instruction found.
2357 return nullptr;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002358}
2359
Johannes Doerfertece81902019-08-12 22:05:53 +00002360ChangeStatus AAIsDeadImpl::updateImpl(Attributor &A) {
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002361 ChangeStatus Status = ChangeStatus::UNCHANGED;
2362
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002363 // Temporary collection to iterate over existing noreturn instructions. This
2364 // will alow easier modification of NoReturnCalls collection
Johannes Doerfert4361da22019-08-04 18:38:53 +00002365 SmallVector<const Instruction *, 8> NoReturnChanged;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002366
Johannes Doerfert4361da22019-08-04 18:38:53 +00002367 for (const Instruction *I : NoReturnCalls)
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002368 NoReturnChanged.push_back(I);
2369
Johannes Doerfert4361da22019-08-04 18:38:53 +00002370 for (const Instruction *I : NoReturnChanged) {
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002371 size_t Size = ToBeExploredPaths.size();
2372
Johannes Doerfert4361da22019-08-04 18:38:53 +00002373 const Instruction *NextNoReturnI = findNextNoReturn(A, I);
2374 if (NextNoReturnI != I) {
2375 Status = ChangeStatus::CHANGED;
2376 NoReturnCalls.remove(I);
2377 if (NextNoReturnI)
2378 NoReturnCalls.insert(NextNoReturnI);
2379 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002380
Johannes Doerfert4361da22019-08-04 18:38:53 +00002381 // Explore new paths.
2382 while (Size != ToBeExploredPaths.size()) {
2383 Status = ChangeStatus::CHANGED;
2384 if (const Instruction *NextNoReturnI =
2385 findNextNoReturn(A, ToBeExploredPaths[Size++]))
2386 NoReturnCalls.insert(NextNoReturnI);
2387 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002388 }
2389
Johannes Doerfertdef99282019-08-14 21:29:37 +00002390 LLVM_DEBUG(dbgs() << "[AAIsDead] AssumedLiveBlocks: "
2391 << AssumedLiveBlocks.size() << " Total number of blocks: "
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002392 << getAssociatedFunction()->size() << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002393
Johannes Doerfertd6207812019-08-07 22:32:38 +00002394 // If we know everything is live there is no need to query for liveness.
2395 if (NoReturnCalls.empty() &&
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002396 getAssociatedFunction()->size() == AssumedLiveBlocks.size()) {
Johannes Doerfertd6207812019-08-07 22:32:38 +00002397 // Indicating a pessimistic fixpoint will cause the state to be "invalid"
2398 // which will cause the Attributor to not return the AAIsDead on request,
2399 // which will prevent us from querying isAssumedDead().
2400 indicatePessimisticFixpoint();
2401 assert(!isValidState() && "Expected an invalid state!");
Johannes Doerfert62a9c1d2019-08-29 01:26:58 +00002402 Status = ChangeStatus::CHANGED;
Johannes Doerfertd6207812019-08-07 22:32:38 +00002403 }
2404
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002405 return Status;
2406}
2407
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002408/// Liveness information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002409struct AAIsDeadCallSite final : AAIsDeadImpl {
2410 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadImpl(IRP) {}
2411
2412 /// See AbstractAttribute::initialize(...).
2413 void initialize(Attributor &A) override {
2414 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002415 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00002416 // sense to specialize attributes for call sites instead of
2417 // redirecting requests to the callee.
2418 llvm_unreachable("Abstract attributes for liveness are not "
2419 "supported for call sites yet!");
2420 }
2421
2422 /// See AbstractAttribute::updateImpl(...).
2423 ChangeStatus updateImpl(Attributor &A) override {
2424 return indicatePessimisticFixpoint();
2425 }
2426
2427 /// See AbstractAttribute::trackStatistics()
2428 void trackStatistics() const override {}
2429};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002430
Hideto Ueno19c07af2019-07-23 08:16:17 +00002431/// -------------------- Dereferenceable Argument Attribute --------------------
2432
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002433template <>
2434ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
2435 const DerefState &R) {
2436 ChangeStatus CS0 = clampStateAndIndicateChange<IntegerState>(
2437 S.DerefBytesState, R.DerefBytesState);
2438 ChangeStatus CS1 =
2439 clampStateAndIndicateChange<IntegerState>(S.GlobalState, R.GlobalState);
2440 return CS0 | CS1;
2441}
2442
Hideto Ueno70576ca2019-08-22 14:18:29 +00002443struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002444 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00002445 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002446
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002447 void initialize(Attributor &A) override {
2448 SmallVector<Attribute, 4> Attrs;
2449 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
2450 Attrs);
2451 for (const Attribute &Attr : Attrs)
2452 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
2453
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002454 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002455
2456 const IRPosition &IRP = this->getIRPosition();
2457 bool IsFnInterface = IRP.isFnInterfaceKind();
2458 const Function *FnScope = IRP.getAnchorScope();
2459 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
2460 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00002461 }
2462
Hideto Ueno19c07af2019-07-23 08:16:17 +00002463 /// See AbstractAttribute::getState()
2464 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00002465 StateType &getState() override { return *this; }
2466 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002467 /// }
2468
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002469 /// See AAFromMustBeExecutedContext
2470 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
2471 bool IsNonNull = false;
2472 bool TrackUse = false;
2473 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
2474 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
2475 takeKnownDerefBytesMaximum(DerefBytes);
2476 return TrackUse;
2477 }
2478
Johannes Doerferteccdf082019-08-05 23:35:12 +00002479 void getDeducedAttributes(LLVMContext &Ctx,
2480 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002481 // TODO: Add *_globally support
2482 if (isAssumedNonNull())
2483 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
2484 Ctx, getAssumedDereferenceableBytes()));
2485 else
2486 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
2487 Ctx, getAssumedDereferenceableBytes()));
2488 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002489
2490 /// See AbstractAttribute::getAsStr().
2491 const std::string getAsStr() const override {
2492 if (!getAssumedDereferenceableBytes())
2493 return "unknown-dereferenceable";
2494 return std::string("dereferenceable") +
2495 (isAssumedNonNull() ? "" : "_or_null") +
2496 (isAssumedGlobal() ? "_globally" : "") + "<" +
2497 std::to_string(getKnownDereferenceableBytes()) + "-" +
2498 std::to_string(getAssumedDereferenceableBytes()) + ">";
2499 }
2500};
2501
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002502/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002503struct AADereferenceableFloating
2504 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
2505 using Base =
2506 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
2507 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00002508
2509 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002510 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002511 ChangeStatus Change = Base::updateImpl(A);
2512
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002513 const DataLayout &DL = A.getDataLayout();
2514
2515 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
2516 unsigned IdxWidth =
2517 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
2518 APInt Offset(IdxWidth, 0);
2519 const Value *Base =
2520 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
2521
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002522 const auto &AA =
2523 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002524 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002525 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002526 // Use IR information if we did not strip anything.
2527 // TODO: track globally.
2528 bool CanBeNull;
2529 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
2530 T.GlobalState.indicatePessimisticFixpoint();
2531 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002532 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002533 DerefBytes = DS.DerefBytesState.getAssumed();
2534 T.GlobalState &= DS.GlobalState;
2535 }
2536
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002537 // For now we do not try to "increase" dereferenceability due to negative
2538 // indices as we first have to come up with code to deal with loops and
2539 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00002540 int64_t OffsetSExt = Offset.getSExtValue();
2541 if (OffsetSExt < 0)
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00002542 Offset = 0;
2543
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002544 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00002545 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002546
Johannes Doerfert785fad32019-08-23 17:29:23 +00002547 if (this == &AA) {
2548 if (!Stripped) {
2549 // If nothing was stripped IR information is all we got.
2550 T.takeKnownDerefBytesMaximum(
2551 std::max(int64_t(0), DerefBytes - OffsetSExt));
2552 T.indicatePessimisticFixpoint();
2553 } else if (OffsetSExt > 0) {
2554 // If something was stripped but there is circular reasoning we look
2555 // for the offset. If it is positive we basically decrease the
2556 // dereferenceable bytes in a circluar loop now, which will simply
2557 // drive them down to the known value in a very slow way which we
2558 // can accelerate.
2559 T.indicatePessimisticFixpoint();
2560 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002561 }
2562
2563 return T.isValidState();
2564 };
2565
2566 DerefState T;
2567 if (!genericValueTraversal<AADereferenceable, DerefState>(
2568 A, getIRPosition(), *this, T, VisitValueCB))
2569 return indicatePessimisticFixpoint();
2570
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002571 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002572 }
2573
2574 /// See AbstractAttribute::trackStatistics()
2575 void trackStatistics() const override {
2576 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
2577 }
2578};
2579
2580/// Dereferenceable attribute for a return value.
2581struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002582 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2583 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002584 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002585 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
2586 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002587
2588 /// See AbstractAttribute::trackStatistics()
2589 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002590 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002591 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002592};
2593
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002594/// Dereferenceable attribute for an argument
2595struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002596 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2597 AADereferenceable, AADereferenceableImpl, DerefState> {
2598 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
2599 AADereferenceable, AADereferenceableImpl, DerefState>;
2600 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002601
2602 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002603 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00002604 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
2605 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002606};
2607
Hideto Ueno19c07af2019-07-23 08:16:17 +00002608/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002609struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002610 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002611 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002612
2613 /// See AbstractAttribute::trackStatistics()
2614 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002615 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002616 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00002617};
2618
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002619/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002620struct AADereferenceableCallSiteReturned final
2621 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2622 AADereferenceable, AADereferenceableImpl> {
2623 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
2624 AADereferenceable, AADereferenceableImpl>;
2625 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002626
2627 /// See AbstractAttribute::initialize(...).
2628 void initialize(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002629 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002630 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002631 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002632 indicatePessimisticFixpoint();
2633 }
2634
2635 /// See AbstractAttribute::updateImpl(...).
2636 ChangeStatus updateImpl(Attributor &A) override {
2637 // TODO: Once we have call site specific value information we can provide
2638 // call site specific liveness information and then it makes
2639 // sense to specialize attributes for call sites arguments instead of
2640 // redirecting requests to the callee argument.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002641
2642 ChangeStatus Change = Base::updateImpl(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002643 Function *F = getAssociatedFunction();
2644 const IRPosition &FnPos = IRPosition::returned(*F);
2645 auto &FnAA = A.getAAFor<AADereferenceable>(*this, FnPos);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002646 return Change |
2647 clampStateAndIndicateChange(
2648 getState(), static_cast<const DerefState &>(FnAA.getState()));
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002649 }
2650
2651 /// See AbstractAttribute::trackStatistics()
2652 void trackStatistics() const override {
2653 STATS_DECLTRACK_CS_ATTR(dereferenceable);
2654 }
2655};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002656
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002657// ------------------------ Align Argument Attribute ------------------------
2658
Johannes Doerfert344d0382019-08-07 22:34:26 +00002659struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002660 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002661
2662 // Max alignemnt value allowed in IR
2663 static const unsigned MAX_ALIGN = 1U << 29;
2664
Johannes Doerfert234eda52019-08-16 19:51:23 +00002665 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002666 void initialize(Attributor &A) override {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002667 takeAssumedMinimum(MAX_ALIGN);
2668
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002669 SmallVector<Attribute, 4> Attrs;
2670 getAttrs({Attribute::Alignment}, Attrs);
2671 for (const Attribute &Attr : Attrs)
2672 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00002673
2674 if (getIRPosition().isFnInterfaceKind() &&
2675 (!getAssociatedFunction() ||
2676 !getAssociatedFunction()->hasExactDefinition()))
2677 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002678 }
2679
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002680 /// See AbstractAttribute::manifest(...).
2681 ChangeStatus manifest(Attributor &A) override {
2682 ChangeStatus Changed = ChangeStatus::UNCHANGED;
2683
2684 // Check for users that allow alignment annotations.
2685 Value &AnchorVal = getIRPosition().getAnchorValue();
2686 for (const Use &U : AnchorVal.uses()) {
2687 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
2688 if (SI->getPointerOperand() == &AnchorVal)
2689 if (SI->getAlignment() < getAssumedAlign()) {
2690 STATS_DECLTRACK(AAAlign, Store,
2691 "Number of times alignemnt added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00002692 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002693 Changed = ChangeStatus::CHANGED;
2694 }
2695 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
2696 if (LI->getPointerOperand() == &AnchorVal)
2697 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00002698 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002699 STATS_DECLTRACK(AAAlign, Load,
2700 "Number of times alignemnt added to a load");
2701 Changed = ChangeStatus::CHANGED;
2702 }
2703 }
2704 }
2705
Johannes Doerfert81df4522019-08-30 15:22:28 +00002706 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002707 }
2708
Johannes Doerfert81df4522019-08-30 15:22:28 +00002709 // TODO: Provide a helper to determine the implied ABI alignment and check in
2710 // the existing manifest method and a new one for AAAlignImpl that value
2711 // to avoid making the alignment explicit if it did not improve.
2712
2713 /// See AbstractAttribute::getDeducedAttributes
2714 virtual void
2715 getDeducedAttributes(LLVMContext &Ctx,
2716 SmallVectorImpl<Attribute> &Attrs) const override {
2717 if (getAssumedAlign() > 1)
2718 Attrs.emplace_back(Attribute::getWithAlignment(Ctx, getAssumedAlign()));
2719 }
2720
2721 /// See AbstractAttribute::getAsStr().
2722 const std::string getAsStr() const override {
2723 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
2724 "-" + std::to_string(getAssumedAlign()) + ">")
2725 : "unknown-align";
2726 }
2727};
2728
2729/// Align attribute for a floating value.
2730struct AAAlignFloating : AAAlignImpl {
2731 AAAlignFloating(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2732
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002733 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00002734 ChangeStatus updateImpl(Attributor &A) override {
2735 const DataLayout &DL = A.getDataLayout();
2736
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002737 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
2738 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002739 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
2740 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002741 // Use only IR information if we did not strip anything.
2742 T.takeKnownMaximum(V.getPointerAlignment(DL));
2743 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002744 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002745 // Use abstract attribute information.
2746 const AAAlign::StateType &DS =
2747 static_cast<const AAAlign::StateType &>(AA.getState());
2748 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00002749 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002750 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002751 };
2752
2753 StateType T;
2754 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
2755 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00002756 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00002757
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00002758 // TODO: If we know we visited all incoming values, thus no are assumed
2759 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00002760 return clampStateAndIndicateChange(getState(), T);
2761 }
2762
2763 /// See AbstractAttribute::trackStatistics()
2764 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
2765};
2766
2767/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002768struct AAAlignReturned final
2769 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002770 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002771 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002772
2773 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002774 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002775};
2776
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002777/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002778struct AAAlignArgument final
2779 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00002780 AAAlignArgument(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002781 : AAArgumentFromCallSiteArguments<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002782
2783 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00002784 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002785};
2786
Johannes Doerfert234eda52019-08-16 19:51:23 +00002787struct AAAlignCallSiteArgument final : AAAlignFloating {
2788 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002789
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00002790 /// See AbstractAttribute::manifest(...).
2791 ChangeStatus manifest(Attributor &A) override {
2792 return AAAlignImpl::manifest(A);
2793 }
2794
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002795 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002796 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002797};
2798
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002799/// Align attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002800struct AAAlignCallSiteReturned final : AAAlignImpl {
2801 AAAlignCallSiteReturned(const IRPosition &IRP) : AAAlignImpl(IRP) {}
2802
2803 /// See AbstractAttribute::initialize(...).
2804 void initialize(Attributor &A) override {
2805 AAAlignImpl::initialize(A);
2806 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002807 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002808 indicatePessimisticFixpoint();
2809 }
2810
2811 /// See AbstractAttribute::updateImpl(...).
2812 ChangeStatus updateImpl(Attributor &A) override {
2813 // TODO: Once we have call site specific value information we can provide
2814 // call site specific liveness information and then it makes
2815 // sense to specialize attributes for call sites arguments instead of
2816 // redirecting requests to the callee argument.
2817 Function *F = getAssociatedFunction();
2818 const IRPosition &FnPos = IRPosition::returned(*F);
2819 auto &FnAA = A.getAAFor<AAAlign>(*this, FnPos);
2820 return clampStateAndIndicateChange(
2821 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
2822 }
2823
2824 /// See AbstractAttribute::trackStatistics()
2825 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
2826};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002827
Johannes Doerferte83f3032019-08-05 23:22:05 +00002828/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00002829struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002830 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00002831
Johannes Doerferte83f3032019-08-05 23:22:05 +00002832 /// See AbstractAttribute::getAsStr().
2833 const std::string getAsStr() const override {
2834 return getAssumed() ? "noreturn" : "may-return";
2835 }
2836
Johannes Doerferte83f3032019-08-05 23:22:05 +00002837 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00002838 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00002839 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002840 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00002841 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00002842 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00002843 return ChangeStatus::UNCHANGED;
2844 }
2845};
2846
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002847struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002848 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002849
2850 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002851 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00002852};
2853
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002854/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002855struct AANoReturnCallSite final : AANoReturnImpl {
2856 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
2857
2858 /// See AbstractAttribute::initialize(...).
2859 void initialize(Attributor &A) override {
2860 AANoReturnImpl::initialize(A);
2861 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002862 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002863 indicatePessimisticFixpoint();
2864 }
2865
2866 /// See AbstractAttribute::updateImpl(...).
2867 ChangeStatus updateImpl(Attributor &A) override {
2868 // TODO: Once we have call site specific value information we can provide
2869 // call site specific liveness information and then it makes
2870 // sense to specialize attributes for call sites arguments instead of
2871 // redirecting requests to the callee argument.
2872 Function *F = getAssociatedFunction();
2873 const IRPosition &FnPos = IRPosition::function(*F);
2874 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
2875 return clampStateAndIndicateChange(
2876 getState(),
2877 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
2878 }
2879
2880 /// See AbstractAttribute::trackStatistics()
2881 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
2882};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002883
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002884/// ----------------------- Variable Capturing ---------------------------------
2885
2886/// A class to hold the state of for no-capture attributes.
2887struct AANoCaptureImpl : public AANoCapture {
2888 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
2889
2890 /// See AbstractAttribute::initialize(...).
2891 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002892 AANoCapture::initialize(A);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002893
Johannes Doerfert72adda12019-10-10 05:33:21 +00002894 // You cannot "capture" null in the default address space.
2895 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
2896 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
2897 indicateOptimisticFixpoint();
2898 return;
2899 }
2900
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002901 const IRPosition &IRP = getIRPosition();
2902 const Function *F =
2903 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
2904
2905 // Check what state the associated function can actually capture.
2906 if (F)
2907 determineFunctionCaptureCapabilities(*F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002908 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002909 indicatePessimisticFixpoint();
2910 }
2911
2912 /// See AbstractAttribute::updateImpl(...).
2913 ChangeStatus updateImpl(Attributor &A) override;
2914
2915 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
2916 virtual void
2917 getDeducedAttributes(LLVMContext &Ctx,
2918 SmallVectorImpl<Attribute> &Attrs) const override {
2919 if (!isAssumedNoCaptureMaybeReturned())
2920 return;
2921
Hideto Ueno37367642019-09-11 06:52:11 +00002922 if (getArgNo() >= 0) {
2923 if (isAssumedNoCapture())
2924 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
2925 else if (ManifestInternal)
2926 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
2927 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002928 }
2929
2930 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
2931 /// depending on the ability of the function associated with \p IRP to capture
2932 /// state in memory and through "returning/throwing", respectively.
2933 static void determineFunctionCaptureCapabilities(const Function &F,
2934 IntegerState &State) {
2935 // TODO: Once we have memory behavior attributes we should use them here.
2936
2937 // If we know we cannot communicate or write to memory, we do not care about
2938 // ptr2int anymore.
2939 if (F.onlyReadsMemory() && F.doesNotThrow() &&
2940 F.getReturnType()->isVoidTy()) {
2941 State.addKnownBits(NO_CAPTURE);
2942 return;
2943 }
2944
2945 // A function cannot capture state in memory if it only reads memory, it can
2946 // however return/throw state and the state might be influenced by the
2947 // pointer value, e.g., loading from a returned pointer might reveal a bit.
2948 if (F.onlyReadsMemory())
2949 State.addKnownBits(NOT_CAPTURED_IN_MEM);
2950
2951 // A function cannot communicate state back if it does not through
2952 // exceptions and doesn not return values.
2953 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
2954 State.addKnownBits(NOT_CAPTURED_IN_RET);
2955 }
2956
2957 /// See AbstractState::getAsStr().
2958 const std::string getAsStr() const override {
2959 if (isKnownNoCapture())
2960 return "known not-captured";
2961 if (isAssumedNoCapture())
2962 return "assumed not-captured";
2963 if (isKnownNoCaptureMaybeReturned())
2964 return "known not-captured-maybe-returned";
2965 if (isAssumedNoCaptureMaybeReturned())
2966 return "assumed not-captured-maybe-returned";
2967 return "assumed-captured";
2968 }
2969};
2970
2971/// Attributor-aware capture tracker.
2972struct AACaptureUseTracker final : public CaptureTracker {
2973
2974 /// Create a capture tracker that can lookup in-flight abstract attributes
2975 /// through the Attributor \p A.
2976 ///
2977 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
2978 /// search is stopped. If a use leads to a return instruction,
2979 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
2980 /// If a use leads to a ptr2int which may capture the value,
2981 /// \p CapturedInInteger is set. If a use is found that is currently assumed
2982 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
2983 /// set. All values in \p PotentialCopies are later tracked as well. For every
2984 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
2985 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
2986 /// conservatively set to true.
2987 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
2988 const AAIsDead &IsDeadAA, IntegerState &State,
2989 SmallVectorImpl<const Value *> &PotentialCopies,
2990 unsigned &RemainingUsesToExplore)
2991 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
2992 PotentialCopies(PotentialCopies),
2993 RemainingUsesToExplore(RemainingUsesToExplore) {}
2994
2995 /// Determine if \p V maybe captured. *Also updates the state!*
2996 bool valueMayBeCaptured(const Value *V) {
2997 if (V->getType()->isPointerTy()) {
2998 PointerMayBeCaptured(V, this);
2999 } else {
3000 State.indicatePessimisticFixpoint();
3001 }
3002 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3003 }
3004
3005 /// See CaptureTracker::tooManyUses().
3006 void tooManyUses() override {
3007 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3008 }
3009
3010 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3011 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3012 return true;
3013 const auto &DerefAA =
3014 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3015 return DerefAA.getAssumedDereferenceableBytes();
3016 }
3017
3018 /// See CaptureTracker::captured(...).
3019 bool captured(const Use *U) override {
3020 Instruction *UInst = cast<Instruction>(U->getUser());
3021 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3022 << "\n");
3023
3024 // Because we may reuse the tracker multiple times we keep track of the
3025 // number of explored uses ourselves as well.
3026 if (RemainingUsesToExplore-- == 0) {
3027 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3028 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3029 /* Return */ true);
3030 }
3031
3032 // Deal with ptr2int by following uses.
3033 if (isa<PtrToIntInst>(UInst)) {
3034 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3035 return valueMayBeCaptured(UInst);
3036 }
3037
3038 // Explicitly catch return instructions.
3039 if (isa<ReturnInst>(UInst))
3040 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3041 /* Return */ true);
3042
3043 // For now we only use special logic for call sites. However, the tracker
3044 // itself knows about a lot of other non-capturing cases already.
3045 CallSite CS(UInst);
3046 if (!CS || !CS.isArgOperand(U))
3047 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3048 /* Return */ true);
3049
3050 unsigned ArgNo = CS.getArgumentNo(U);
3051 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3052 // If we have a abstract no-capture attribute for the argument we can use
3053 // it to justify a non-capture attribute here. This allows recursion!
3054 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3055 if (ArgNoCaptureAA.isAssumedNoCapture())
3056 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3057 /* Return */ false);
3058 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3059 addPotentialCopy(CS);
3060 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3061 /* Return */ false);
3062 }
3063
3064 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3065 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3066 /* Return */ true);
3067 }
3068
3069 /// Register \p CS as potential copy of the value we are checking.
3070 void addPotentialCopy(CallSite CS) {
3071 PotentialCopies.push_back(CS.getInstruction());
3072 }
3073
3074 /// See CaptureTracker::shouldExplore(...).
3075 bool shouldExplore(const Use *U) override {
3076 // Check liveness.
3077 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3078 }
3079
3080 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3081 /// \p CapturedInRet, then return the appropriate value for use in the
3082 /// CaptureTracker::captured() interface.
3083 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3084 bool CapturedInRet) {
3085 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3086 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3087 if (CapturedInMem)
3088 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3089 if (CapturedInInt)
3090 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3091 if (CapturedInRet)
3092 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3093 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3094 }
3095
3096private:
3097 /// The attributor providing in-flight abstract attributes.
3098 Attributor &A;
3099
3100 /// The abstract attribute currently updated.
3101 AANoCapture &NoCaptureAA;
3102
3103 /// The abstract liveness state.
3104 const AAIsDead &IsDeadAA;
3105
3106 /// The state currently updated.
3107 IntegerState &State;
3108
3109 /// Set of potential copies of the tracked value.
3110 SmallVectorImpl<const Value *> &PotentialCopies;
3111
3112 /// Global counter to limit the number of explored uses.
3113 unsigned &RemainingUsesToExplore;
3114};
3115
3116ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
3117 const IRPosition &IRP = getIRPosition();
3118 const Value *V =
3119 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
3120 if (!V)
3121 return indicatePessimisticFixpoint();
3122
3123 const Function *F =
3124 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
3125 assert(F && "Expected a function!");
3126 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, IRPosition::function(*F));
3127
3128 AANoCapture::StateType T;
3129 // TODO: Once we have memory behavior attributes we should use them here
3130 // similar to the reasoning in
3131 // AANoCaptureImpl::determineFunctionCaptureCapabilities(...).
3132
3133 // TODO: Use the AAReturnedValues to learn if the argument can return or
3134 // not.
3135
3136 // Use the CaptureTracker interface and logic with the specialized tracker,
3137 // defined in AACaptureUseTracker, that can look at in-flight abstract
3138 // attributes and directly updates the assumed state.
3139 SmallVector<const Value *, 4> PotentialCopies;
3140 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
3141 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
3142 RemainingUsesToExplore);
3143
3144 // Check all potential copies of the associated value until we can assume
3145 // none will be captured or we have to assume at least one might be.
3146 unsigned Idx = 0;
3147 PotentialCopies.push_back(V);
3148 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
3149 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
3150
3151 AAAlign::StateType &S = getState();
3152 auto Assumed = S.getAssumed();
3153 S.intersectAssumedBits(T.getAssumed());
3154 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
3155 : ChangeStatus::CHANGED;
3156}
3157
3158/// NoCapture attribute for function arguments.
3159struct AANoCaptureArgument final : AANoCaptureImpl {
3160 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3161
3162 /// See AbstractAttribute::trackStatistics()
3163 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
3164};
3165
3166/// NoCapture attribute for call site arguments.
3167struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
3168 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3169
3170 /// See AbstractAttribute::updateImpl(...).
3171 ChangeStatus updateImpl(Attributor &A) override {
3172 // TODO: Once we have call site specific value information we can provide
3173 // call site specific liveness information and then it makes
3174 // sense to specialize attributes for call sites arguments instead of
3175 // redirecting requests to the callee argument.
3176 Argument *Arg = getAssociatedArgument();
3177 if (!Arg)
3178 return indicatePessimisticFixpoint();
3179 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3180 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
3181 return clampStateAndIndicateChange(
3182 getState(),
3183 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3184 }
3185
3186 /// See AbstractAttribute::trackStatistics()
3187 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
3188};
3189
3190/// NoCapture attribute for floating values.
3191struct AANoCaptureFloating final : AANoCaptureImpl {
3192 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3193
3194 /// See AbstractAttribute::trackStatistics()
3195 void trackStatistics() const override {
3196 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
3197 }
3198};
3199
3200/// NoCapture attribute for function return value.
3201struct AANoCaptureReturned final : AANoCaptureImpl {
3202 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
3203 llvm_unreachable("NoCapture is not applicable to function returns!");
3204 }
3205
3206 /// See AbstractAttribute::initialize(...).
3207 void initialize(Attributor &A) override {
3208 llvm_unreachable("NoCapture is not applicable to function returns!");
3209 }
3210
3211 /// See AbstractAttribute::updateImpl(...).
3212 ChangeStatus updateImpl(Attributor &A) override {
3213 llvm_unreachable("NoCapture is not applicable to function returns!");
3214 }
3215
3216 /// See AbstractAttribute::trackStatistics()
3217 void trackStatistics() const override {}
3218};
3219
3220/// NoCapture attribute deduction for a call site return value.
3221struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
3222 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
3223
3224 /// See AbstractAttribute::trackStatistics()
3225 void trackStatistics() const override {
3226 STATS_DECLTRACK_CSRET_ATTR(nocapture)
3227 }
3228};
3229
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003230/// ------------------ Value Simplify Attribute ----------------------------
3231struct AAValueSimplifyImpl : AAValueSimplify {
3232 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
3233
3234 /// See AbstractAttribute::getAsStr().
3235 const std::string getAsStr() const override {
3236 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
3237 : "not-simple";
3238 }
3239
3240 /// See AbstractAttribute::trackStatistics()
3241 void trackStatistics() const override {}
3242
3243 /// See AAValueSimplify::getAssumedSimplifiedValue()
3244 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
3245 if (!getAssumed())
3246 return const_cast<Value *>(&getAssociatedValue());
3247 return SimplifiedAssociatedValue;
3248 }
3249 void initialize(Attributor &A) override {}
3250
3251 /// Helper function for querying AAValueSimplify and updating candicate.
3252 /// \param QueryingValue Value trying to unify with SimplifiedValue
3253 /// \param AccumulatedSimplifiedValue Current simplification result.
3254 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
3255 Value &QueryingValue,
3256 Optional<Value *> &AccumulatedSimplifiedValue) {
3257 // FIXME: Add a typecast support.
3258
3259 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
3260 QueryingAA, IRPosition::value(QueryingValue));
3261
3262 Optional<Value *> QueryingValueSimplified =
3263 ValueSimpifyAA.getAssumedSimplifiedValue(A);
3264
3265 if (!QueryingValueSimplified.hasValue())
3266 return true;
3267
3268 if (!QueryingValueSimplified.getValue())
3269 return false;
3270
3271 Value &QueryingValueSimplifiedUnwrapped =
3272 *QueryingValueSimplified.getValue();
3273
3274 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
3275 return true;
3276
3277 if (AccumulatedSimplifiedValue.hasValue())
3278 return AccumulatedSimplifiedValue == QueryingValueSimplified;
3279
3280 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
3281 << " is assumed to be "
3282 << QueryingValueSimplifiedUnwrapped << "\n");
3283
3284 AccumulatedSimplifiedValue = QueryingValueSimplified;
3285 return true;
3286 }
3287
3288 /// See AbstractAttribute::manifest(...).
3289 ChangeStatus manifest(Attributor &A) override {
3290 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3291
3292 if (!SimplifiedAssociatedValue.hasValue() ||
3293 !SimplifiedAssociatedValue.getValue())
3294 return Changed;
3295
3296 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
3297 // We can replace the AssociatedValue with the constant.
3298 Value &V = getAssociatedValue();
3299 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
3300 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
3301 << "\n");
3302 V.replaceAllUsesWith(C);
3303 Changed = ChangeStatus::CHANGED;
3304 }
3305 }
3306
3307 return Changed | AAValueSimplify::manifest(A);
3308 }
3309
3310protected:
3311 // An assumed simplified value. Initially, it is set to Optional::None, which
3312 // means that the value is not clear under current assumption. If in the
3313 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
3314 // returns orignal associated value.
3315 Optional<Value *> SimplifiedAssociatedValue;
3316};
3317
3318struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
3319 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3320
3321 /// See AbstractAttribute::updateImpl(...).
3322 ChangeStatus updateImpl(Attributor &A) override {
3323 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3324
Johannes Doerfert661db042019-10-07 23:14:58 +00003325 auto PredForCallSite = [&](AbstractCallSite ACS) {
3326 // Check if we have an associated argument or not (which can happen for
3327 // callback calls).
3328 if (Value *ArgOp = ACS.getCallArgOperand(getArgNo()))
3329 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
3330 return false;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00003331 };
3332
3333 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
3334 return indicatePessimisticFixpoint();
3335
3336 // If a candicate was found in this update, return CHANGED.
3337 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3338 ? ChangeStatus::UNCHANGED
3339 : ChangeStatus ::CHANGED;
3340 }
3341
3342 /// See AbstractAttribute::trackStatistics()
3343 void trackStatistics() const override {
3344 STATS_DECLTRACK_ARG_ATTR(value_simplify)
3345 }
3346};
3347
3348struct AAValueSimplifyReturned : AAValueSimplifyImpl {
3349 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3350
3351 /// See AbstractAttribute::updateImpl(...).
3352 ChangeStatus updateImpl(Attributor &A) override {
3353 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3354
3355 auto PredForReturned = [&](Value &V) {
3356 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3357 };
3358
3359 if (!A.checkForAllReturnedValues(PredForReturned, *this))
3360 return indicatePessimisticFixpoint();
3361
3362 // If a candicate was found in this update, return CHANGED.
3363 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3364 ? ChangeStatus::UNCHANGED
3365 : ChangeStatus ::CHANGED;
3366 }
3367 /// See AbstractAttribute::trackStatistics()
3368 void trackStatistics() const override {
3369 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
3370 }
3371};
3372
3373struct AAValueSimplifyFloating : AAValueSimplifyImpl {
3374 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3375
3376 /// See AbstractAttribute::initialize(...).
3377 void initialize(Attributor &A) override {
3378 Value &V = getAnchorValue();
3379
3380 // TODO: add other stuffs
3381 if (isa<Constant>(V) || isa<UndefValue>(V))
3382 indicatePessimisticFixpoint();
3383 }
3384
3385 /// See AbstractAttribute::updateImpl(...).
3386 ChangeStatus updateImpl(Attributor &A) override {
3387 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
3388
3389 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
3390 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
3391 if (!Stripped && this == &AA) {
3392 // TODO: Look the instruction and check recursively.
3393 LLVM_DEBUG(
3394 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
3395 << V << "\n");
3396 indicatePessimisticFixpoint();
3397 return false;
3398 }
3399 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
3400 };
3401
3402 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
3403 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
3404 VisitValueCB))
3405 return indicatePessimisticFixpoint();
3406
3407 // If a candicate was found in this update, return CHANGED.
3408
3409 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
3410 ? ChangeStatus::UNCHANGED
3411 : ChangeStatus ::CHANGED;
3412 }
3413
3414 /// See AbstractAttribute::trackStatistics()
3415 void trackStatistics() const override {
3416 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
3417 }
3418};
3419
3420struct AAValueSimplifyFunction : AAValueSimplifyImpl {
3421 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
3422
3423 /// See AbstractAttribute::initialize(...).
3424 void initialize(Attributor &A) override {
3425 SimplifiedAssociatedValue = &getAnchorValue();
3426 indicateOptimisticFixpoint();
3427 }
3428 /// See AbstractAttribute::initialize(...).
3429 ChangeStatus updateImpl(Attributor &A) override {
3430 llvm_unreachable(
3431 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
3432 }
3433 /// See AbstractAttribute::trackStatistics()
3434 void trackStatistics() const override {
3435 STATS_DECLTRACK_FN_ATTR(value_simplify)
3436 }
3437};
3438
3439struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
3440 AAValueSimplifyCallSite(const IRPosition &IRP)
3441 : AAValueSimplifyFunction(IRP) {}
3442 /// See AbstractAttribute::trackStatistics()
3443 void trackStatistics() const override {
3444 STATS_DECLTRACK_CS_ATTR(value_simplify)
3445 }
3446};
3447
3448struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
3449 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
3450 : AAValueSimplifyReturned(IRP) {}
3451
3452 void trackStatistics() const override {
3453 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
3454 }
3455};
3456struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
3457 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
3458 : AAValueSimplifyFloating(IRP) {}
3459
3460 void trackStatistics() const override {
3461 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
3462 }
3463};
3464
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003465/// ----------------------- Heap-To-Stack Conversion ---------------------------
3466struct AAHeapToStackImpl : public AAHeapToStack {
3467 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
3468
3469 const std::string getAsStr() const override {
3470 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
3471 }
3472
3473 ChangeStatus manifest(Attributor &A) override {
3474 assert(getState().isValidState() &&
3475 "Attempted to manifest an invalid state!");
3476
3477 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
3478 Function *F = getAssociatedFunction();
3479 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3480
3481 for (Instruction *MallocCall : MallocCalls) {
3482 // This malloc cannot be replaced.
3483 if (BadMallocCalls.count(MallocCall))
3484 continue;
3485
3486 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
3487 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
3488 A.deleteAfterManifest(*FreeCall);
3489 HasChanged = ChangeStatus::CHANGED;
3490 }
3491
3492 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
3493 << "\n");
3494
3495 Constant *Size;
3496 if (isCallocLikeFn(MallocCall, TLI)) {
3497 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
3498 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
3499 APInt TotalSize = SizeT->getValue() * Num->getValue();
3500 Size =
3501 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
3502 } else {
3503 Size = cast<ConstantInt>(MallocCall->getOperand(0));
3504 }
3505
3506 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
3507 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
3508 Size, "", MallocCall->getNextNode());
3509
3510 if (AI->getType() != MallocCall->getType())
3511 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
3512 AI->getNextNode());
3513
3514 MallocCall->replaceAllUsesWith(AI);
3515
3516 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
3517 auto *NBB = II->getNormalDest();
3518 BranchInst::Create(NBB, MallocCall->getParent());
3519 A.deleteAfterManifest(*MallocCall);
3520 } else {
3521 A.deleteAfterManifest(*MallocCall);
3522 }
3523
3524 if (isCallocLikeFn(MallocCall, TLI)) {
3525 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
3526 AI->getNextNode());
3527 Value *Ops[] = {
3528 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
3529 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
3530
3531 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
3532 Module *M = F->getParent();
3533 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
3534 CallInst::Create(Fn, Ops, "", BI->getNextNode());
3535 }
3536 HasChanged = ChangeStatus::CHANGED;
3537 }
3538
3539 return HasChanged;
3540 }
3541
3542 /// Collection of all malloc calls in a function.
3543 SmallSetVector<Instruction *, 4> MallocCalls;
3544
3545 /// Collection of malloc calls that cannot be converted.
3546 DenseSet<const Instruction *> BadMallocCalls;
3547
3548 /// A map for each malloc call to the set of associated free calls.
3549 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
3550
3551 ChangeStatus updateImpl(Attributor &A) override;
3552};
3553
3554ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
3555 const Function *F = getAssociatedFunction();
3556 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
3557
3558 auto UsesCheck = [&](Instruction &I) {
3559 SmallPtrSet<const Use *, 8> Visited;
3560 SmallVector<const Use *, 8> Worklist;
3561
3562 for (Use &U : I.uses())
3563 Worklist.push_back(&U);
3564
3565 while (!Worklist.empty()) {
3566 const Use *U = Worklist.pop_back_val();
3567 if (!Visited.insert(U).second)
3568 continue;
3569
3570 auto *UserI = U->getUser();
3571
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003572 if (isa<LoadInst>(UserI))
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003573 continue;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00003574 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
3575 if (SI->getValueOperand() == U->get()) {
3576 LLVM_DEBUG(dbgs() << "[H2S] escaping store to memory: " << *UserI << "\n");
3577 return false;
3578 }
3579 // A store into the malloc'ed memory is fine.
3580 continue;
3581 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003582
3583 // NOTE: Right now, if a function that has malloc pointer as an argument
3584 // frees memory, we assume that the malloc pointer is freed.
3585
3586 // TODO: Add nofree callsite argument attribute to indicate that pointer
3587 // argument is not freed.
3588 if (auto *CB = dyn_cast<CallBase>(UserI)) {
3589 if (!CB->isArgOperand(U))
3590 continue;
3591
3592 if (CB->isLifetimeStartOrEnd())
3593 continue;
3594
3595 // Record malloc.
3596 if (isFreeCall(UserI, TLI)) {
3597 FreesForMalloc[&I].insert(
3598 cast<Instruction>(const_cast<User *>(UserI)));
3599 continue;
3600 }
3601
3602 // If a function does not free memory we are fine
3603 const auto &NoFreeAA =
3604 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(*CB));
3605
3606 unsigned ArgNo = U - CB->arg_begin();
3607 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
3608 *this, IRPosition::callsite_argument(*CB, ArgNo));
3609
3610 if (!NoCaptureAA.isAssumedNoCapture() || !NoFreeAA.isAssumedNoFree()) {
3611 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
3612 return false;
3613 }
3614 continue;
3615 }
3616
3617 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI)) {
3618 for (Use &U : UserI->uses())
3619 Worklist.push_back(&U);
3620 continue;
3621 }
3622
3623 // Unknown user.
3624 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
3625 return false;
3626 }
3627 return true;
3628 };
3629
3630 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003631 if (BadMallocCalls.count(&I))
3632 return true;
3633
3634 bool IsMalloc = isMallocLikeFn(&I, TLI);
3635 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
3636 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003637 BadMallocCalls.insert(&I);
3638 return true;
3639 }
3640
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003641 if (IsMalloc) {
3642 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
3643 if (Size->getValue().sle(MaxHeapToStackSize))
3644 if (UsesCheck(I)) {
3645 MallocCalls.insert(&I);
3646 return true;
3647 }
3648 } else if (IsCalloc) {
3649 bool Overflow = false;
3650 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
3651 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
3652 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
3653 .sle(MaxHeapToStackSize))
3654 if (!Overflow && UsesCheck(I)) {
3655 MallocCalls.insert(&I);
3656 return true;
3657 }
3658 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003659
Johannes Doerfertd20f8072019-10-13 03:54:08 +00003660 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00003661 return true;
3662 };
3663
3664 size_t NumBadMallocs = BadMallocCalls.size();
3665
3666 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
3667
3668 if (NumBadMallocs != BadMallocCalls.size())
3669 return ChangeStatus::CHANGED;
3670
3671 return ChangeStatus::UNCHANGED;
3672}
3673
3674struct AAHeapToStackFunction final : public AAHeapToStackImpl {
3675 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
3676
3677 /// See AbstractAttribute::trackStatistics()
3678 void trackStatistics() const override {
3679 STATS_DECL(MallocCalls, Function,
3680 "Number of MallocCalls converted to allocas");
3681 BUILD_STAT_NAME(MallocCalls, Function) += MallocCalls.size();
3682 }
3683};
3684
Johannes Doerfert1097fab2019-10-07 21:07:57 +00003685/// -------------------- Memory Behavior Attributes ----------------------------
3686/// Includes read-none, read-only, and write-only.
3687/// ----------------------------------------------------------------------------
3688struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
3689 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
3690
3691 /// See AbstractAttribute::initialize(...).
3692 void initialize(Attributor &A) override {
3693 intersectAssumedBits(BEST_STATE);
3694 getKnownStateFromValue(getIRPosition(), getState());
3695 IRAttribute::initialize(A);
3696 }
3697
3698 /// Return the memory behavior information encoded in the IR for \p IRP.
3699 static void getKnownStateFromValue(const IRPosition &IRP,
3700 IntegerState &State) {
3701 SmallVector<Attribute, 2> Attrs;
3702 IRP.getAttrs(AttrKinds, Attrs);
3703 for (const Attribute &Attr : Attrs) {
3704 switch (Attr.getKindAsEnum()) {
3705 case Attribute::ReadNone:
3706 State.addKnownBits(NO_ACCESSES);
3707 break;
3708 case Attribute::ReadOnly:
3709 State.addKnownBits(NO_WRITES);
3710 break;
3711 case Attribute::WriteOnly:
3712 State.addKnownBits(NO_READS);
3713 break;
3714 default:
3715 llvm_unreachable("Unexpcted attribute!");
3716 }
3717 }
3718
3719 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
3720 if (!I->mayReadFromMemory())
3721 State.addKnownBits(NO_READS);
3722 if (!I->mayWriteToMemory())
3723 State.addKnownBits(NO_WRITES);
3724 }
3725 }
3726
3727 /// See AbstractAttribute::getDeducedAttributes(...).
3728 void getDeducedAttributes(LLVMContext &Ctx,
3729 SmallVectorImpl<Attribute> &Attrs) const override {
3730 assert(Attrs.size() == 0);
3731 if (isAssumedReadNone())
3732 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
3733 else if (isAssumedReadOnly())
3734 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
3735 else if (isAssumedWriteOnly())
3736 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
3737 assert(Attrs.size() <= 1);
3738 }
3739
3740 /// See AbstractAttribute::manifest(...).
3741 ChangeStatus manifest(Attributor &A) override {
3742 IRPosition &IRP = getIRPosition();
3743
3744 // Check if we would improve the existing attributes first.
3745 SmallVector<Attribute, 4> DeducedAttrs;
3746 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
3747 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
3748 return IRP.hasAttr(Attr.getKindAsEnum(),
3749 /* IgnoreSubsumingPositions */ true);
3750 }))
3751 return ChangeStatus::UNCHANGED;
3752
3753 // Clear existing attributes.
3754 IRP.removeAttrs(AttrKinds);
3755
3756 // Use the generic manifest method.
3757 return IRAttribute::manifest(A);
3758 }
3759
3760 /// See AbstractState::getAsStr().
3761 const std::string getAsStr() const override {
3762 if (isAssumedReadNone())
3763 return "readnone";
3764 if (isAssumedReadOnly())
3765 return "readonly";
3766 if (isAssumedWriteOnly())
3767 return "writeonly";
3768 return "may-read/write";
3769 }
3770
3771 /// The set of IR attributes AAMemoryBehavior deals with.
3772 static const Attribute::AttrKind AttrKinds[3];
3773};
3774
3775const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
3776 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
3777
3778/// Memory behavior attribute for a floating value.
3779struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
3780 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
3781
3782 /// See AbstractAttribute::initialize(...).
3783 void initialize(Attributor &A) override {
3784 AAMemoryBehaviorImpl::initialize(A);
3785 // Initialize the use vector with all direct uses of the associated value.
3786 for (const Use &U : getAssociatedValue().uses())
3787 Uses.insert(&U);
3788 }
3789
3790 /// See AbstractAttribute::updateImpl(...).
3791 ChangeStatus updateImpl(Attributor &A) override;
3792
3793 /// See AbstractAttribute::trackStatistics()
3794 void trackStatistics() const override {
3795 if (isAssumedReadNone())
3796 STATS_DECLTRACK_FLOATING_ATTR(readnone)
3797 else if (isAssumedReadOnly())
3798 STATS_DECLTRACK_FLOATING_ATTR(readonly)
3799 else if (isAssumedWriteOnly())
3800 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
3801 }
3802
3803private:
3804 /// Return true if users of \p UserI might access the underlying
3805 /// variable/location described by \p U and should therefore be analyzed.
3806 bool followUsersOfUseIn(Attributor &A, const Use *U,
3807 const Instruction *UserI);
3808
3809 /// Update the state according to the effect of use \p U in \p UserI.
3810 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
3811
3812protected:
3813 /// Container for (transitive) uses of the associated argument.
3814 SetVector<const Use *> Uses;
3815};
3816
3817/// Memory behavior attribute for function argument.
3818struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
3819 AAMemoryBehaviorArgument(const IRPosition &IRP)
3820 : AAMemoryBehaviorFloating(IRP) {}
3821
3822 /// See AbstractAttribute::initialize(...).
3823 void initialize(Attributor &A) override {
3824 AAMemoryBehaviorFloating::initialize(A);
3825
3826 // TODO: From readattrs.ll: "inalloca parameters are always
3827 // considered written"
3828 if (hasAttr({Attribute::InAlloca}))
3829 removeAssumedBits(NO_WRITES);
3830
3831 // Initialize the use vector with all direct uses of the associated value.
3832 Argument *Arg = getAssociatedArgument();
3833 if (!Arg || !Arg->getParent()->hasExactDefinition())
3834 indicatePessimisticFixpoint();
3835 }
3836
3837 /// See AbstractAttribute::trackStatistics()
3838 void trackStatistics() const override {
3839 if (isAssumedReadNone())
3840 STATS_DECLTRACK_ARG_ATTR(readnone)
3841 else if (isAssumedReadOnly())
3842 STATS_DECLTRACK_ARG_ATTR(readonly)
3843 else if (isAssumedWriteOnly())
3844 STATS_DECLTRACK_ARG_ATTR(writeonly)
3845 }
3846};
3847
3848struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
3849 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
3850 : AAMemoryBehaviorArgument(IRP) {}
3851
3852 /// See AbstractAttribute::updateImpl(...).
3853 ChangeStatus updateImpl(Attributor &A) override {
3854 // TODO: Once we have call site specific value information we can provide
3855 // call site specific liveness liveness information and then it makes
3856 // sense to specialize attributes for call sites arguments instead of
3857 // redirecting requests to the callee argument.
3858 Argument *Arg = getAssociatedArgument();
3859 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3860 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
3861 return clampStateAndIndicateChange(
3862 getState(),
3863 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
3864 }
3865
3866 /// See AbstractAttribute::trackStatistics()
3867 void trackStatistics() const override {
3868 if (isAssumedReadNone())
3869 STATS_DECLTRACK_CSARG_ATTR(readnone)
3870 else if (isAssumedReadOnly())
3871 STATS_DECLTRACK_CSARG_ATTR(readonly)
3872 else if (isAssumedWriteOnly())
3873 STATS_DECLTRACK_CSARG_ATTR(writeonly)
3874 }
3875};
3876
3877/// Memory behavior attribute for a call site return position.
3878struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
3879 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
3880 : AAMemoryBehaviorFloating(IRP) {}
3881
3882 /// See AbstractAttribute::manifest(...).
3883 ChangeStatus manifest(Attributor &A) override {
3884 // We do not annotate returned values.
3885 return ChangeStatus::UNCHANGED;
3886 }
3887
3888 /// See AbstractAttribute::trackStatistics()
3889 void trackStatistics() const override {}
3890};
3891
3892/// An AA to represent the memory behavior function attributes.
3893struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
3894 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
3895
3896 /// See AbstractAttribute::updateImpl(Attributor &A).
3897 virtual ChangeStatus updateImpl(Attributor &A) override;
3898
3899 /// See AbstractAttribute::manifest(...).
3900 ChangeStatus manifest(Attributor &A) override {
3901 Function &F = cast<Function>(getAnchorValue());
3902 if (isAssumedReadNone()) {
3903 F.removeFnAttr(Attribute::ArgMemOnly);
3904 F.removeFnAttr(Attribute::InaccessibleMemOnly);
3905 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
3906 }
3907 return AAMemoryBehaviorImpl::manifest(A);
3908 }
3909
3910 /// See AbstractAttribute::trackStatistics()
3911 void trackStatistics() const override {
3912 if (isAssumedReadNone())
3913 STATS_DECLTRACK_FN_ATTR(readnone)
3914 else if (isAssumedReadOnly())
3915 STATS_DECLTRACK_FN_ATTR(readonly)
3916 else if (isAssumedWriteOnly())
3917 STATS_DECLTRACK_FN_ATTR(writeonly)
3918 }
3919};
3920
3921/// AAMemoryBehavior attribute for call sites.
3922struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
3923 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
3924
3925 /// See AbstractAttribute::initialize(...).
3926 void initialize(Attributor &A) override {
3927 AAMemoryBehaviorImpl::initialize(A);
3928 Function *F = getAssociatedFunction();
3929 if (!F || !F->hasExactDefinition())
3930 indicatePessimisticFixpoint();
3931 }
3932
3933 /// See AbstractAttribute::updateImpl(...).
3934 ChangeStatus updateImpl(Attributor &A) override {
3935 // TODO: Once we have call site specific value information we can provide
3936 // call site specific liveness liveness information and then it makes
3937 // sense to specialize attributes for call sites arguments instead of
3938 // redirecting requests to the callee argument.
3939 Function *F = getAssociatedFunction();
3940 const IRPosition &FnPos = IRPosition::function(*F);
3941 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3942 return clampStateAndIndicateChange(
3943 getState(), static_cast<const AAAlign::StateType &>(FnAA.getState()));
3944 }
3945
3946 /// See AbstractAttribute::trackStatistics()
3947 void trackStatistics() const override {
3948 if (isAssumedReadNone())
3949 STATS_DECLTRACK_CS_ATTR(readnone)
3950 else if (isAssumedReadOnly())
3951 STATS_DECLTRACK_CS_ATTR(readonly)
3952 else if (isAssumedWriteOnly())
3953 STATS_DECLTRACK_CS_ATTR(writeonly)
3954 }
3955};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00003956} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00003957
3958ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
3959
3960 // The current assumed state used to determine a change.
3961 auto AssumedState = getAssumed();
3962
3963 auto CheckRWInst = [&](Instruction &I) {
3964 // If the instruction has an own memory behavior state, use it to restrict
3965 // the local state. No further analysis is required as the other memory
3966 // state is as optimistic as it gets.
3967 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
3968 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
3969 *this, IRPosition::callsite_function(ICS));
3970 intersectAssumedBits(MemBehaviorAA.getAssumed());
3971 return !isAtFixpoint();
3972 }
3973
3974 // Remove access kind modifiers if necessary.
3975 if (I.mayReadFromMemory())
3976 removeAssumedBits(NO_READS);
3977 if (I.mayWriteToMemory())
3978 removeAssumedBits(NO_WRITES);
3979 return !isAtFixpoint();
3980 };
3981
3982 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
3983 return indicatePessimisticFixpoint();
3984
3985 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
3986 : ChangeStatus::UNCHANGED;
3987}
3988
3989ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
3990
3991 const IRPosition &IRP = getIRPosition();
3992 const IRPosition &FnPos = IRPosition::function_scope(IRP);
3993 AAMemoryBehavior::StateType &S = getState();
3994
3995 // First, check the function scope. We take the known information and we avoid
3996 // work if the assumed information implies the current assumed information for
3997 // this attribute.
3998 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3999 S.addKnownBits(FnMemAA.getKnown());
4000 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
4001 return ChangeStatus::UNCHANGED;
4002
4003 // Make sure the value is not captured (except through "return"), if
4004 // it is, any information derived would be irrelevant anyway as we cannot
4005 // check the potential aliases introduced by the capture.
4006 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
4007 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned())
4008 return indicatePessimisticFixpoint();
4009
4010 // The current assumed state used to determine a change.
4011 auto AssumedState = S.getAssumed();
4012
4013 // Liveness information to exclude dead users.
4014 // TODO: Take the FnPos once we have call site specific liveness information.
4015 const auto &LivenessAA = A.getAAFor<AAIsDead>(
4016 *this, IRPosition::function(*IRP.getAssociatedFunction()));
4017
4018 // Visit and expand uses until all are analyzed or a fixpoint is reached.
4019 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
4020 const Use *U = Uses[i];
4021 Instruction *UserI = cast<Instruction>(U->getUser());
4022 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
4023 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
4024 << "]\n");
4025 if (LivenessAA.isAssumedDead(UserI))
4026 continue;
4027
4028 // Check if the users of UserI should also be visited.
4029 if (followUsersOfUseIn(A, U, UserI))
4030 for (const Use &UserIUse : UserI->uses())
4031 Uses.insert(&UserIUse);
4032
4033 // If UserI might touch memory we analyze the use in detail.
4034 if (UserI->mayReadOrWriteMemory())
4035 analyzeUseIn(A, U, UserI);
4036 }
4037
4038 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4039 : ChangeStatus::UNCHANGED;
4040}
4041
4042bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
4043 const Instruction *UserI) {
4044 // The loaded value is unrelated to the pointer argument, no need to
4045 // follow the users of the load.
4046 if (isa<LoadInst>(UserI))
4047 return false;
4048
4049 // By default we follow all uses assuming UserI might leak information on U,
4050 // we have special handling for call sites operands though.
4051 ImmutableCallSite ICS(UserI);
4052 if (!ICS || !ICS.isArgOperand(U))
4053 return true;
4054
4055 // If the use is a call argument known not to be captured, the users of
4056 // the call do not need to be visited because they have to be unrelated to
4057 // the input. Note that this check is not trivial even though we disallow
4058 // general capturing of the underlying argument. The reason is that the
4059 // call might the argument "through return", which we allow and for which we
4060 // need to check call users.
4061 unsigned ArgNo = ICS.getArgumentNo(U);
4062 const auto &ArgNoCaptureAA =
4063 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
4064 return !ArgNoCaptureAA.isAssumedNoCapture();
4065}
4066
4067void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
4068 const Instruction *UserI) {
4069 assert(UserI->mayReadOrWriteMemory());
4070
4071 switch (UserI->getOpcode()) {
4072 default:
4073 // TODO: Handle all atomics and other side-effect operations we know of.
4074 break;
4075 case Instruction::Load:
4076 // Loads cause the NO_READS property to disappear.
4077 removeAssumedBits(NO_READS);
4078 return;
4079
4080 case Instruction::Store:
4081 // Stores cause the NO_WRITES property to disappear if the use is the
4082 // pointer operand. Note that we do assume that capturing was taken care of
4083 // somewhere else.
4084 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
4085 removeAssumedBits(NO_WRITES);
4086 return;
4087
4088 case Instruction::Call:
4089 case Instruction::CallBr:
4090 case Instruction::Invoke: {
4091 // For call sites we look at the argument memory behavior attribute (this
4092 // could be recursive!) in order to restrict our own state.
4093 ImmutableCallSite ICS(UserI);
4094
4095 // Give up on operand bundles.
4096 if (ICS.isBundleOperand(U)) {
4097 indicatePessimisticFixpoint();
4098 return;
4099 }
4100
4101 // Calling a function does read the function pointer, maybe write it if the
4102 // function is self-modifying.
4103 if (ICS.isCallee(U)) {
4104 removeAssumedBits(NO_READS);
4105 break;
4106 }
4107
4108 // Adjust the possible access behavior based on the information on the
4109 // argument.
4110 unsigned ArgNo = ICS.getArgumentNo(U);
4111 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
4112 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4113 // "assumed" has at most the same bits as the MemBehaviorAA assumed
4114 // and at least "known".
4115 intersectAssumedBits(MemBehaviorAA.getAssumed());
4116 return;
4117 }
4118 };
4119
4120 // Generally, look at the "may-properties" and adjust the assumed state if we
4121 // did not trigger special handling before.
4122 if (UserI->mayReadFromMemory())
4123 removeAssumedBits(NO_READS);
4124 if (UserI->mayWriteToMemory())
4125 removeAssumedBits(NO_WRITES);
4126}
4127
Johannes Doerfertaade7822019-06-05 03:02:24 +00004128/// ----------------------------------------------------------------------------
4129/// Attributor
4130/// ----------------------------------------------------------------------------
4131
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004132bool Attributor::isAssumedDead(const AbstractAttribute &AA,
4133 const AAIsDead *LivenessAA) {
4134 const Instruction *CtxI = AA.getIRPosition().getCtxI();
4135 if (!CtxI)
4136 return false;
4137
4138 if (!LivenessAA)
4139 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00004140 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
4141 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00004142
4143 // Don't check liveness for AAIsDead.
4144 if (&AA == LivenessAA)
4145 return false;
4146
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004147 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004148 return false;
4149
Johannes Doerfert19b00432019-08-26 17:48:05 +00004150 // We actually used liveness information so we have to record a dependence.
4151 recordDependence(*LivenessAA, AA);
4152
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004153 return true;
4154}
4155
Johannes Doerfert661db042019-10-07 23:14:58 +00004156bool Attributor::checkForAllCallSites(
4157 const function_ref<bool(AbstractCallSite)> &Pred,
4158 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004159 // We can try to determine information from
4160 // the call sites. However, this is only possible all call sites are known,
4161 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004162 const IRPosition &IRP = QueryingAA.getIRPosition();
4163 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00004164 if (!AssociatedFunction) {
4165 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
4166 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004167 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00004168 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004169
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004170 if (RequireAllCallSites && !AssociatedFunction->hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004171 LLVM_DEBUG(
4172 dbgs()
Johannes Doerfert5304b722019-08-14 22:04:28 +00004173 << "[Attributor] Function " << AssociatedFunction->getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00004174 << " has no internal linkage, hence not all call sites are known\n");
4175 return false;
4176 }
4177
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004178 for (const Use &U : AssociatedFunction->uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00004179 AbstractCallSite ACS(&U);
4180 if (!ACS) {
4181 LLVM_DEBUG(dbgs() << "[Attributor] Function "
4182 << AssociatedFunction->getName()
4183 << " has non call site use " << *U.get() << " in "
4184 << *U.getUser() << "\n");
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004185 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00004186 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00004187
Johannes Doerfert661db042019-10-07 23:14:58 +00004188 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004189 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004190
Johannes Doerfert661db042019-10-07 23:14:58 +00004191 const auto &LivenessAA =
4192 getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*Caller),
4193 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004194
4195 // Skip dead calls.
Johannes Doerfert19b00432019-08-26 17:48:05 +00004196 if (LivenessAA.isAssumedDead(I)) {
4197 // We actually used liveness information so we have to record a
4198 // dependence.
4199 recordDependence(LivenessAA, QueryingAA);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00004200 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004201 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004202
Johannes Doerfert661db042019-10-07 23:14:58 +00004203 const Use *EffectiveUse =
4204 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
4205 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004206 if (!RequireAllCallSites)
4207 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00004208 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004209 << " is an invalid use of "
4210 << AssociatedFunction->getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004211 return false;
4212 }
4213
Johannes Doerfert661db042019-10-07 23:14:58 +00004214 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00004215 continue;
4216
Johannes Doerfert5304b722019-08-14 22:04:28 +00004217 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00004218 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00004219 return false;
4220 }
4221
4222 return true;
4223}
4224
Johannes Doerfert14a04932019-08-07 22:27:24 +00004225bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004226 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00004227 &Pred,
4228 const AbstractAttribute &QueryingAA) {
4229
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004230 const IRPosition &IRP = QueryingAA.getIRPosition();
4231 // Since we need to provide return instructions we have to have an exact
4232 // definition.
4233 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004234 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004235 return false;
4236
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004237 // If this is a call site query we use the call site specific return values
4238 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004239 // TODO: use the function scope once we have call site AAReturnedValues.
4240 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004241 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004242 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004243 return false;
4244
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004245 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00004246}
4247
4248bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004249 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00004250 const AbstractAttribute &QueryingAA) {
4251
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004252 const IRPosition &IRP = QueryingAA.getIRPosition();
4253 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004254 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00004255 return false;
4256
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004257 // TODO: use the function scope once we have call site AAReturnedValues.
4258 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004259 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004260 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004261 return false;
4262
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004263 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00004264 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00004265 return Pred(RV);
4266 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00004267}
4268
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004269static bool
4270checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
4271 const function_ref<bool(Instruction &)> &Pred,
4272 const AAIsDead *LivenessAA, bool &AnyDead,
4273 const ArrayRef<unsigned> &Opcodes) {
4274 for (unsigned Opcode : Opcodes) {
4275 for (Instruction *I : OpcodeInstMap[Opcode]) {
4276 // Skip dead instructions.
4277 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
4278 AnyDead = true;
4279 continue;
4280 }
4281
4282 if (!Pred(*I))
4283 return false;
4284 }
4285 }
4286 return true;
4287}
4288
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004289bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004290 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004291 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004292
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004293 const IRPosition &IRP = QueryingAA.getIRPosition();
4294 // Since we need to provide instructions we have to have an exact definition.
4295 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004296 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004297 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004298
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004299 // TODO: use the function scope once we have call site AAReturnedValues.
4300 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004301 const auto &LivenessAA =
4302 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
4303 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004304
4305 auto &OpcodeInstMap =
4306 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004307 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
4308 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004309 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004310
Johannes Doerfert19b00432019-08-26 17:48:05 +00004311 // If we actually used liveness information so we have to record a dependence.
4312 if (AnyDead)
4313 recordDependence(LivenessAA, QueryingAA);
4314
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004315 return true;
4316}
4317
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004318bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004319 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00004320 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004321
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004322 const Function *AssociatedFunction =
4323 QueryingAA.getIRPosition().getAssociatedFunction();
4324 if (!AssociatedFunction)
4325 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004326
Johannes Doerfert07a5c122019-08-28 14:09:14 +00004327 // TODO: use the function scope once we have call site AAReturnedValues.
4328 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
4329 const auto &LivenessAA =
4330 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00004331 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004332
4333 for (Instruction *I :
4334 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004335 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00004336 if (LivenessAA.isAssumedDead(I)) {
4337 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004338 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00004339 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004340
4341 if (!Pred(*I))
4342 return false;
4343 }
4344
Johannes Doerfert19b00432019-08-26 17:48:05 +00004345 // If we actually used liveness information so we have to record a dependence.
4346 if (AnyDead)
4347 recordDependence(LivenessAA, QueryingAA);
4348
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00004349 return true;
4350}
4351
Johannes Doerfert2f622062019-09-04 16:35:20 +00004352ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004353 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
4354 << AllAbstractAttributes.size()
4355 << " abstract attributes.\n");
4356
Stefan Stipanovic53605892019-06-27 11:27:54 +00004357 // Now that all abstract attributes are collected and initialized we start
4358 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00004359
4360 unsigned IterationCounter = 1;
4361
4362 SmallVector<AbstractAttribute *, 64> ChangedAAs;
4363 SetVector<AbstractAttribute *> Worklist;
4364 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
4365
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004366 bool RecomputeDependences = false;
4367
Johannes Doerfertaade7822019-06-05 03:02:24 +00004368 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004369 // Remember the size to determine new attributes.
4370 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004371 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
4372 << ", Worklist size: " << Worklist.size() << "\n");
4373
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004374 // If dependences (=QueryMap) are recomputed we have to look at all abstract
4375 // attributes again, regardless of what changed in the last iteration.
4376 if (RecomputeDependences) {
4377 LLVM_DEBUG(
4378 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
4379 QueryMap.clear();
4380 ChangedAAs.clear();
4381 Worklist.insert(AllAbstractAttributes.begin(),
4382 AllAbstractAttributes.end());
4383 }
4384
Johannes Doerfertaade7822019-06-05 03:02:24 +00004385 // Add all abstract attributes that are potentially dependent on one that
4386 // changed to the work list.
4387 for (AbstractAttribute *ChangedAA : ChangedAAs) {
4388 auto &QuerriedAAs = QueryMap[ChangedAA];
4389 Worklist.insert(QuerriedAAs.begin(), QuerriedAAs.end());
4390 }
4391
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004392 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
4393 << ", Worklist+Dependent size: " << Worklist.size()
4394 << "\n");
4395
Johannes Doerfertaade7822019-06-05 03:02:24 +00004396 // Reset the changed set.
4397 ChangedAAs.clear();
4398
4399 // Update all abstract attribute in the work list and record the ones that
4400 // changed.
4401 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004402 if (!isAssumedDead(*AA, nullptr))
4403 if (AA->update(*this) == ChangeStatus::CHANGED)
4404 ChangedAAs.push_back(AA);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004405
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004406 // Check if we recompute the dependences in the next iteration.
4407 RecomputeDependences = (DepRecomputeInterval > 0 &&
4408 IterationCounter % DepRecomputeInterval == 0);
4409
Johannes Doerfert9543f142019-08-23 15:24:57 +00004410 // Add attributes to the changed set if they have been created in the last
4411 // iteration.
4412 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
4413 AllAbstractAttributes.end());
4414
Johannes Doerfertaade7822019-06-05 03:02:24 +00004415 // Reset the work list and repopulate with the changed abstract attributes.
4416 // Note that dependent ones are added above.
4417 Worklist.clear();
4418 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
4419
Johannes Doerfertbf112132019-08-29 01:29:44 +00004420 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
4421 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004422
Johannes Doerfertaade7822019-06-05 03:02:24 +00004423 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
4424 << IterationCounter << "/" << MaxFixpointIterations
4425 << " iterations\n");
4426
Johannes Doerfertbf112132019-08-29 01:29:44 +00004427 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00004428
Johannes Doerfertaade7822019-06-05 03:02:24 +00004429 bool FinishedAtFixpoint = Worklist.empty();
4430
4431 // Reset abstract arguments not settled in a sound fixpoint by now. This
4432 // happens when we stopped the fixpoint iteration early. Note that only the
4433 // ones marked as "changed" *and* the ones transitively depending on them
4434 // need to be reverted to a pessimistic state. Others might not be in a
4435 // fixpoint state but we can use the optimistic results for them anyway.
4436 SmallPtrSet<AbstractAttribute *, 32> Visited;
4437 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
4438 AbstractAttribute *ChangedAA = ChangedAAs[u];
4439 if (!Visited.insert(ChangedAA).second)
4440 continue;
4441
4442 AbstractState &State = ChangedAA->getState();
4443 if (!State.isAtFixpoint()) {
4444 State.indicatePessimisticFixpoint();
4445
4446 NumAttributesTimedOut++;
4447 }
4448
4449 auto &QuerriedAAs = QueryMap[ChangedAA];
4450 ChangedAAs.append(QuerriedAAs.begin(), QuerriedAAs.end());
4451 }
4452
4453 LLVM_DEBUG({
4454 if (!Visited.empty())
4455 dbgs() << "\n[Attributor] Finalized " << Visited.size()
4456 << " abstract attributes.\n";
4457 });
4458
4459 unsigned NumManifested = 0;
4460 unsigned NumAtFixpoint = 0;
4461 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
4462 for (AbstractAttribute *AA : AllAbstractAttributes) {
4463 AbstractState &State = AA->getState();
4464
4465 // If there is not already a fixpoint reached, we can now take the
4466 // optimistic state. This is correct because we enforced a pessimistic one
4467 // on abstract attributes that were transitively dependent on a changed one
4468 // already above.
4469 if (!State.isAtFixpoint())
4470 State.indicateOptimisticFixpoint();
4471
4472 // If the state is invalid, we do not try to manifest it.
4473 if (!State.isValidState())
4474 continue;
4475
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00004476 // Skip dead code.
4477 if (isAssumedDead(*AA, nullptr))
4478 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004479 // Manifest the state and record if we changed the IR.
4480 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00004481 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
4482 AA->trackStatistics();
4483
Johannes Doerfertaade7822019-06-05 03:02:24 +00004484 ManifestChange = ManifestChange | LocalChange;
4485
4486 NumAtFixpoint++;
4487 NumManifested += (LocalChange == ChangeStatus::CHANGED);
4488 }
4489
4490 (void)NumManifested;
4491 (void)NumAtFixpoint;
4492 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
4493 << " arguments while " << NumAtFixpoint
4494 << " were in a valid fixpoint state\n");
4495
4496 // If verification is requested, we finished this run at a fixpoint, and the
4497 // IR was changed, we re-run the whole fixpoint analysis, starting at
4498 // re-initialization of the arguments. This re-run should not result in an IR
4499 // change. Though, the (virtual) state of attributes at the end of the re-run
4500 // might be more optimistic than the known state or the IR state if the better
4501 // state cannot be manifested.
4502 if (VerifyAttributor && FinishedAtFixpoint &&
4503 ManifestChange == ChangeStatus::CHANGED) {
4504 VerifyAttributor = false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00004505 ChangeStatus VerifyStatus = run(M);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004506 if (VerifyStatus != ChangeStatus::UNCHANGED)
4507 llvm_unreachable(
4508 "Attributor verification failed, re-run did result in an IR change "
4509 "even after a fixpoint was reached in the original run. (False "
4510 "positives possible!)");
4511 VerifyAttributor = true;
4512 }
4513
4514 NumAttributesManifested += NumManifested;
4515 NumAttributesValidFixpoint += NumAtFixpoint;
4516
Fangrui Songf1826172019-08-20 07:21:43 +00004517 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004518 assert(
4519 NumFinalAAs == AllAbstractAttributes.size() &&
4520 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00004521
4522 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00004523 {
4524 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
4525 << ToBeDeletedFunctions.size() << " functions and "
4526 << ToBeDeletedBlocks.size() << " blocks and "
4527 << ToBeDeletedInsts.size() << " instructions\n");
4528 for (Instruction *I : ToBeDeletedInsts) {
4529 if (!I->use_empty())
4530 I->replaceAllUsesWith(UndefValue::get(I->getType()));
4531 I->eraseFromParent();
4532 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004533
Johannes Doerfert2f622062019-09-04 16:35:20 +00004534 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
4535 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
4536 ToBeDeletedBBs.reserve(NumDeadBlocks);
4537 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
4538 DeleteDeadBlocks(ToBeDeletedBBs);
4539 STATS_DECLTRACK(AAIsDead, BasicBlock,
4540 "Number of dead basic blocks deleted.");
4541 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00004542
Johannes Doerfert2f622062019-09-04 16:35:20 +00004543 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
4544 for (Function *Fn : ToBeDeletedFunctions) {
4545 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
4546 Fn->eraseFromParent();
4547 STATS_TRACK(AAIsDead, Function);
4548 }
4549
4550 // Identify dead internal functions and delete them. This happens outside
4551 // the other fixpoint analysis as we might treat potentially dead functions
4552 // as live to lower the number of iterations. If they happen to be dead, the
4553 // below fixpoint loop will identify and eliminate them.
4554 SmallVector<Function *, 8> InternalFns;
4555 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004556 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00004557 InternalFns.push_back(&F);
4558
4559 bool FoundDeadFn = true;
4560 while (FoundDeadFn) {
4561 FoundDeadFn = false;
4562 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
4563 Function *F = InternalFns[u];
4564 if (!F)
4565 continue;
4566
4567 const auto *LivenessAA =
4568 lookupAAFor<AAIsDead>(IRPosition::function(*F));
4569 if (LivenessAA &&
Johannes Doerfert661db042019-10-07 23:14:58 +00004570 !checkForAllCallSites([](AbstractCallSite ACS) { return false; },
Johannes Doerfert2f622062019-09-04 16:35:20 +00004571 *LivenessAA, true))
4572 continue;
4573
4574 STATS_TRACK(AAIsDead, Function);
4575 F->replaceAllUsesWith(UndefValue::get(F->getType()));
4576 F->eraseFromParent();
4577 InternalFns[u] = nullptr;
4578 FoundDeadFn = true;
4579 }
4580 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00004581 }
4582
Johannes Doerfertbf112132019-08-29 01:29:44 +00004583 if (VerifyMaxFixpointIterations &&
4584 IterationCounter != MaxFixpointIterations) {
4585 errs() << "\n[Attributor] Fixpoint iteration done after: "
4586 << IterationCounter << "/" << MaxFixpointIterations
4587 << " iterations\n";
4588 llvm_unreachable("The fixpoint was not reached with exactly the number of "
4589 "specified iterations!");
4590 }
4591
Johannes Doerfertaade7822019-06-05 03:02:24 +00004592 return ManifestChange;
4593}
4594
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004595void Attributor::initializeInformationCache(Function &F) {
4596
4597 // Walk all instructions to find interesting instructions that might be
4598 // queried by abstract attributes during their initialization or update.
4599 // This has to happen before we create attributes.
4600 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
4601 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
4602
4603 for (Instruction &I : instructions(&F)) {
4604 bool IsInterestingOpcode = false;
4605
4606 // To allow easy access to all instructions in a function with a given
4607 // opcode we store them in the InfoCache. As not all opcodes are interesting
4608 // to concrete attributes we only cache the ones that are as identified in
4609 // the following switch.
4610 // Note: There are no concrete attributes now so this is initially empty.
4611 switch (I.getOpcode()) {
4612 default:
4613 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
4614 "New call site/base instruction type needs to be known int the "
4615 "Attributor.");
4616 break;
4617 case Instruction::Load:
4618 // The alignment of a pointer is interesting for loads.
4619 case Instruction::Store:
4620 // The alignment of a pointer is interesting for stores.
4621 case Instruction::Call:
4622 case Instruction::CallBr:
4623 case Instruction::Invoke:
4624 case Instruction::CleanupRet:
4625 case Instruction::CatchSwitch:
4626 case Instruction::Resume:
4627 case Instruction::Ret:
4628 IsInterestingOpcode = true;
4629 }
4630 if (IsInterestingOpcode)
4631 InstOpcodeMap[I.getOpcode()].push_back(&I);
4632 if (I.mayReadOrWriteMemory())
4633 ReadOrWriteInsts.push_back(&I);
4634 }
4635}
4636
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004637void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00004638 if (!VisitedFunctions.insert(&F).second)
4639 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004640
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004641 IRPosition FPos = IRPosition::function(F);
4642
Johannes Doerfert305b9612019-08-04 18:40:01 +00004643 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00004644 // We need dead instruction detection because we do not want to deal with
4645 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004646 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00004647
4648 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004649 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00004650
Stefan Stipanovic53605892019-06-27 11:27:54 +00004651 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004652 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00004653
Stefan Stipanovic06263672019-07-11 21:37:40 +00004654 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004655 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00004656
Hideto Ueno65bbaf92019-07-12 17:38:51 +00004657 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004658 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00004659
Johannes Doerferte83f3032019-08-05 23:22:05 +00004660 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004661 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00004662
Hideto Ueno63f60662019-09-21 15:13:19 +00004663 // Every function might be "no-recurse".
4664 getOrCreateAAFor<AANoRecurse>(FPos);
4665
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004666 // Every function might be "readnone/readonly/writeonly/...".
4667 getOrCreateAAFor<AAMemoryBehavior>(FPos);
4668
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004669 // Every function might be applicable for Heap-To-Stack conversion.
4670 if (EnableHeapToStack)
4671 getOrCreateAAFor<AAHeapToStack>(FPos);
4672
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00004673 // Return attributes are only appropriate if the return type is non void.
4674 Type *ReturnType = F.getReturnType();
4675 if (!ReturnType->isVoidTy()) {
4676 // Argument attribute "returned" --- Create only one per function even
4677 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004678 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00004679
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004680 IRPosition RetPos = IRPosition::returned(F);
4681
4682 // Every function might be simplified.
4683 getOrCreateAAFor<AAValueSimplify>(RetPos);
4684
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004685 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004686
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004687 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004688 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004689
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004690 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004691 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004692
4693 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004694 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004695
4696 // Every function with pointer return type might be marked
4697 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004698 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00004699 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00004700 }
4701
Hideto Ueno54869ec2019-07-15 06:49:04 +00004702 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004703 IRPosition ArgPos = IRPosition::argument(Arg);
4704
4705 // Every argument might be simplified.
4706 getOrCreateAAFor<AAValueSimplify>(ArgPos);
4707
Hideto Ueno19c07af2019-07-23 08:16:17 +00004708 if (Arg.getType()->isPointerTy()) {
4709 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004710 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004711
Hideto Uenocbab3342019-08-29 05:52:00 +00004712 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004713 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00004714
Hideto Ueno19c07af2019-07-23 08:16:17 +00004715 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004716 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004717
4718 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004719 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004720
4721 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004722 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004723
4724 // Every argument with pointer type might be marked
4725 // "readnone/readonly/writeonly/..."
4726 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004727 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00004728 }
4729
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004730 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004731 CallSite CS(&I);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004732 if (CS.getCalledFunction()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00004733 for (int i = 0, e = CS.getCalledFunction()->arg_size(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004734
4735 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
4736
4737 // Call site argument might be simplified.
4738 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
4739
Hideto Ueno54869ec2019-07-15 06:49:04 +00004740 if (!CS.getArgument(i)->getType()->isPointerTy())
4741 continue;
4742
4743 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004744 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00004745
Hideto Uenocbab3342019-08-29 05:52:00 +00004746 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004747 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00004748
Hideto Ueno19c07af2019-07-23 08:16:17 +00004749 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004750 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00004751
4752 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00004753 getOrCreateAAFor<AAAlign>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00004754 }
4755 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004756 return true;
4757 };
4758
4759 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
4760 bool Success, AnyDead = false;
4761 Success = checkForAllInstructionsImpl(
4762 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
4763 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
4764 (unsigned)Instruction::Call});
4765 (void)Success;
4766 assert(Success && !AnyDead && "Expected the check call to be successful!");
4767
4768 auto LoadStorePred = [&](Instruction &I) -> bool {
4769 if (isa<LoadInst>(I))
4770 getOrCreateAAFor<AAAlign>(
4771 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
4772 else
4773 getOrCreateAAFor<AAAlign>(
4774 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
4775 return true;
4776 };
4777 Success = checkForAllInstructionsImpl(
4778 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
4779 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
4780 (void)Success;
4781 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00004782}
4783
4784/// Helpers to ease debugging through output streams and print calls.
4785///
4786///{
4787raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
4788 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
4789}
4790
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004791raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004792 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004793 case IRPosition::IRP_INVALID:
4794 return OS << "inv";
4795 case IRPosition::IRP_FLOAT:
4796 return OS << "flt";
4797 case IRPosition::IRP_RETURNED:
4798 return OS << "fn_ret";
4799 case IRPosition::IRP_CALL_SITE_RETURNED:
4800 return OS << "cs_ret";
4801 case IRPosition::IRP_FUNCTION:
4802 return OS << "fn";
4803 case IRPosition::IRP_CALL_SITE:
4804 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004805 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00004806 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004807 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00004808 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00004809 }
4810 llvm_unreachable("Unknown attribute position!");
4811}
4812
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004813raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004814 const Value &AV = Pos.getAssociatedValue();
4815 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004816 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
4817}
4818
Johannes Doerfertacc80792019-08-12 22:07:34 +00004819raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerState &S) {
4820 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
4821 << static_cast<const AbstractState &>(S);
4822}
4823
Johannes Doerfertaade7822019-06-05 03:02:24 +00004824raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
4825 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
4826}
4827
4828raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
4829 AA.print(OS);
4830 return OS;
4831}
4832
4833void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004834 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
4835 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00004836}
4837///}
4838
4839/// ----------------------------------------------------------------------------
4840/// Pass (Manager) Boilerplate
4841/// ----------------------------------------------------------------------------
4842
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004843static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004844 if (DisableAttributor)
4845 return false;
4846
4847 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
4848 << " functions.\n");
4849
4850 // Create an Attributor and initially empty information cache that is filled
4851 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00004852 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00004853 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004854
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00004855 for (Function &F : M)
4856 A.initializeInformationCache(F);
4857
Johannes Doerfertaade7822019-06-05 03:02:24 +00004858 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004859 if (F.hasExactDefinition())
4860 NumFnWithExactDefinition++;
4861 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00004862 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004863
Johannes Doerfert2f622062019-09-04 16:35:20 +00004864 // We look at internal functions only on-demand but if any use is not a
4865 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00004866 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00004867 if (llvm::all_of(F.uses(), [](const Use &U) {
4868 return ImmutableCallSite(U.getUser()) &&
4869 ImmutableCallSite(U.getUser()).isCallee(&U);
4870 }))
4871 continue;
4872 }
4873
Johannes Doerfertaade7822019-06-05 03:02:24 +00004874 // Populate the Attributor with abstract attribute opportunities in the
4875 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004876 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004877 }
4878
Johannes Doerfert2f622062019-09-04 16:35:20 +00004879 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00004880}
4881
4882PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00004883 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004884 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00004885 // FIXME: Think about passes we will preserve and add them here.
4886 return PreservedAnalyses::none();
4887 }
4888 return PreservedAnalyses::all();
4889}
4890
4891namespace {
4892
4893struct AttributorLegacyPass : public ModulePass {
4894 static char ID;
4895
4896 AttributorLegacyPass() : ModulePass(ID) {
4897 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
4898 }
4899
4900 bool runOnModule(Module &M) override {
4901 if (skipModule(M))
4902 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004903
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00004904 AnalysisGetter AG;
4905 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00004906 }
4907
4908 void getAnalysisUsage(AnalysisUsage &AU) const override {
4909 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004910 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00004911 }
4912};
4913
4914} // end anonymous namespace
4915
4916Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
4917
4918char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004919
4920const char AAReturnedValues::ID = 0;
4921const char AANoUnwind::ID = 0;
4922const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00004923const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004924const char AANonNull::ID = 0;
4925const char AANoRecurse::ID = 0;
4926const char AAWillReturn::ID = 0;
4927const char AANoAlias::ID = 0;
4928const char AANoReturn::ID = 0;
4929const char AAIsDead::ID = 0;
4930const char AADereferenceable::ID = 0;
4931const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004932const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004933const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004934const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004935const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00004936
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004937// Macro magic to create the static generator function for attributes that
4938// follow the naming scheme.
4939
4940#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
4941 case IRPosition::PK: \
4942 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
4943
4944#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
4945 case IRPosition::PK: \
4946 AA = new CLASS##SUFFIX(IRP); \
4947 break;
4948
4949#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4950 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4951 CLASS *AA = nullptr; \
4952 switch (IRP.getPositionKind()) { \
4953 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4954 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
4955 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
4956 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
4957 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
4958 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
4959 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4960 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4961 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004962 return *AA; \
4963 }
4964
4965#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4966 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4967 CLASS *AA = nullptr; \
4968 switch (IRP.getPositionKind()) { \
4969 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4970 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
4971 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
4972 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4973 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4974 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
4975 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4976 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4977 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00004978 return *AA; \
4979 }
4980
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004981#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4982 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4983 CLASS *AA = nullptr; \
4984 switch (IRP.getPositionKind()) { \
4985 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
4986 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
4987 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
4988 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
4989 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
4990 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
4991 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
4992 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
4993 } \
4994 return *AA; \
4995 }
4996
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004997#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
4998 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
4999 CLASS *AA = nullptr; \
5000 switch (IRP.getPositionKind()) { \
5001 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5002 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
5003 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
5004 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5005 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
5006 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
5007 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
5008 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5009 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005010 return *AA; \
5011 }
5012
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005013#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
5014 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
5015 CLASS *AA = nullptr; \
5016 switch (IRP.getPositionKind()) { \
5017 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
5018 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
5019 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
5020 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
5021 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
5022 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
5023 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
5024 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
5025 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005026 return *AA; \
5027 }
5028
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005029CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
5030CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
5031CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
5032CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
5033CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
5034CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
5035CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
5036CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
5037
5038CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
5039CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
5040CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
5041CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00005042CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005043
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005044CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
5045
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005046CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
5047
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005048CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
5049
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005050#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005051#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00005052#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005053#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00005054#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005055#undef SWITCH_PK_CREATE
5056#undef SWITCH_PK_INV
5057
Johannes Doerfertaade7822019-06-05 03:02:24 +00005058INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
5059 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005060INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00005061INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
5062 "Deduce and propagate attributes", false, false)