blob: 46e5c16990e205bb870e1d9a3607a330e6bdd766 [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 Ueno188f9a32020-01-15 15:25:52 +090026#include "llvm/Analysis/LazyValueInfo.h"
Hideto Ueno19c07af2019-07-23 08:16:17 +000027#include "llvm/Analysis/Loads.h"
Stefan Stipanovic431141c2019-09-15 21:47:41 +000028#include "llvm/Analysis/MemoryBuiltins.h"
Hideto Ueno188f9a32020-01-15 15:25:52 +090029#include "llvm/Analysis/ScalarEvolution.h"
Hideto Ueno54869ec2019-07-15 06:49:04 +000030#include "llvm/Analysis/ValueTracking.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000031#include "llvm/IR/Argument.h"
32#include "llvm/IR/Attributes.h"
Hideto Ueno11d37102019-07-17 15:15:43 +000033#include "llvm/IR/CFG.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000034#include "llvm/IR/InstIterator.h"
Stefan Stipanovic06263672019-07-11 21:37:40 +000035#include "llvm/IR/IntrinsicInst.h"
Johannes Doerferta4088c72020-01-07 16:01:57 -060036#include "llvm/IR/Verifier.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080037#include "llvm/InitializePasses.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000038#include "llvm/Support/CommandLine.h"
39#include "llvm/Support/Debug.h"
40#include "llvm/Support/raw_ostream.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000041#include "llvm/Transforms/Utils/BasicBlockUtils.h"
42#include "llvm/Transforms/Utils/Local.h"
43
Johannes Doerfertaade7822019-06-05 03:02:24 +000044#include <cassert>
45
46using namespace llvm;
47
48#define DEBUG_TYPE "attributor"
49
50STATISTIC(NumFnWithExactDefinition,
51 "Number of function with exact definitions");
52STATISTIC(NumFnWithoutExactDefinition,
53 "Number of function without exact definitions");
54STATISTIC(NumAttributesTimedOut,
55 "Number of abstract attributes timed out before fixpoint");
56STATISTIC(NumAttributesValidFixpoint,
57 "Number of abstract attributes in a valid fixpoint state");
58STATISTIC(NumAttributesManifested,
59 "Number of abstract attributes manifested in IR");
Johannes Doerfert680f6382019-11-02 02:48:05 -050060STATISTIC(NumAttributesFixedDueToRequiredDependences,
61 "Number of abstract attributes fixed due to required dependences");
Johannes Doerfertaade7822019-06-05 03:02:24 +000062
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000063// Some helper macros to deal with statistics tracking.
64//
65// Usage:
66// For simple IR attribute tracking overload trackStatistics in the abstract
Johannes Doerfert17b578b2019-08-14 21:46:25 +000067// attribute and choose the right STATS_DECLTRACK_********* macro,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000068// e.g.,:
69// void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +000070// STATS_DECLTRACK_ARG_ATTR(returned)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000071// }
72// If there is a single "increment" side one can use the macro
Johannes Doerfert17b578b2019-08-14 21:46:25 +000073// STATS_DECLTRACK with a custom message. If there are multiple increment
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000074// sides, STATS_DECL and STATS_TRACK can also be used separatly.
75//
76#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
77 ("Number of " #TYPE " marked '" #NAME "'")
78#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
Johannes Doerferta7a3b3a2019-09-04 19:01:08 +000079#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
80#define STATS_DECL(NAME, TYPE, MSG) \
81 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000082#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
Johannes Doerfert17b578b2019-08-14 21:46:25 +000083#define STATS_DECLTRACK(NAME, TYPE, MSG) \
Johannes Doerfert169af992019-08-20 06:09:56 +000084 { \
85 STATS_DECL(NAME, TYPE, MSG) \
86 STATS_TRACK(NAME, TYPE) \
87 }
Johannes Doerfert17b578b2019-08-14 21:46:25 +000088#define STATS_DECLTRACK_ARG_ATTR(NAME) \
89 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
90#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
91 STATS_DECLTRACK(NAME, CSArguments, \
92 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
93#define STATS_DECLTRACK_FN_ATTR(NAME) \
94 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
95#define STATS_DECLTRACK_CS_ATTR(NAME) \
96 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
97#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
98 STATS_DECLTRACK(NAME, FunctionReturn, \
Johannes Doerfert2db85282019-08-21 20:56:56 +000099 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000100#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
101 STATS_DECLTRACK(NAME, CSReturn, \
102 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
103#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
104 STATS_DECLTRACK(NAME, Floating, \
105 ("Number of floating values known to be '" #NAME "'"))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000106
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600107// Specialization of the operator<< for abstract attributes subclasses. This
108// disambiguates situations where multiple operators are applicable.
109namespace llvm {
110#define PIPE_OPERATOR(CLASS) \
111 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
112 return OS << static_cast<const AbstractAttribute &>(AA); \
113 }
114
115PIPE_OPERATOR(AAIsDead)
116PIPE_OPERATOR(AANoUnwind)
117PIPE_OPERATOR(AANoSync)
118PIPE_OPERATOR(AANoRecurse)
119PIPE_OPERATOR(AAWillReturn)
120PIPE_OPERATOR(AANoReturn)
121PIPE_OPERATOR(AAReturnedValues)
122PIPE_OPERATOR(AANonNull)
123PIPE_OPERATOR(AANoAlias)
124PIPE_OPERATOR(AADereferenceable)
125PIPE_OPERATOR(AAAlign)
126PIPE_OPERATOR(AANoCapture)
127PIPE_OPERATOR(AAValueSimplify)
128PIPE_OPERATOR(AANoFree)
129PIPE_OPERATOR(AAHeapToStack)
130PIPE_OPERATOR(AAReachability)
131PIPE_OPERATOR(AAMemoryBehavior)
Hideto Ueno188f9a32020-01-15 15:25:52 +0900132PIPE_OPERATOR(AAValueConstantRange)
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600133
134#undef PIPE_OPERATOR
135} // namespace llvm
136
Johannes Doerfertaade7822019-06-05 03:02:24 +0000137// TODO: Determine a good default value.
138//
139// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
140// (when run with the first 5 abstract attributes). The results also indicate
141// that we never reach 32 iterations but always find a fixpoint sooner.
142//
143// This will become more evolved once we perform two interleaved fixpoint
144// iterations: bottom-up and top-down.
145static cl::opt<unsigned>
146 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
147 cl::desc("Maximal number of fixpoint iterations."),
148 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000149static cl::opt<bool> VerifyMaxFixpointIterations(
150 "attributor-max-iterations-verify", cl::Hidden,
151 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
152 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000153
154static cl::opt<bool> DisableAttributor(
155 "attributor-disable", cl::Hidden,
156 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000157 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000158
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500159static cl::opt<bool> AnnotateDeclarationCallSites(
160 "attributor-annotate-decl-cs", cl::Hidden,
James Hendersond68904f2020-01-06 10:15:44 +0000161 cl::desc("Annotate call sites of function declarations."), cl::init(false));
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500162
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000163static cl::opt<bool> ManifestInternal(
164 "attributor-manifest-internal", cl::Hidden,
165 cl::desc("Manifest Attributor internal string attributes."),
166 cl::init(false));
167
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000168static cl::opt<unsigned> DepRecInterval(
169 "attributor-dependence-recompute-interval", cl::Hidden,
170 cl::desc("Number of iterations until dependences are recomputed."),
171 cl::init(4));
172
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000173static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
174 cl::init(true), cl::Hidden);
175
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000176static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
177 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000178
Johannes Doerfertaade7822019-06-05 03:02:24 +0000179/// Logic operators for the change status enum class.
180///
181///{
182ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
183 return l == ChangeStatus::CHANGED ? l : r;
184}
185ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
186 return l == ChangeStatus::UNCHANGED ? l : r;
187}
188///}
189
Johannes Doerfertb1b441d2019-10-10 01:19:57 -0500190Argument *IRPosition::getAssociatedArgument() const {
191 if (getPositionKind() == IRP_ARGUMENT)
192 return cast<Argument>(&getAnchorValue());
193
194 // Not an Argument and no argument number means this is not a call site
195 // argument, thus we cannot find a callback argument to return.
196 int ArgNo = getArgNo();
197 if (ArgNo < 0)
198 return nullptr;
199
200 // Use abstract call sites to make the connection between the call site
201 // values and the ones in callbacks. If a callback was found that makes use
202 // of the underlying call site operand, we want the corresponding callback
203 // callee argument and not the direct callee argument.
204 Optional<Argument *> CBCandidateArg;
205 SmallVector<const Use *, 4> CBUses;
206 ImmutableCallSite ICS(&getAnchorValue());
207 AbstractCallSite::getCallbackUses(ICS, CBUses);
208 for (const Use *U : CBUses) {
209 AbstractCallSite ACS(U);
210 assert(ACS && ACS.isCallbackCall());
211 if (!ACS.getCalledFunction())
212 continue;
213
214 for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {
215
216 // Test if the underlying call site operand is argument number u of the
217 // callback callee.
218 if (ACS.getCallArgOperandNo(u) != ArgNo)
219 continue;
220
221 assert(ACS.getCalledFunction()->arg_size() > u &&
222 "ACS mapped into var-args arguments!");
223 if (CBCandidateArg.hasValue()) {
224 CBCandidateArg = nullptr;
225 break;
226 }
227 CBCandidateArg = ACS.getCalledFunction()->getArg(u);
228 }
229 }
230
231 // If we found a unique callback candidate argument, return it.
232 if (CBCandidateArg.hasValue() && CBCandidateArg.getValue())
233 return CBCandidateArg.getValue();
234
235 // If no callbacks were found, or none used the underlying call site operand
236 // exclusively, use the direct callee argument if available.
237 const Function *Callee = ICS.getCalledFunction();
238 if (Callee && Callee->arg_size() > unsigned(ArgNo))
239 return Callee->getArg(ArgNo);
240
241 return nullptr;
242}
243
Johannes Doerfert5d346022019-12-13 22:11:42 -0600244/// For calls (and invokes) we will only replace instruction uses to not disturb
245/// the old style call graph.
246/// TODO: Remove this once we get rid of the old PM.
247static void replaceAllInstructionUsesWith(Value &Old, Value &New) {
248 if (!isa<CallBase>(Old))
249 return Old.replaceAllUsesWith(&New);
250 SmallVector<Use *, 8> Uses;
251 for (Use &U : Old.uses())
252 if (isa<Instruction>(U.getUser()))
253 Uses.push_back(&U);
254 for (Use *U : Uses)
255 U->set(&New);
256}
257
Johannes Doerfertdef99282019-08-14 21:29:37 +0000258/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000259/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000260/// with the "returned" attribute. Once we cannot look through the value any
261/// further, the callback \p VisitValueCB is invoked and passed the current
262/// value, the \p State, and a flag to indicate if we stripped anything. To
263/// limit how much effort is invested, we will never visit more values than
264/// specified by \p MaxValues.
265template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000266static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000267 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000268 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000269 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000270
Johannes Doerfertdef99282019-08-14 21:29:37 +0000271 const AAIsDead *LivenessAA = nullptr;
272 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000273 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000274 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
275 /* TrackDependence */ false);
276 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000277
278 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000279 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000280 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000281 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000282
283 int Iteration = 0;
284 do {
285 Value *V = Worklist.pop_back_val();
286
287 // Check if we should process the current value. To prevent endless
288 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000289 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000290 continue;
291
292 // Make sure we limit the compile time for complex expressions.
293 if (Iteration++ >= MaxValues)
294 return false;
295
296 // Explicitly look through calls with a "returned" attribute if we do
297 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000298 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000299 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000300 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000301 } else {
302 CallSite CS(V);
303 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000304 for (Argument &Arg : CS.getCalledFunction()->args())
305 if (Arg.hasReturnedAttr()) {
306 NewV = CS.getArgOperand(Arg.getArgNo());
307 break;
308 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000309 }
310 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000311 if (NewV && NewV != V) {
312 Worklist.push_back(NewV);
313 continue;
314 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000315
316 // Look through select instructions, visit both potential values.
317 if (auto *SI = dyn_cast<SelectInst>(V)) {
318 Worklist.push_back(SI->getTrueValue());
319 Worklist.push_back(SI->getFalseValue());
320 continue;
321 }
322
Johannes Doerfertdef99282019-08-14 21:29:37 +0000323 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000324 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000325 assert(LivenessAA &&
326 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000327 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
328 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000329 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000330 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000331 continue;
332 }
333 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000334 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000335 continue;
336 }
337
338 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000339 if (!VisitValueCB(*V, State, Iteration > 1))
340 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000341 } while (!Worklist.empty());
342
Johannes Doerfert19b00432019-08-26 17:48:05 +0000343 // If we actually used liveness information so we have to record a dependence.
344 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -0500345 A.recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000346
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000347 // All values have been visited.
348 return true;
349}
350
Johannes Doerfertaade7822019-06-05 03:02:24 +0000351/// Return true if \p New is equal or worse than \p Old.
352static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
353 if (!Old.isIntAttribute())
354 return true;
355
356 return Old.getValueAsInt() >= New.getValueAsInt();
357}
358
359/// Return true if the information provided by \p Attr was added to the
360/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000361/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000362static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000363 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000364
365 if (Attr.isEnumAttribute()) {
366 Attribute::AttrKind Kind = Attr.getKindAsEnum();
367 if (Attrs.hasAttribute(AttrIdx, Kind))
368 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
369 return false;
370 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
371 return true;
372 }
373 if (Attr.isStringAttribute()) {
374 StringRef Kind = Attr.getKindAsString();
375 if (Attrs.hasAttribute(AttrIdx, Kind))
376 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
377 return false;
378 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
379 return true;
380 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000381 if (Attr.isIntAttribute()) {
382 Attribute::AttrKind Kind = Attr.getKindAsEnum();
383 if (Attrs.hasAttribute(AttrIdx, Kind))
384 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
385 return false;
386 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
387 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
388 return true;
389 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000390
391 llvm_unreachable("Expected enum or string attribute!");
392}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000393
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000394static const Value *
395getBasePointerOfAccessPointerOperand(const Instruction *I, int64_t &BytesOffset,
396 const DataLayout &DL,
397 bool AllowNonInbounds = false) {
Hideto Uenoef4febd2019-12-29 17:34:08 +0900398 const Value *Ptr =
399 Attributor::getPointerOperand(I, /* AllowVolatile */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000400 if (!Ptr)
401 return nullptr;
402
403 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000404 AllowNonInbounds);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000405}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000406
Johannes Doerfertece81902019-08-12 22:05:53 +0000407ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000408 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
409 if (getState().isAtFixpoint())
410 return HasChanged;
411
412 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
413
Johannes Doerfertece81902019-08-12 22:05:53 +0000414 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000415
416 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
417 << "\n");
418
419 return HasChanged;
420}
421
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000422ChangeStatus
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500423IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000424 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000425 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000426 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000427
Johannes Doerfertaade7822019-06-05 03:02:24 +0000428 // In the following some generic code that will manifest attributes in
429 // DeducedAttrs if they improve the current IR. Due to the different
430 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000431
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000432 AttributeList Attrs;
433 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000434 case IRPosition::IRP_INVALID:
435 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000436 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000437 case IRPosition::IRP_ARGUMENT:
438 case IRPosition::IRP_FUNCTION:
439 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000440 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000441 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000442 case IRPosition::IRP_CALL_SITE:
443 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000444 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000445 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000446 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000447 }
448
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000449 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000450 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000451 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000452 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000453 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000454
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000455 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000456 }
457
458 if (HasChanged == ChangeStatus::UNCHANGED)
459 return HasChanged;
460
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000461 switch (PK) {
462 case IRPosition::IRP_ARGUMENT:
463 case IRPosition::IRP_FUNCTION:
464 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000465 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000466 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000467 case IRPosition::IRP_CALL_SITE:
468 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000469 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000470 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000471 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000472 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000473 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000474 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000475 }
476
477 return HasChanged;
478}
479
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000480const IRPosition IRPosition::EmptyKey(255);
481const IRPosition IRPosition::TombstoneKey(256);
482
483SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
484 IRPositions.emplace_back(IRP);
485
486 ImmutableCallSite ICS(&IRP.getAnchorValue());
487 switch (IRP.getPositionKind()) {
488 case IRPosition::IRP_INVALID:
489 case IRPosition::IRP_FLOAT:
490 case IRPosition::IRP_FUNCTION:
491 return;
492 case IRPosition::IRP_ARGUMENT:
493 case IRPosition::IRP_RETURNED:
494 IRPositions.emplace_back(
495 IRPosition::function(*IRP.getAssociatedFunction()));
496 return;
497 case IRPosition::IRP_CALL_SITE:
498 assert(ICS && "Expected call site!");
499 // TODO: We need to look at the operand bundles similar to the redirection
500 // in CallBase.
501 if (!ICS.hasOperandBundles())
502 if (const Function *Callee = ICS.getCalledFunction())
503 IRPositions.emplace_back(IRPosition::function(*Callee));
504 return;
505 case IRPosition::IRP_CALL_SITE_RETURNED:
506 assert(ICS && "Expected call site!");
507 // TODO: We need to look at the operand bundles similar to the redirection
508 // in CallBase.
509 if (!ICS.hasOperandBundles()) {
510 if (const Function *Callee = ICS.getCalledFunction()) {
511 IRPositions.emplace_back(IRPosition::returned(*Callee));
512 IRPositions.emplace_back(IRPosition::function(*Callee));
513 }
514 }
515 IRPositions.emplace_back(
516 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
517 return;
518 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
519 int ArgNo = IRP.getArgNo();
520 assert(ICS && ArgNo >= 0 && "Expected call site!");
521 // TODO: We need to look at the operand bundles similar to the redirection
522 // in CallBase.
523 if (!ICS.hasOperandBundles()) {
524 const Function *Callee = ICS.getCalledFunction();
525 if (Callee && Callee->arg_size() > unsigned(ArgNo))
526 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
527 if (Callee)
528 IRPositions.emplace_back(IRPosition::function(*Callee));
529 }
530 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
531 return;
532 }
533 }
534}
535
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000536bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
537 bool IgnoreSubsumingPositions) const {
538 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000539 for (Attribute::AttrKind AK : AKs)
540 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
541 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000542 // The first position returned by the SubsumingPositionIterator is
543 // always the position itself. If we ignore subsuming positions we
544 // are done after the first iteration.
545 if (IgnoreSubsumingPositions)
546 break;
547 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000548 return false;
549}
550
551void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600552 SmallVectorImpl<Attribute> &Attrs,
553 bool IgnoreSubsumingPositions) const {
554 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000555 for (Attribute::AttrKind AK : AKs) {
556 const Attribute &Attr = EquivIRP.getAttr(AK);
557 if (Attr.getKindAsEnum() == AK)
558 Attrs.push_back(Attr);
559 }
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600560 // The first position returned by the SubsumingPositionIterator is
561 // always the position itself. If we ignore subsuming positions we
562 // are done after the first iteration.
563 if (IgnoreSubsumingPositions)
564 break;
565 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000566}
567
568void IRPosition::verify() {
569 switch (KindOrArgNo) {
570 default:
571 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
572 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
573 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000574 if (isa<Argument>(AnchorVal)) {
575 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000576 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000577 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
578 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000579 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000580 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000581 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000582 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
583 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000584 "Associated value mismatch!");
585 }
586 break;
587 case IRP_INVALID:
588 assert(!AnchorVal && "Expected no value for an invalid position!");
589 break;
590 case IRP_FLOAT:
591 assert((!isa<CallBase>(&getAssociatedValue()) &&
592 !isa<Argument>(&getAssociatedValue())) &&
593 "Expected specialized kind for call base and argument values!");
594 break;
595 case IRP_RETURNED:
596 assert(isa<Function>(AnchorVal) &&
597 "Expected function for a 'returned' position!");
598 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
599 break;
600 case IRP_CALL_SITE_RETURNED:
601 assert((isa<CallBase>(AnchorVal)) &&
602 "Expected call base for 'call site returned' position!");
603 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
604 break;
605 case IRP_CALL_SITE:
606 assert((isa<CallBase>(AnchorVal)) &&
607 "Expected call base for 'call site function' position!");
608 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
609 break;
610 case IRP_FUNCTION:
611 assert(isa<Function>(AnchorVal) &&
612 "Expected function for a 'function' position!");
613 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
614 break;
615 }
616}
617
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000618namespace {
Johannes Doerfert1a746452019-10-20 22:28:49 -0500619/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000620/// information in \p R and indicate/return if \p S did change (as-in update is
621/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000622template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500623ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000624 auto Assumed = S.getAssumed();
625 S ^= R;
626 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
627 : ChangeStatus::CHANGED;
628}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000629
Johannes Doerfert234eda52019-08-16 19:51:23 +0000630/// Clamp the information known for all returned values of a function
631/// (identified by \p QueryingAA) into \p S.
632template <typename AAType, typename StateType = typename AAType::StateType>
633static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
634 StateType &S) {
635 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600636 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000637
638 assert((QueryingAA.getIRPosition().getPositionKind() ==
639 IRPosition::IRP_RETURNED ||
640 QueryingAA.getIRPosition().getPositionKind() ==
641 IRPosition::IRP_CALL_SITE_RETURNED) &&
642 "Can only clamp returned value states for a function returned or call "
643 "site returned position!");
644
645 // Use an optional state as there might not be any return values and we want
646 // to join (IntegerState::operator&) the state of all there are.
647 Optional<StateType> T;
648
649 // Callback for each possibly returned value.
650 auto CheckReturnValue = [&](Value &RV) -> bool {
651 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000652 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
653 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
654 << " @ " << RVPos << "\n");
655 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000656 if (T.hasValue())
657 *T &= AAS;
658 else
659 T = AAS;
660 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
661 << "\n");
662 return T->isValidState();
663 };
664
665 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
666 S.indicatePessimisticFixpoint();
667 else if (T.hasValue())
668 S ^= *T;
669}
670
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000671/// Helper class to compose two generic deduction
672template <typename AAType, typename Base, typename StateType,
673 template <typename...> class F, template <typename...> class G>
674struct AAComposeTwoGenericDeduction
675 : public F<AAType, G<AAType, Base, StateType>, StateType> {
676 AAComposeTwoGenericDeduction(const IRPosition &IRP)
677 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
678
679 /// See AbstractAttribute::updateImpl(...).
680 ChangeStatus updateImpl(Attributor &A) override {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100681 ChangeStatus ChangedF =
682 F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000683 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
684 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000685 }
686};
687
Johannes Doerfert234eda52019-08-16 19:51:23 +0000688/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000689template <typename AAType, typename Base,
690 typename StateType = typename AAType::StateType>
691struct AAReturnedFromReturnedValues : public Base {
692 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000693
694 /// See AbstractAttribute::updateImpl(...).
695 ChangeStatus updateImpl(Attributor &A) override {
696 StateType S;
697 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000698 // TODO: If we know we visited all returned values, thus no are assumed
699 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000700 return clampStateAndIndicateChange<StateType>(this->getState(), S);
701 }
702};
703
704/// Clamp the information known at all call sites for a given argument
705/// (identified by \p QueryingAA) into \p S.
706template <typename AAType, typename StateType = typename AAType::StateType>
707static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
708 StateType &S) {
709 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600710 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000711
712 assert(QueryingAA.getIRPosition().getPositionKind() ==
713 IRPosition::IRP_ARGUMENT &&
714 "Can only clamp call site argument states for an argument position!");
715
716 // Use an optional state as there might not be any return values and we want
717 // to join (IntegerState::operator&) the state of all there are.
718 Optional<StateType> T;
719
720 // The argument number which is also the call site argument number.
721 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
722
Johannes Doerfert661db042019-10-07 23:14:58 +0000723 auto CallSiteCheck = [&](AbstractCallSite ACS) {
724 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
725 // Check if a coresponding argument was found or if it is on not associated
726 // (which can happen for callback calls).
727 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
728 return false;
729
730 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
731 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
732 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000733 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000734 if (T.hasValue())
735 *T &= AAS;
736 else
737 T = AAS;
738 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
739 << "\n");
740 return T->isValidState();
741 };
742
743 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true))
744 S.indicatePessimisticFixpoint();
745 else if (T.hasValue())
746 S ^= *T;
747}
748
749/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000750template <typename AAType, typename Base,
751 typename StateType = typename AAType::StateType>
752struct AAArgumentFromCallSiteArguments : public Base {
753 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000754
755 /// See AbstractAttribute::updateImpl(...).
756 ChangeStatus updateImpl(Attributor &A) override {
757 StateType S;
758 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000759 // TODO: If we know we visited all incoming values, thus no are assumed
760 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000761 return clampStateAndIndicateChange<StateType>(this->getState(), S);
762 }
763};
764
765/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000766template <typename AAType, typename Base,
767 typename StateType = typename AAType::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000768struct AACallSiteReturnedFromReturned : public Base {
769 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000770
771 /// See AbstractAttribute::updateImpl(...).
772 ChangeStatus updateImpl(Attributor &A) override {
773 assert(this->getIRPosition().getPositionKind() ==
774 IRPosition::IRP_CALL_SITE_RETURNED &&
775 "Can only wrap function returned positions for call site returned "
776 "positions!");
777 auto &S = this->getState();
778
779 const Function *AssociatedFunction =
780 this->getIRPosition().getAssociatedFunction();
781 if (!AssociatedFunction)
782 return S.indicatePessimisticFixpoint();
783
784 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000785 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000786 return clampStateAndIndicateChange(
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000787 S, static_cast<const typename AAType::StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000788 }
789};
790
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000791/// Helper class for generic deduction using must-be-executed-context
792/// Base class is required to have `followUse` method.
793
794/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000795/// U - Underlying use.
796/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000797/// `followUse` returns true if the value should be tracked transitively.
798
799template <typename AAType, typename Base,
800 typename StateType = typename AAType::StateType>
801struct AAFromMustBeExecutedContext : public Base {
802 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
803
804 void initialize(Attributor &A) override {
805 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500806 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000807 Instruction *CtxI = IRP.getCtxI();
808
809 if (!CtxI)
810 return;
811
812 for (const Use &U : IRP.getAssociatedValue().uses())
813 Uses.insert(&U);
814 }
815
816 /// See AbstractAttribute::updateImpl(...).
817 ChangeStatus updateImpl(Attributor &A) override {
818 auto BeforeState = this->getState();
819 auto &S = this->getState();
820 Instruction *CtxI = this->getIRPosition().getCtxI();
821 if (!CtxI)
822 return ChangeStatus::UNCHANGED;
823
824 MustBeExecutedContextExplorer &Explorer =
825 A.getInfoCache().getMustBeExecutedContextExplorer();
826
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500827 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100828 for (unsigned u = 0; u < Uses.size(); ++u) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500829 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000830 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500831 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000832 if (Found && Base::followUse(A, U, UserI))
833 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500834 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000835 }
836 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000837
838 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
839 }
840
841private:
842 /// Container for (transitive) uses of the associated value.
843 SetVector<const Use *> Uses;
844};
845
846template <typename AAType, typename Base,
847 typename StateType = typename AAType::StateType>
848using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
849 AAComposeTwoGenericDeduction<AAType, Base, StateType,
850 AAFromMustBeExecutedContext,
851 AAArgumentFromCallSiteArguments>;
852
853template <typename AAType, typename Base,
854 typename StateType = typename AAType::StateType>
855using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
856 AAComposeTwoGenericDeduction<AAType, Base, StateType,
857 AAFromMustBeExecutedContext,
858 AACallSiteReturnedFromReturned>;
859
Stefan Stipanovic53605892019-06-27 11:27:54 +0000860/// -----------------------NoUnwind Function Attribute--------------------------
861
Johannes Doerfert344d0382019-08-07 22:34:26 +0000862struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000863 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000864
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000865 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000866 return getAssumed() ? "nounwind" : "may-unwind";
867 }
868
869 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000870 ChangeStatus updateImpl(Attributor &A) override {
871 auto Opcodes = {
872 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
873 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
874 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
875
876 auto CheckForNoUnwind = [&](Instruction &I) {
877 if (!I.mayThrow())
878 return true;
879
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000880 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
881 const auto &NoUnwindAA =
882 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
883 return NoUnwindAA.isAssumedNoUnwind();
884 }
885 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000886 };
887
888 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
889 return indicatePessimisticFixpoint();
890
891 return ChangeStatus::UNCHANGED;
892 }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000893};
894
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000895struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000896 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000897
898 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000899 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000900};
901
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000902/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000903struct AANoUnwindCallSite final : AANoUnwindImpl {
904 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
905
906 /// See AbstractAttribute::initialize(...).
907 void initialize(Attributor &A) override {
908 AANoUnwindImpl::initialize(A);
909 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000910 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000911 indicatePessimisticFixpoint();
912 }
913
914 /// See AbstractAttribute::updateImpl(...).
915 ChangeStatus updateImpl(Attributor &A) override {
916 // TODO: Once we have call site specific value information we can provide
917 // call site specific liveness information and then it makes
918 // sense to specialize attributes for call sites arguments instead of
919 // redirecting requests to the callee argument.
920 Function *F = getAssociatedFunction();
921 const IRPosition &FnPos = IRPosition::function(*F);
922 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
923 return clampStateAndIndicateChange(
924 getState(),
925 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
926 }
927
928 /// See AbstractAttribute::trackStatistics()
929 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
930};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000931
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000932/// --------------------- Function Return Values -------------------------------
933
934/// "Attribute" that collects all potential returned values and the return
935/// instructions that they arise from.
936///
937/// If there is a unique returned value R, the manifest method will:
938/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +0000939class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000940
941 /// Mapping of values potentially returned by the associated function to the
942 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +0000943 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000944
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000945 /// Mapping to remember the number of returned values for a call site such
946 /// that we can avoid updates if nothing changed.
947 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
948
949 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000950 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000951
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000952 /// State flags
953 ///
954 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000955 bool IsFixed = false;
956 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000957 ///}
958
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000959public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000960 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000961
962 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +0000963 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000964 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000965 IsFixed = false;
966 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000967 ReturnedValues.clear();
968
Johannes Doerfertdef99282019-08-14 21:29:37 +0000969 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000970 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000971 indicatePessimisticFixpoint();
972 return;
973 }
Johannes Doerferte273ac42020-01-12 00:13:03 -0600974 assert(!F->getReturnType()->isVoidTy() &&
975 "Did not expect a void return type!");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000976
977 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000978 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000979
980 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000981 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000982 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000983 auto &ReturnInstSet = ReturnedValues[&Arg];
984 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
985 ReturnInstSet.insert(cast<ReturnInst>(RI));
986
987 indicateOptimisticFixpoint();
988 return;
989 }
990 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000991
992 if (!F->hasExactDefinition())
993 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000994 }
995
996 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000997 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000998
999 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001000 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001001
1002 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001003 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001004
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001005 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00001006 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001007
Johannes Doerfertdef99282019-08-14 21:29:37 +00001008 llvm::iterator_range<iterator> returned_values() override {
1009 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1010 }
1011
1012 llvm::iterator_range<const_iterator> returned_values() const override {
1013 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1014 }
1015
Johannes Doerfert695089e2019-08-23 15:23:49 +00001016 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001017 return UnresolvedCalls;
1018 }
1019
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001020 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001021 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001022 return isValidState() ? ReturnedValues.size() : -1;
1023 }
1024
1025 /// Return an assumed unique return value if a single candidate is found. If
1026 /// there cannot be one, return a nullptr. If it is not clear yet, return the
1027 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001028 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001029
Johannes Doerfert14a04932019-08-07 22:27:24 +00001030 /// See AbstractState::checkForAllReturnedValues(...).
1031 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001032 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001033 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001034
1035 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001036 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001037
1038 /// See AbstractState::isAtFixpoint().
1039 bool isAtFixpoint() const override { return IsFixed; }
1040
1041 /// See AbstractState::isValidState().
1042 bool isValidState() const override { return IsValidState; }
1043
1044 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001045 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001046 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001047 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001048 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001049
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001050 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001051 IsFixed = true;
1052 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001053 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001054 }
1055};
1056
1057ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
1058 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1059
1060 // Bookkeeping.
1061 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001062 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
1063 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001064
1065 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001066 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001067
1068 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
1069 return Changed;
1070
1071 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001072 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
1073 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001074
Johannes Doerfert23400e612019-08-23 17:41:37 +00001075 // Callback to replace the uses of CB with the constant C.
1076 auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +00001077 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +00001078 return ChangeStatus::UNCHANGED;
Johannes Doerfert5d346022019-12-13 22:11:42 -06001079 replaceAllInstructionUsesWith(CB, C);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001080 return ChangeStatus::CHANGED;
1081 };
1082
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001083 // If the assumed unique return value is an argument, annotate it.
1084 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05001085 // TODO: This should be handled differently!
1086 this->AnchorVal = UniqueRVArg;
1087 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +00001088 Changed = IRAttribute::manifest(A);
1089 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
1090 // We can replace the returned value with the unique returned constant.
1091 Value &AnchorValue = getAnchorValue();
1092 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1093 for (const Use &U : F->uses())
1094 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001095 if (CB->isCallee(&U)) {
1096 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001097 CB->getType() == RVC->getType()
1098 ? RVC
1099 : ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001100 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1101 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001102 } else {
1103 assert(isa<CallBase>(AnchorValue) &&
1104 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001105 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001106 AnchorValue.getType() == RVC->getType()
1107 ? RVC
1108 : ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001109 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001110 }
1111 if (Changed == ChangeStatus::CHANGED)
1112 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1113 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001114 }
1115
1116 return Changed;
1117}
1118
1119const std::string AAReturnedValuesImpl::getAsStr() const {
1120 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001121 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001122 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001123}
1124
Johannes Doerfert14a04932019-08-07 22:27:24 +00001125Optional<Value *>
1126AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1127 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001128 // undef values that can also be present, it is assumed to be the actual
1129 // return value and forwarded to the caller of this method. If there are
1130 // multiple, a nullptr is returned indicating there cannot be a unique
1131 // returned value.
1132 Optional<Value *> UniqueRV;
1133
Johannes Doerfert14a04932019-08-07 22:27:24 +00001134 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001135 // If we found a second returned value and neither the current nor the saved
1136 // one is an undef, there is no unique returned value. Undefs are special
1137 // since we can pretend they have any value.
1138 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1139 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1140 UniqueRV = nullptr;
1141 return false;
1142 }
1143
1144 // Do not overwrite a value with an undef.
1145 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1146 UniqueRV = &RV;
1147
1148 return true;
1149 };
1150
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001151 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001152 UniqueRV = nullptr;
1153
1154 return UniqueRV;
1155}
1156
Johannes Doerfert14a04932019-08-07 22:27:24 +00001157bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001158 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001159 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001160 if (!isValidState())
1161 return false;
1162
1163 // Check all returned values but ignore call sites as long as we have not
1164 // encountered an overdefined one during an update.
1165 for (auto &It : ReturnedValues) {
1166 Value *RV = It.first;
1167
Johannes Doerfertdef99282019-08-14 21:29:37 +00001168 CallBase *CB = dyn_cast<CallBase>(RV);
1169 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001170 continue;
1171
Johannes Doerfert695089e2019-08-23 15:23:49 +00001172 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001173 return false;
1174 }
1175
1176 return true;
1177}
1178
Johannes Doerfertece81902019-08-12 22:05:53 +00001179ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001180 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1181 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001182
Johannes Doerfertdef99282019-08-14 21:29:37 +00001183 // State used in the value traversals starting in returned values.
1184 struct RVState {
1185 // The map in which we collect return values -> return instrs.
1186 decltype(ReturnedValues) &RetValsMap;
1187 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001188 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001189 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001190 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001191 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001192
Johannes Doerfertdef99282019-08-14 21:29:37 +00001193 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001194 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001195 auto Size = RVS.RetValsMap[&Val].size();
1196 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1197 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1198 RVS.Changed |= Inserted;
1199 LLVM_DEBUG({
1200 if (Inserted)
1201 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1202 << " => " << RVS.RetInsts.size() << "\n";
1203 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001204 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001205 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001206
Johannes Doerfertdef99282019-08-14 21:29:37 +00001207 // Helper method to invoke the generic value traversal.
1208 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1209 IRPosition RetValPos = IRPosition::value(RV);
1210 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1211 RVS, VisitValueCB);
1212 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001213
Johannes Doerfertdef99282019-08-14 21:29:37 +00001214 // Callback for all "return intructions" live in the associated function.
1215 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1216 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001217 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001218 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001219 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1220 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001221
Johannes Doerfertdef99282019-08-14 21:29:37 +00001222 // Start by discovering returned values from all live returned instructions in
1223 // the associated function.
1224 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1225 return indicatePessimisticFixpoint();
1226
1227 // Once returned values "directly" present in the code are handled we try to
1228 // resolve returned calls.
1229 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001230 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001231 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1232 << " by #" << It.second.size() << " RIs\n");
1233 CallBase *CB = dyn_cast<CallBase>(It.first);
1234 if (!CB || UnresolvedCalls.count(CB))
1235 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001236
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001237 if (!CB->getCalledFunction()) {
1238 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1239 << "\n");
1240 UnresolvedCalls.insert(CB);
1241 continue;
1242 }
1243
1244 // TODO: use the function scope once we have call site AAReturnedValues.
1245 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1246 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001247 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06001248 << RetValAA << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001249
1250 // Skip dead ends, thus if we do not know anything about the returned
1251 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001252 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001253 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1254 << "\n");
1255 UnresolvedCalls.insert(CB);
1256 continue;
1257 }
1258
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001259 // Do not try to learn partial information. If the callee has unresolved
1260 // return values we will treat the call as unresolved/opaque.
1261 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1262 if (!RetValAAUnresolvedCalls.empty()) {
1263 UnresolvedCalls.insert(CB);
1264 continue;
1265 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001266
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001267 // Now check if we can track transitively returned values. If possible, thus
1268 // if all return value can be represented in the current scope, do so.
1269 bool Unresolved = false;
1270 for (auto &RetValAAIt : RetValAA.returned_values()) {
1271 Value *RetVal = RetValAAIt.first;
1272 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1273 isa<Constant>(RetVal))
1274 continue;
1275 // Anything that did not fit in the above categories cannot be resolved,
1276 // mark the call as unresolved.
1277 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1278 "cannot be translated: "
1279 << *RetVal << "\n");
1280 UnresolvedCalls.insert(CB);
1281 Unresolved = true;
1282 break;
1283 }
1284
1285 if (Unresolved)
1286 continue;
1287
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001288 // Now track transitively returned values.
1289 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1290 if (NumRetAA == RetValAA.getNumReturnValues()) {
1291 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1292 "changed since it was seen last\n");
1293 continue;
1294 }
1295 NumRetAA = RetValAA.getNumReturnValues();
1296
Johannes Doerfertdef99282019-08-14 21:29:37 +00001297 for (auto &RetValAAIt : RetValAA.returned_values()) {
1298 Value *RetVal = RetValAAIt.first;
1299 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1300 // Arguments are mapped to call site operands and we begin the traversal
1301 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001302 bool Unused = false;
1303 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001304 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1305 continue;
1306 } else if (isa<CallBase>(RetVal)) {
1307 // Call sites are resolved by the callee attribute over time, no need to
1308 // do anything for us.
1309 continue;
1310 } else if (isa<Constant>(RetVal)) {
1311 // Constants are valid everywhere, we can simply take them.
1312 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1313 continue;
1314 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001315 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001316 }
1317
Johannes Doerfertdef99282019-08-14 21:29:37 +00001318 // To avoid modifications to the ReturnedValues map while we iterate over it
1319 // we kept record of potential new entries in a copy map, NewRVsMap.
1320 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001321 assert(!It.second.empty() && "Entry does not add anything.");
1322 auto &ReturnInsts = ReturnedValues[It.first];
1323 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001324 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001325 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1326 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001327 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001328 }
1329 }
1330
Johannes Doerfertdef99282019-08-14 21:29:37 +00001331 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1332 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001333}
1334
Johannes Doerfertdef99282019-08-14 21:29:37 +00001335struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1336 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1337
1338 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001339 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001340};
1341
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001342/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001343struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1344 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1345
1346 /// See AbstractAttribute::initialize(...).
1347 void initialize(Attributor &A) override {
1348 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001349 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001350 // sense to specialize attributes for call sites instead of
1351 // redirecting requests to the callee.
1352 llvm_unreachable("Abstract attributes for returned values are not "
1353 "supported for call sites yet!");
1354 }
1355
1356 /// See AbstractAttribute::updateImpl(...).
1357 ChangeStatus updateImpl(Attributor &A) override {
1358 return indicatePessimisticFixpoint();
1359 }
1360
1361 /// See AbstractAttribute::trackStatistics()
1362 void trackStatistics() const override {}
1363};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001364
Stefan Stipanovic06263672019-07-11 21:37:40 +00001365/// ------------------------ NoSync Function Attribute -------------------------
1366
Johannes Doerfert344d0382019-08-07 22:34:26 +00001367struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001368 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001369
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001370 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001371 return getAssumed() ? "nosync" : "may-sync";
1372 }
1373
1374 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001375 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001376
Stefan Stipanovic06263672019-07-11 21:37:40 +00001377 /// Helper function used to determine whether an instruction is non-relaxed
1378 /// atomic. In other words, if an atomic instruction does not have unordered
1379 /// or monotonic ordering
1380 static bool isNonRelaxedAtomic(Instruction *I);
1381
1382 /// Helper function used to determine whether an instruction is volatile.
1383 static bool isVolatile(Instruction *I);
1384
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001385 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1386 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001387 static bool isNoSyncIntrinsic(Instruction *I);
1388};
1389
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001390bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001391 if (!I->isAtomic())
1392 return false;
1393
1394 AtomicOrdering Ordering;
1395 switch (I->getOpcode()) {
1396 case Instruction::AtomicRMW:
1397 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1398 break;
1399 case Instruction::Store:
1400 Ordering = cast<StoreInst>(I)->getOrdering();
1401 break;
1402 case Instruction::Load:
1403 Ordering = cast<LoadInst>(I)->getOrdering();
1404 break;
1405 case Instruction::Fence: {
1406 auto *FI = cast<FenceInst>(I);
1407 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1408 return false;
1409 Ordering = FI->getOrdering();
1410 break;
1411 }
1412 case Instruction::AtomicCmpXchg: {
1413 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1414 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1415 // Only if both are relaxed, than it can be treated as relaxed.
1416 // Otherwise it is non-relaxed.
1417 if (Success != AtomicOrdering::Unordered &&
1418 Success != AtomicOrdering::Monotonic)
1419 return true;
1420 if (Failure != AtomicOrdering::Unordered &&
1421 Failure != AtomicOrdering::Monotonic)
1422 return true;
1423 return false;
1424 }
1425 default:
1426 llvm_unreachable(
1427 "New atomic operations need to be known in the attributor.");
1428 }
1429
1430 // Relaxed.
1431 if (Ordering == AtomicOrdering::Unordered ||
1432 Ordering == AtomicOrdering::Monotonic)
1433 return false;
1434 return true;
1435}
1436
1437/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1438/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001439bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001440 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1441 switch (II->getIntrinsicID()) {
1442 /// Element wise atomic memory intrinsics are can only be unordered,
1443 /// therefore nosync.
1444 case Intrinsic::memset_element_unordered_atomic:
1445 case Intrinsic::memmove_element_unordered_atomic:
1446 case Intrinsic::memcpy_element_unordered_atomic:
1447 return true;
1448 case Intrinsic::memset:
1449 case Intrinsic::memmove:
1450 case Intrinsic::memcpy:
1451 if (!cast<MemIntrinsic>(II)->isVolatile())
1452 return true;
1453 return false;
1454 default:
1455 return false;
1456 }
1457 }
1458 return false;
1459}
1460
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001461bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001462 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1463 "Calls should not be checked here");
1464
1465 switch (I->getOpcode()) {
1466 case Instruction::AtomicRMW:
1467 return cast<AtomicRMWInst>(I)->isVolatile();
1468 case Instruction::Store:
1469 return cast<StoreInst>(I)->isVolatile();
1470 case Instruction::Load:
1471 return cast<LoadInst>(I)->isVolatile();
1472 case Instruction::AtomicCmpXchg:
1473 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1474 default:
1475 return false;
1476 }
1477}
1478
Johannes Doerfertece81902019-08-12 22:05:53 +00001479ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001480
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001481 auto CheckRWInstForNoSync = [&](Instruction &I) {
1482 /// We are looking for volatile instructions or Non-Relaxed atomics.
Pankaj Godeb9a26a82019-11-22 14:46:43 +05301483 /// FIXME: We should improve the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001484
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001485 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1486 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001487
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001488 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1489 if (ICS.hasFnAttr(Attribute::NoSync))
1490 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001491
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001492 const auto &NoSyncAA =
1493 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1494 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001495 return true;
1496 return false;
1497 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001498
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001499 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1500 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001501
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001502 return false;
1503 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001504
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001505 auto CheckForNoSync = [&](Instruction &I) {
1506 // At this point we handled all read/write effects and they are all
1507 // nosync, so they can be skipped.
1508 if (I.mayReadOrWriteMemory())
1509 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001510
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001511 // non-convergent and readnone imply nosync.
1512 return !ImmutableCallSite(&I).isConvergent();
1513 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001514
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001515 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1516 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001517 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001518
Stefan Stipanovic06263672019-07-11 21:37:40 +00001519 return ChangeStatus::UNCHANGED;
1520}
1521
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001522struct AANoSyncFunction final : public AANoSyncImpl {
1523 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1524
1525 /// See AbstractAttribute::trackStatistics()
1526 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1527};
1528
1529/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001530struct AANoSyncCallSite final : AANoSyncImpl {
1531 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1532
1533 /// See AbstractAttribute::initialize(...).
1534 void initialize(Attributor &A) override {
1535 AANoSyncImpl::initialize(A);
1536 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001537 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001538 indicatePessimisticFixpoint();
1539 }
1540
1541 /// See AbstractAttribute::updateImpl(...).
1542 ChangeStatus updateImpl(Attributor &A) override {
1543 // TODO: Once we have call site specific value information we can provide
1544 // call site specific liveness information and then it makes
1545 // sense to specialize attributes for call sites arguments instead of
1546 // redirecting requests to the callee argument.
1547 Function *F = getAssociatedFunction();
1548 const IRPosition &FnPos = IRPosition::function(*F);
1549 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1550 return clampStateAndIndicateChange(
1551 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1552 }
1553
1554 /// See AbstractAttribute::trackStatistics()
1555 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1556};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001557
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001558/// ------------------------ No-Free Attributes ----------------------------
1559
Johannes Doerfert344d0382019-08-07 22:34:26 +00001560struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001561 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001562
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001563 /// See AbstractAttribute::updateImpl(...).
1564 ChangeStatus updateImpl(Attributor &A) override {
1565 auto CheckForNoFree = [&](Instruction &I) {
1566 ImmutableCallSite ICS(&I);
1567 if (ICS.hasFnAttr(Attribute::NoFree))
1568 return true;
1569
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001570 const auto &NoFreeAA =
1571 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1572 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001573 };
1574
1575 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1576 return indicatePessimisticFixpoint();
1577 return ChangeStatus::UNCHANGED;
1578 }
1579
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001580 /// See AbstractAttribute::getAsStr().
1581 const std::string getAsStr() const override {
1582 return getAssumed() ? "nofree" : "may-free";
1583 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001584};
1585
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001586struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001587 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001588
1589 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001590 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001591};
1592
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001593/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001594struct AANoFreeCallSite final : AANoFreeImpl {
1595 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1596
1597 /// See AbstractAttribute::initialize(...).
1598 void initialize(Attributor &A) override {
1599 AANoFreeImpl::initialize(A);
1600 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001601 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001602 indicatePessimisticFixpoint();
1603 }
1604
1605 /// See AbstractAttribute::updateImpl(...).
1606 ChangeStatus updateImpl(Attributor &A) override {
1607 // TODO: Once we have call site specific value information we can provide
1608 // call site specific liveness information and then it makes
1609 // sense to specialize attributes for call sites arguments instead of
1610 // redirecting requests to the callee argument.
1611 Function *F = getAssociatedFunction();
1612 const IRPosition &FnPos = IRPosition::function(*F);
1613 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1614 return clampStateAndIndicateChange(
1615 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1616 }
1617
1618 /// See AbstractAttribute::trackStatistics()
1619 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1620};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001621
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001622/// NoFree attribute for floating values.
1623struct AANoFreeFloating : AANoFreeImpl {
1624 AANoFreeFloating(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1625
1626 /// See AbstractAttribute::trackStatistics()
1627 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
1628
1629 /// See Abstract Attribute::updateImpl(...).
1630 ChangeStatus updateImpl(Attributor &A) override {
1631 const IRPosition &IRP = getIRPosition();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001632
1633 const auto &NoFreeAA =
1634 A.getAAFor<AANoFree>(*this, IRPosition::function_scope(IRP));
1635 if (NoFreeAA.isAssumedNoFree())
1636 return ChangeStatus::UNCHANGED;
1637
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001638 Value &AssociatedValue = getIRPosition().getAssociatedValue();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001639 auto Pred = [&](const Use &U, bool &Follow) -> bool {
1640 Instruction *UserI = cast<Instruction>(U.getUser());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001641 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001642 if (CB->isBundleOperand(&U))
1643 return false;
1644 if (!CB->isArgOperand(&U))
1645 return true;
1646 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001647
1648 const auto &NoFreeArg = A.getAAFor<AANoFree>(
1649 *this, IRPosition::callsite_argument(*CB, ArgNo));
Hideto Ueno63599bd2019-12-12 12:26:09 +00001650 return NoFreeArg.isAssumedNoFree();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001651 }
1652
1653 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
1654 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001655 Follow = true;
1656 return true;
Hideto Ueno4ecf2552019-12-12 13:42:40 +00001657 }
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001658
1659 // Unknown user.
Hideto Ueno63599bd2019-12-12 12:26:09 +00001660 return false;
1661 };
1662 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001663 return indicatePessimisticFixpoint();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001664
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001665 return ChangeStatus::UNCHANGED;
1666 }
1667};
1668
1669/// NoFree attribute for a call site argument.
1670struct AANoFreeArgument final : AANoFreeFloating {
1671 AANoFreeArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1672
1673 /// See AbstractAttribute::trackStatistics()
1674 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
1675};
1676
1677/// NoFree attribute for call site arguments.
1678struct AANoFreeCallSiteArgument final : AANoFreeFloating {
1679 AANoFreeCallSiteArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1680
1681 /// See AbstractAttribute::updateImpl(...).
1682 ChangeStatus updateImpl(Attributor &A) override {
1683 // TODO: Once we have call site specific value information we can provide
1684 // call site specific liveness information and then it makes
1685 // sense to specialize attributes for call sites arguments instead of
1686 // redirecting requests to the callee argument.
1687 Argument *Arg = getAssociatedArgument();
1688 if (!Arg)
1689 return indicatePessimisticFixpoint();
1690 const IRPosition &ArgPos = IRPosition::argument(*Arg);
1691 auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
1692 return clampStateAndIndicateChange(
1693 getState(), static_cast<const AANoFree::StateType &>(ArgAA.getState()));
1694 }
1695
1696 /// See AbstractAttribute::trackStatistics()
1697 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
1698};
1699
1700/// NoFree attribute for function return value.
1701struct AANoFreeReturned final : AANoFreeFloating {
1702 AANoFreeReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {
1703 llvm_unreachable("NoFree is not applicable to function returns!");
1704 }
1705
1706 /// See AbstractAttribute::initialize(...).
1707 void initialize(Attributor &A) override {
1708 llvm_unreachable("NoFree is not applicable to function returns!");
1709 }
1710
1711 /// See AbstractAttribute::updateImpl(...).
1712 ChangeStatus updateImpl(Attributor &A) override {
1713 llvm_unreachable("NoFree is not applicable to function returns!");
1714 }
1715
1716 /// See AbstractAttribute::trackStatistics()
1717 void trackStatistics() const override {}
1718};
1719
1720/// NoFree attribute deduction for a call site return value.
1721struct AANoFreeCallSiteReturned final : AANoFreeFloating {
1722 AANoFreeCallSiteReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1723
1724 ChangeStatus manifest(Attributor &A) override {
1725 return ChangeStatus::UNCHANGED;
1726 }
1727 /// See AbstractAttribute::trackStatistics()
1728 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
1729};
1730
Hideto Ueno54869ec2019-07-15 06:49:04 +00001731/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001732static int64_t getKnownNonNullAndDerefBytesForUse(
1733 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1734 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001735 TrackUse = false;
1736
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001737 const Value *UseV = U->get();
1738 if (!UseV->getType()->isPointerTy())
1739 return 0;
1740
1741 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001742 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001743 bool NullPointerIsDefined =
1744 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001745 const DataLayout &DL = A.getInfoCache().getDL();
1746 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1747 if (ICS.isBundleOperand(U))
1748 return 0;
1749
1750 if (ICS.isCallee(U)) {
1751 IsNonNull |= !NullPointerIsDefined;
1752 return 0;
1753 }
1754
1755 unsigned ArgNo = ICS.getArgumentNo(U);
1756 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001757 // As long as we only use known information there is no need to track
1758 // dependences here.
1759 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP,
1760 /* TrackDependence */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001761 IsNonNull |= DerefAA.isKnownNonNull();
1762 return DerefAA.getKnownDereferenceableBytes();
1763 }
1764
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001765 // We need to follow common pointer manipulation uses to the accesses they
1766 // feed into. We can try to be smart to avoid looking through things we do not
1767 // like for now, e.g., non-inbounds GEPs.
1768 if (isa<CastInst>(I)) {
1769 TrackUse = true;
1770 return 0;
1771 }
1772 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001773 if (GEP->hasAllConstantIndices()) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001774 TrackUse = true;
1775 return 0;
1776 }
1777
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001778 int64_t Offset;
1779 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09001780 if (Base == &AssociatedValue &&
1781 Attributor::getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001782 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001783 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001784
1785 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001786 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001787 }
1788 }
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001789
1790 /// Corner case when an offset is 0.
1791 if (const Value *Base = getBasePointerOfAccessPointerOperand(
1792 I, Offset, DL, /*AllowNonInbounds*/ true)) {
1793 if (Offset == 0 && Base == &AssociatedValue &&
Hideto Uenoef4febd2019-12-29 17:34:08 +09001794 Attributor::getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001795 int64_t DerefBytes =
1796 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType());
1797 IsNonNull |= !NullPointerIsDefined;
1798 return std::max(int64_t(0), DerefBytes);
1799 }
1800 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001801
1802 return 0;
1803}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001804
Johannes Doerfert344d0382019-08-07 22:34:26 +00001805struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001806 AANonNullImpl(const IRPosition &IRP)
1807 : AANonNull(IRP),
1808 NullIsDefined(NullPointerIsDefined(
1809 getAnchorScope(),
1810 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001811
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001812 /// See AbstractAttribute::initialize(...).
1813 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001814 if (!NullIsDefined &&
1815 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001816 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001817 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1818 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001819 else
1820 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001821 }
1822
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001823 /// See AAFromMustBeExecutedContext
1824 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1825 bool IsNonNull = false;
1826 bool TrackUse = false;
1827 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1828 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001829 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001830 return TrackUse;
1831 }
1832
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001833 /// See AbstractAttribute::getAsStr().
1834 const std::string getAsStr() const override {
1835 return getAssumed() ? "nonnull" : "may-null";
1836 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001837
1838 /// Flag to determine if the underlying value can be null and still allow
1839 /// valid accesses.
1840 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001841};
1842
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001843/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001844struct AANonNullFloating
1845 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1846 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1847 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001848
Hideto Ueno54869ec2019-07-15 06:49:04 +00001849 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001850 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001851 ChangeStatus Change = Base::updateImpl(A);
1852 if (isKnownNonNull())
1853 return Change;
1854
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001855 if (!NullIsDefined) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001856 const auto &DerefAA =
1857 A.getAAFor<AADereferenceable>(*this, getIRPosition());
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001858 if (DerefAA.getAssumedDereferenceableBytes())
1859 return Change;
1860 }
1861
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001862 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001863
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001864 DominatorTree *DT = nullptr;
1865 InformationCache &InfoCache = A.getInfoCache();
1866 if (const Function *Fn = getAnchorScope())
1867 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
1868
Johannes Doerfert1a746452019-10-20 22:28:49 -05001869 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001870 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001871 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1872 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001873 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001874 T.indicatePessimisticFixpoint();
1875 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001876 // Use abstract attribute information.
1877 const AANonNull::StateType &NS =
1878 static_cast<const AANonNull::StateType &>(AA.getState());
1879 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001880 }
1881 return T.isValidState();
1882 };
1883
1884 StateType T;
1885 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1886 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001887 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001888
1889 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001890 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001891
1892 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001893 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001894};
1895
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001896/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001897struct AANonNullReturned final
1898 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001899 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001900 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001901
1902 /// See AbstractAttribute::trackStatistics()
1903 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1904};
1905
Hideto Ueno54869ec2019-07-15 06:49:04 +00001906/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001907struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001908 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1909 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001910 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001911 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1912 AANonNullImpl>(
1913 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001914
1915 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001916 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001917};
1918
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001919struct AANonNullCallSiteArgument final : AANonNullFloating {
1920 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001921
1922 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001923 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001924};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001925
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001926/// NonNull attribute for a call site return position.
1927struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001928 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1929 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001930 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001931 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1932 AANonNullImpl>(
1933 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001934
1935 /// See AbstractAttribute::trackStatistics()
1936 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1937};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001938
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001939/// ------------------------ No-Recurse Attributes ----------------------------
1940
1941struct AANoRecurseImpl : public AANoRecurse {
1942 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1943
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001944 /// See AbstractAttribute::getAsStr()
1945 const std::string getAsStr() const override {
1946 return getAssumed() ? "norecurse" : "may-recurse";
1947 }
1948};
1949
1950struct AANoRecurseFunction final : AANoRecurseImpl {
1951 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1952
Hideto Ueno63f60662019-09-21 15:13:19 +00001953 /// See AbstractAttribute::initialize(...).
1954 void initialize(Attributor &A) override {
1955 AANoRecurseImpl::initialize(A);
1956 if (const Function *F = getAnchorScope())
1957 if (A.getInfoCache().getSccSize(*F) == 1)
1958 return;
1959 indicatePessimisticFixpoint();
1960 }
1961
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001962 /// See AbstractAttribute::updateImpl(...).
1963 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00001964
1965 auto CheckForNoRecurse = [&](Instruction &I) {
1966 ImmutableCallSite ICS(&I);
1967 if (ICS.hasFnAttr(Attribute::NoRecurse))
1968 return true;
1969
1970 const auto &NoRecurseAA =
1971 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
1972 if (!NoRecurseAA.isAssumedNoRecurse())
1973 return false;
1974
1975 // Recursion to the same function
1976 if (ICS.getCalledFunction() == getAnchorScope())
1977 return false;
1978
1979 return true;
1980 };
1981
1982 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
1983 return indicatePessimisticFixpoint();
1984 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001985 }
1986
1987 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1988};
1989
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001990/// NoRecurse attribute deduction for a call sites.
1991struct AANoRecurseCallSite final : AANoRecurseImpl {
1992 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1993
1994 /// See AbstractAttribute::initialize(...).
1995 void initialize(Attributor &A) override {
1996 AANoRecurseImpl::initialize(A);
1997 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001998 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001999 indicatePessimisticFixpoint();
2000 }
2001
2002 /// See AbstractAttribute::updateImpl(...).
2003 ChangeStatus updateImpl(Attributor &A) override {
2004 // TODO: Once we have call site specific value information we can provide
2005 // call site specific liveness information and then it makes
2006 // sense to specialize attributes for call sites arguments instead of
2007 // redirecting requests to the callee argument.
2008 Function *F = getAssociatedFunction();
2009 const IRPosition &FnPos = IRPosition::function(*F);
2010 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
2011 return clampStateAndIndicateChange(
2012 getState(),
2013 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
2014 }
2015
2016 /// See AbstractAttribute::trackStatistics()
2017 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2018};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002019
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002020/// -------------------- Undefined-Behavior Attributes ------------------------
2021
2022struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2023 AAUndefinedBehaviorImpl(const IRPosition &IRP) : AAUndefinedBehavior(IRP) {}
2024
2025 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert5732f562019-12-24 19:25:08 -06002026 // through a pointer (i.e. also branches etc.)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002027 ChangeStatus updateImpl(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002028 const size_t UBPrevSize = KnownUBInsts.size();
2029 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002030
Johannes Doerfert5732f562019-12-24 19:25:08 -06002031 auto InspectMemAccessInstForUB = [&](Instruction &I) {
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002032 // Skip instructions that are already saved.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002033 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002034 return true;
2035
Hideto Uenoef4febd2019-12-29 17:34:08 +09002036 // If we reach here, we know we have an instruction
2037 // that accesses memory through a pointer operand,
2038 // for which getPointerOperand() should give it to us.
2039 const Value *PtrOp =
2040 Attributor::getPointerOperand(&I, /* AllowVolatile */ true);
2041 assert(PtrOp &&
2042 "Expected pointer operand of memory accessing instruction");
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002043
Johannes Doerfert5732f562019-12-24 19:25:08 -06002044 // A memory access through a pointer is considered UB
2045 // only if the pointer has constant null value.
2046 // TODO: Expand it to not only check constant values.
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002047 if (!isa<ConstantPointerNull>(PtrOp)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002048 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002049 return true;
2050 }
Johannes Doerfert5732f562019-12-24 19:25:08 -06002051 const Type *PtrTy = PtrOp->getType();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002052
Johannes Doerfert5732f562019-12-24 19:25:08 -06002053 // Because we only consider instructions inside functions,
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002054 // assume that a parent function exists.
2055 const Function *F = I.getFunction();
2056
Johannes Doerfert5732f562019-12-24 19:25:08 -06002057 // A memory access using constant null pointer is only considered UB
2058 // if null pointer is _not_ defined for the target platform.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002059 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()))
2060 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002061 else
Hideto Uenoef4febd2019-12-29 17:34:08 +09002062 KnownUBInsts.insert(&I);
2063 return true;
2064 };
2065
2066 auto InspectBrInstForUB = [&](Instruction &I) {
2067 // A conditional branch instruction is considered UB if it has `undef`
2068 // condition.
2069
2070 // Skip instructions that are already saved.
2071 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2072 return true;
2073
2074 // We know we have a branch instruction.
2075 auto BrInst = cast<BranchInst>(&I);
2076
2077 // Unconditional branches are never considered UB.
2078 if (BrInst->isUnconditional())
2079 return true;
2080
2081 // Either we stopped and the appropriate action was taken,
2082 // or we got back a simplified value to continue.
2083 Optional<Value *> SimplifiedCond =
2084 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2085 if (!SimplifiedCond.hasValue())
2086 return true;
2087 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002088 return true;
2089 };
2090
Johannes Doerfert5732f562019-12-24 19:25:08 -06002091 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
2092 {Instruction::Load, Instruction::Store,
2093 Instruction::AtomicCmpXchg,
2094 Instruction::AtomicRMW});
Hideto Uenoef4febd2019-12-29 17:34:08 +09002095 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br});
2096 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
2097 UBPrevSize != KnownUBInsts.size())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002098 return ChangeStatus::CHANGED;
2099 return ChangeStatus::UNCHANGED;
2100 }
2101
Hideto Uenoef4febd2019-12-29 17:34:08 +09002102 bool isKnownToCauseUB(Instruction *I) const override {
2103 return KnownUBInsts.count(I);
2104 }
2105
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002106 bool isAssumedToCauseUB(Instruction *I) const override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002107 // In simple words, if an instruction is not in the assumed to _not_
2108 // cause UB, then it is assumed UB (that includes those
2109 // in the KnownUBInsts set). The rest is boilerplate
2110 // is to ensure that it is one of the instructions we test
2111 // for UB.
2112
2113 switch (I->getOpcode()) {
2114 case Instruction::Load:
2115 case Instruction::Store:
2116 case Instruction::AtomicCmpXchg:
2117 case Instruction::AtomicRMW:
2118 return !AssumedNoUBInsts.count(I);
2119 case Instruction::Br: {
2120 auto BrInst = cast<BranchInst>(I);
2121 if (BrInst->isUnconditional())
2122 return false;
2123 return !AssumedNoUBInsts.count(I);
2124 } break;
2125 default:
2126 return false;
2127 }
2128 return false;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002129 }
2130
2131 ChangeStatus manifest(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002132 if (KnownUBInsts.empty())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002133 return ChangeStatus::UNCHANGED;
Hideto Uenoef4febd2019-12-29 17:34:08 +09002134 for (Instruction *I : KnownUBInsts)
Hideto Uenocb5eb132019-12-27 02:39:37 +09002135 A.changeToUnreachableAfterManifest(I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002136 return ChangeStatus::CHANGED;
2137 }
2138
2139 /// See AbstractAttribute::getAsStr()
2140 const std::string getAsStr() const override {
2141 return getAssumed() ? "undefined-behavior" : "no-ub";
2142 }
2143
Hideto Uenoef4febd2019-12-29 17:34:08 +09002144 /// Note: The correctness of this analysis depends on the fact that the
2145 /// following 2 sets will stop changing after some point.
2146 /// "Change" here means that their size changes.
2147 /// The size of each set is monotonically increasing
2148 /// (we only add items to them) and it is upper bounded by the number of
2149 /// instructions in the processed function (we can never save more
2150 /// elements in either set than this number). Hence, at some point,
2151 /// they will stop increasing.
2152 /// Consequently, at some point, both sets will have stopped
2153 /// changing, effectively making the analysis reach a fixpoint.
2154
2155 /// Note: These 2 sets are disjoint and an instruction can be considered
2156 /// one of 3 things:
2157 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
2158 /// the KnownUBInsts set.
2159 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
2160 /// has a reason to assume it).
2161 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
2162 /// could not find a reason to assume or prove that it can cause UB,
2163 /// hence it assumes it doesn't. We have a set for these instructions
2164 /// so that we don't reprocess them in every update.
2165 /// Note however that instructions in this set may cause UB.
2166
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002167protected:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002168 /// A set of all live instructions _known_ to cause UB.
2169 SmallPtrSet<Instruction *, 8> KnownUBInsts;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002170
2171private:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002172 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
2173 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
2174
2175 // Should be called on updates in which if we're processing an instruction
2176 // \p I that depends on a value \p V, one of the following has to happen:
2177 // - If the value is assumed, then stop.
2178 // - If the value is known but undef, then consider it UB.
2179 // - Otherwise, do specific processing with the simplified value.
2180 // We return None in the first 2 cases to signify that an appropriate
2181 // action was taken and the caller should stop.
2182 // Otherwise, we return the simplified value that the caller should
2183 // use for specific processing.
2184 Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
2185 Instruction *I) {
2186 const auto &ValueSimplifyAA =
2187 A.getAAFor<AAValueSimplify>(*this, IRPosition::value(*V));
2188 Optional<Value *> SimplifiedV =
2189 ValueSimplifyAA.getAssumedSimplifiedValue(A);
2190 if (!ValueSimplifyAA.isKnown()) {
2191 // Don't depend on assumed values.
2192 return llvm::None;
2193 }
2194 if (!SimplifiedV.hasValue()) {
2195 // If it is known (which we tested above) but it doesn't have a value,
2196 // then we can assume `undef` and hence the instruction is UB.
2197 KnownUBInsts.insert(I);
2198 return llvm::None;
2199 }
2200 Value *Val = SimplifiedV.getValue();
2201 if (isa<UndefValue>(Val)) {
2202 KnownUBInsts.insert(I);
2203 return llvm::None;
2204 }
2205 return Val;
2206 }
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002207};
2208
2209struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
2210 AAUndefinedBehaviorFunction(const IRPosition &IRP)
2211 : AAUndefinedBehaviorImpl(IRP) {}
2212
2213 /// See AbstractAttribute::trackStatistics()
2214 void trackStatistics() const override {
2215 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
2216 "Number of instructions known to have UB");
2217 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
Hideto Uenoef4febd2019-12-29 17:34:08 +09002218 KnownUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002219 }
2220};
2221
Hideto Ueno11d37102019-07-17 15:15:43 +00002222/// ------------------------ Will-Return Attributes ----------------------------
2223
Hideto Ueno11d37102019-07-17 15:15:43 +00002224// Helper function that checks whether a function has any cycle.
2225// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002226static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00002227 SmallPtrSet<BasicBlock *, 32> Visited;
2228
2229 // Traverse BB by dfs and check whether successor is already visited.
2230 for (BasicBlock *BB : depth_first(&F)) {
2231 Visited.insert(BB);
2232 for (auto *SuccBB : successors(BB)) {
2233 if (Visited.count(SuccBB))
2234 return true;
2235 }
2236 }
2237 return false;
2238}
2239
2240// Helper function that checks the function have a loop which might become an
2241// endless loop
2242// FIXME: Any cycle is regarded as endless loop for now.
2243// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002244static bool containsPossiblyEndlessLoop(Function *F) {
2245 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00002246}
2247
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002248struct AAWillReturnImpl : public AAWillReturn {
2249 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00002250
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002251 /// See AbstractAttribute::initialize(...).
2252 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002253 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00002254
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002255 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002256 if (containsPossiblyEndlessLoop(F))
2257 indicatePessimisticFixpoint();
2258 }
Hideto Ueno11d37102019-07-17 15:15:43 +00002259
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002260 /// See AbstractAttribute::updateImpl(...).
2261 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002262 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002263 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
2264 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
2265 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002266 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002267 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002268 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002269 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
2270 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002271 };
2272
2273 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
2274 return indicatePessimisticFixpoint();
2275
2276 return ChangeStatus::UNCHANGED;
2277 }
2278
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002279 /// See AbstractAttribute::getAsStr()
2280 const std::string getAsStr() const override {
2281 return getAssumed() ? "willreturn" : "may-noreturn";
2282 }
2283};
2284
2285struct AAWillReturnFunction final : AAWillReturnImpl {
2286 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2287
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002288 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002289 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002290};
Hideto Ueno11d37102019-07-17 15:15:43 +00002291
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002292/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002293struct AAWillReturnCallSite final : AAWillReturnImpl {
2294 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2295
2296 /// See AbstractAttribute::initialize(...).
2297 void initialize(Attributor &A) override {
2298 AAWillReturnImpl::initialize(A);
2299 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002300 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002301 indicatePessimisticFixpoint();
2302 }
2303
2304 /// See AbstractAttribute::updateImpl(...).
2305 ChangeStatus updateImpl(Attributor &A) override {
2306 // TODO: Once we have call site specific value information we can provide
2307 // call site specific liveness information and then it makes
2308 // sense to specialize attributes for call sites arguments instead of
2309 // redirecting requests to the callee argument.
2310 Function *F = getAssociatedFunction();
2311 const IRPosition &FnPos = IRPosition::function(*F);
2312 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
2313 return clampStateAndIndicateChange(
2314 getState(),
2315 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
2316 }
2317
2318 /// See AbstractAttribute::trackStatistics()
2319 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
2320};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002321
Pankaj Gode04945c92019-11-22 18:40:47 +05302322/// -------------------AAReachability Attribute--------------------------
2323
2324struct AAReachabilityImpl : AAReachability {
2325 AAReachabilityImpl(const IRPosition &IRP) : AAReachability(IRP) {}
2326
2327 const std::string getAsStr() const override {
2328 // TODO: Return the number of reachable queries.
2329 return "reachable";
2330 }
2331
2332 /// See AbstractAttribute::initialize(...).
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002333 void initialize(Attributor &A) override { indicatePessimisticFixpoint(); }
Pankaj Gode04945c92019-11-22 18:40:47 +05302334
2335 /// See AbstractAttribute::updateImpl(...).
2336 ChangeStatus updateImpl(Attributor &A) override {
2337 return indicatePessimisticFixpoint();
2338 }
2339};
2340
2341struct AAReachabilityFunction final : public AAReachabilityImpl {
2342 AAReachabilityFunction(const IRPosition &IRP) : AAReachabilityImpl(IRP) {}
2343
2344 /// See AbstractAttribute::trackStatistics()
2345 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); }
2346};
2347
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002348/// ------------------------ NoAlias Argument Attribute ------------------------
2349
Johannes Doerfert344d0382019-08-07 22:34:26 +00002350struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002351 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002352
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002353 const std::string getAsStr() const override {
2354 return getAssumed() ? "noalias" : "may-alias";
2355 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002356};
2357
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002358/// NoAlias attribute for a floating value.
2359struct AANoAliasFloating final : AANoAliasImpl {
2360 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2361
Hideto Uenocbab3342019-08-29 05:52:00 +00002362 /// See AbstractAttribute::initialize(...).
2363 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002364 AANoAliasImpl::initialize(A);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002365 Value &Val = getAssociatedValue();
2366 if (isa<AllocaInst>(Val))
2367 indicateOptimisticFixpoint();
2368 if (isa<ConstantPointerNull>(Val) &&
2369 Val.getType()->getPointerAddressSpace() == 0)
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002370 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002371 }
2372
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002373 /// See AbstractAttribute::updateImpl(...).
2374 ChangeStatus updateImpl(Attributor &A) override {
2375 // TODO: Implement this.
2376 return indicatePessimisticFixpoint();
2377 }
2378
2379 /// See AbstractAttribute::trackStatistics()
2380 void trackStatistics() const override {
2381 STATS_DECLTRACK_FLOATING_ATTR(noalias)
2382 }
2383};
2384
2385/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00002386struct AANoAliasArgument final
2387 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002388 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
2389 AANoAliasArgument(const IRPosition &IRP) : Base(IRP) {}
2390
Johannes Doerfert2baf0002020-01-12 00:18:07 -06002391 /// See AbstractAttribute::initialize(...).
2392 void initialize(Attributor &A) override {
2393 Base::initialize(A);
2394 // See callsite argument attribute and callee argument attribute.
2395 if (hasAttr({Attribute::ByVal}))
2396 indicateOptimisticFixpoint();
2397 }
2398
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002399 /// See AbstractAttribute::update(...).
2400 ChangeStatus updateImpl(Attributor &A) override {
2401 // We have to make sure no-alias on the argument does not break
2402 // synchronization when this is a callback argument, see also [1] below.
2403 // If synchronization cannot be affected, we delegate to the base updateImpl
2404 // function, otherwise we give up for now.
2405
2406 // If the function is no-sync, no-alias cannot break synchronization.
2407 const auto &NoSyncAA = A.getAAFor<AANoSync>(
2408 *this, IRPosition::function_scope(getIRPosition()));
2409 if (NoSyncAA.isAssumedNoSync())
2410 return Base::updateImpl(A);
2411
2412 // If the argument is read-only, no-alias cannot break synchronization.
2413 const auto &MemBehaviorAA =
2414 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
2415 if (MemBehaviorAA.isAssumedReadOnly())
2416 return Base::updateImpl(A);
2417
2418 // If the argument is never passed through callbacks, no-alias cannot break
2419 // synchronization.
2420 if (A.checkForAllCallSites(
2421 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
2422 true))
2423 return Base::updateImpl(A);
2424
2425 // TODO: add no-alias but make sure it doesn't break synchronization by
2426 // introducing fake uses. See:
2427 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
2428 // International Workshop on OpenMP 2018,
2429 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
2430
2431 return indicatePessimisticFixpoint();
2432 }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002433
2434 /// See AbstractAttribute::trackStatistics()
2435 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
2436};
2437
2438struct AANoAliasCallSiteArgument final : AANoAliasImpl {
2439 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2440
Hideto Uenocbab3342019-08-29 05:52:00 +00002441 /// See AbstractAttribute::initialize(...).
2442 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00002443 // See callsite argument attribute and callee argument attribute.
2444 ImmutableCallSite ICS(&getAnchorValue());
2445 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
2446 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002447 }
2448
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002449 /// See AbstractAttribute::updateImpl(...).
2450 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002451 // We can deduce "noalias" if the following conditions hold.
2452 // (i) Associated value is assumed to be noalias in the definition.
2453 // (ii) Associated value is assumed to be no-capture in all the uses
2454 // possibly executed before this callsite.
2455 // (iii) There is no other pointer argument which could alias with the
2456 // value.
2457
2458 const Value &V = getAssociatedValue();
2459 const IRPosition IRP = IRPosition::value(V);
2460
2461 // (i) Check whether noalias holds in the definition.
2462
2463 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002464 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] check definition: " << V
2465 << " :: " << NoAliasAA << "\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002466
2467 if (!NoAliasAA.isAssumedNoAlias())
2468 return indicatePessimisticFixpoint();
2469
2470 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
2471 << " is assumed NoAlias in the definition\n");
2472
2473 // (ii) Check whether the value is captured in the scope using AANoCapture.
2474 // FIXME: This is conservative though, it is better to look at CFG and
2475 // check only uses possibly executed before this callsite.
2476
2477 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002478 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2479 LLVM_DEBUG(
2480 dbgs() << "[Attributor][AANoAliasCSArg] " << V
2481 << " cannot be noalias as it is potentially captured\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002482 return indicatePessimisticFixpoint();
Johannes Doerfert72adda12019-10-10 05:33:21 +00002483 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002484
2485 // (iii) Check there is no other pointer argument which could alias with the
2486 // value.
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002487 // TODO: AbstractCallSite
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002488 ImmutableCallSite ICS(&getAnchorValue());
2489 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
2490 if (getArgNo() == (int)i)
2491 continue;
2492 const Value *ArgOp = ICS.getArgOperand(i);
2493 if (!ArgOp->getType()->isPointerTy())
2494 continue;
2495
Hideto Ueno30d86f12019-09-17 06:53:27 +00002496 if (const Function *F = getAnchorScope()) {
2497 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002498 bool IsAliasing = !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
Hideto Ueno30d86f12019-09-17 06:53:27 +00002499 LLVM_DEBUG(dbgs()
2500 << "[Attributor][NoAliasCSArg] Check alias between "
2501 "callsite arguments "
2502 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
Johannes Doerfert72adda12019-10-10 05:33:21 +00002503 << getAssociatedValue() << " " << *ArgOp << " => "
2504 << (IsAliasing ? "" : "no-") << "alias \n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002505
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002506 if (!IsAliasing)
Hideto Ueno30d86f12019-09-17 06:53:27 +00002507 continue;
2508 }
2509 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002510 return indicatePessimisticFixpoint();
2511 }
2512
2513 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002514 }
2515
2516 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002517 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002518};
2519
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002520/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002521struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002522 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002523
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002524 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002525 virtual ChangeStatus updateImpl(Attributor &A) override {
2526
2527 auto CheckReturnValue = [&](Value &RV) -> bool {
2528 if (Constant *C = dyn_cast<Constant>(&RV))
2529 if (C->isNullValue() || isa<UndefValue>(C))
2530 return true;
2531
2532 /// For now, we can only deduce noalias if we have call sites.
2533 /// FIXME: add more support.
2534 ImmutableCallSite ICS(&RV);
2535 if (!ICS)
2536 return false;
2537
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002538 const IRPosition &RVPos = IRPosition::value(RV);
2539 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002540 if (!NoAliasAA.isAssumedNoAlias())
2541 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002542
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002543 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2544 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002545 };
2546
2547 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2548 return indicatePessimisticFixpoint();
2549
2550 return ChangeStatus::UNCHANGED;
2551 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002552
2553 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002554 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002555};
2556
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002557/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002558struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2559 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2560
2561 /// See AbstractAttribute::initialize(...).
2562 void initialize(Attributor &A) override {
2563 AANoAliasImpl::initialize(A);
2564 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002565 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002566 indicatePessimisticFixpoint();
2567 }
2568
2569 /// See AbstractAttribute::updateImpl(...).
2570 ChangeStatus updateImpl(Attributor &A) override {
2571 // TODO: Once we have call site specific value information we can provide
2572 // call site specific liveness information and then it makes
2573 // sense to specialize attributes for call sites arguments instead of
2574 // redirecting requests to the callee argument.
2575 Function *F = getAssociatedFunction();
2576 const IRPosition &FnPos = IRPosition::returned(*F);
2577 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2578 return clampStateAndIndicateChange(
2579 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2580 }
2581
2582 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002583 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002584};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002585
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002586/// -------------------AAIsDead Function Attribute-----------------------
2587
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002588struct AAIsDeadValueImpl : public AAIsDead {
2589 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002590
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002591 /// See AAIsDead::isAssumedDead().
2592 bool isAssumedDead() const override { return getAssumed(); }
2593
2594 /// See AAIsDead::isAssumedDead(BasicBlock *).
2595 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2596
2597 /// See AAIsDead::isKnownDead(BasicBlock *).
2598 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2599
2600 /// See AAIsDead::isAssumedDead(Instruction *I).
2601 bool isAssumedDead(const Instruction *I) const override {
2602 return I == getCtxI() && isAssumedDead();
2603 }
2604
2605 /// See AAIsDead::isKnownDead(Instruction *I).
2606 bool isKnownDead(const Instruction *I) const override {
2607 return I == getCtxI() && getKnown();
2608 }
2609
2610 /// See AbstractAttribute::getAsStr().
2611 const std::string getAsStr() const override {
2612 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2613 }
2614};
2615
2616struct AAIsDeadFloating : public AAIsDeadValueImpl {
2617 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2618
2619 /// See AbstractAttribute::initialize(...).
2620 void initialize(Attributor &A) override {
2621 if (Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()))
2622 if (!wouldInstructionBeTriviallyDead(I))
2623 indicatePessimisticFixpoint();
2624 if (isa<UndefValue>(getAssociatedValue()))
2625 indicatePessimisticFixpoint();
2626 }
2627
2628 /// See AbstractAttribute::updateImpl(...).
2629 ChangeStatus updateImpl(Attributor &A) override {
2630 auto UsePred = [&](const Use &U, bool &Follow) {
2631 Instruction *UserI = cast<Instruction>(U.getUser());
2632 if (CallSite CS = CallSite(UserI)) {
2633 if (!CS.isArgOperand(&U))
2634 return false;
2635 const IRPosition &CSArgPos =
2636 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
2637 const auto &CSArgIsDead = A.getAAFor<AAIsDead>(*this, CSArgPos);
2638 return CSArgIsDead.isAssumedDead();
2639 }
2640 if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
2641 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
2642 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, RetPos);
2643 return RetIsDeadAA.isAssumedDead();
2644 }
2645 Follow = true;
2646 return wouldInstructionBeTriviallyDead(UserI);
2647 };
2648
2649 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
2650 return indicatePessimisticFixpoint();
2651 return ChangeStatus::UNCHANGED;
2652 }
2653
2654 /// See AbstractAttribute::manifest(...).
2655 ChangeStatus manifest(Attributor &A) override {
2656 Value &V = getAssociatedValue();
2657 if (auto *I = dyn_cast<Instruction>(&V))
2658 if (wouldInstructionBeTriviallyDead(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002659 A.deleteAfterManifest(*I);
2660 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002661 }
2662
2663 if (V.use_empty())
2664 return ChangeStatus::UNCHANGED;
2665
2666 UndefValue &UV = *UndefValue::get(V.getType());
Hideto Ueno34fe8d02019-12-30 17:08:48 +09002667 bool AnyChange = A.changeValueAfterManifest(V, UV);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002668 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2669 }
2670
2671 /// See AbstractAttribute::trackStatistics()
2672 void trackStatistics() const override {
2673 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2674 }
2675};
2676
2677struct AAIsDeadArgument : public AAIsDeadFloating {
2678 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2679
2680 /// See AbstractAttribute::initialize(...).
2681 void initialize(Attributor &A) override {
2682 if (!getAssociatedFunction()->hasExactDefinition())
2683 indicatePessimisticFixpoint();
2684 }
2685
Johannes Doerfert75133632019-10-10 01:39:16 -05002686 /// See AbstractAttribute::manifest(...).
2687 ChangeStatus manifest(Attributor &A) override {
2688 ChangeStatus Changed = AAIsDeadFloating::manifest(A);
2689 Argument &Arg = *getAssociatedArgument();
2690 if (Arg.getParent()->hasLocalLinkage())
2691 if (A.registerFunctionSignatureRewrite(
2692 Arg, /* ReplacementTypes */ {},
2693 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{},
2694 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{}))
2695 return ChangeStatus::CHANGED;
2696 return Changed;
2697 }
2698
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002699 /// See AbstractAttribute::trackStatistics()
2700 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2701};
2702
2703struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2704 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2705
2706 /// See AbstractAttribute::initialize(...).
2707 void initialize(Attributor &A) override {
2708 if (isa<UndefValue>(getAssociatedValue()))
2709 indicatePessimisticFixpoint();
2710 }
2711
2712 /// See AbstractAttribute::updateImpl(...).
2713 ChangeStatus updateImpl(Attributor &A) override {
2714 // TODO: Once we have call site specific value information we can provide
2715 // call site specific liveness information and then it makes
2716 // sense to specialize attributes for call sites arguments instead of
2717 // redirecting requests to the callee argument.
2718 Argument *Arg = getAssociatedArgument();
2719 if (!Arg)
2720 return indicatePessimisticFixpoint();
2721 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2722 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
2723 return clampStateAndIndicateChange(
2724 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
2725 }
2726
2727 /// See AbstractAttribute::manifest(...).
2728 ChangeStatus manifest(Attributor &A) override {
2729 CallBase &CB = cast<CallBase>(getAnchorValue());
2730 Use &U = CB.getArgOperandUse(getArgNo());
2731 assert(!isa<UndefValue>(U.get()) &&
2732 "Expected undef values to be filtered out!");
2733 UndefValue &UV = *UndefValue::get(U->getType());
2734 if (A.changeUseAfterManifest(U, UV))
2735 return ChangeStatus::CHANGED;
2736 return ChangeStatus::UNCHANGED;
2737 }
2738
2739 /// See AbstractAttribute::trackStatistics()
2740 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
2741};
2742
2743struct AAIsDeadReturned : public AAIsDeadValueImpl {
2744 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2745
2746 /// See AbstractAttribute::updateImpl(...).
2747 ChangeStatus updateImpl(Attributor &A) override {
2748
2749 auto PredForCallSite = [&](AbstractCallSite ACS) {
2750 if (ACS.isCallbackCall())
2751 return false;
2752 const IRPosition &CSRetPos =
2753 IRPosition::callsite_returned(ACS.getCallSite());
2754 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, CSRetPos);
2755 return RetIsDeadAA.isAssumedDead();
2756 };
2757
2758 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
2759 return indicatePessimisticFixpoint();
2760
2761 return ChangeStatus::UNCHANGED;
2762 }
2763
2764 /// See AbstractAttribute::manifest(...).
2765 ChangeStatus manifest(Attributor &A) override {
2766 // TODO: Rewrite the signature to return void?
2767 bool AnyChange = false;
2768 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
2769 auto RetInstPred = [&](Instruction &I) {
2770 ReturnInst &RI = cast<ReturnInst>(I);
2771 if (!isa<UndefValue>(RI.getReturnValue()))
2772 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
2773 return true;
2774 };
2775 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
2776 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2777 }
2778
2779 /// See AbstractAttribute::trackStatistics()
2780 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
2781};
2782
2783struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
2784 AAIsDeadCallSiteReturned(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2785
2786 /// See AbstractAttribute::initialize(...).
2787 void initialize(Attributor &A) override {}
2788
2789 /// See AbstractAttribute::trackStatistics()
2790 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(IsDead) }
2791};
2792
2793struct AAIsDeadFunction : public AAIsDead {
2794 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
2795
2796 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002797 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002798 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002799 if (F && !F->isDeclaration()) {
2800 ToBeExploredFrom.insert(&F->getEntryBlock().front());
2801 assumeLive(A, F->getEntryBlock());
2802 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002803 }
2804
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002805 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002806 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002807 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002808 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002809 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
2810 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002811 }
2812
2813 /// See AbstractAttribute::manifest(...).
2814 ChangeStatus manifest(Attributor &A) override {
2815 assert(getState().isValidState() &&
2816 "Attempted to manifest an invalid state!");
2817
2818 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002819 Function &F = *getAssociatedFunction();
2820
2821 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002822 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002823 return ChangeStatus::CHANGED;
2824 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002825
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002826 // Flag to determine if we can change an invoke to a call assuming the
2827 // callee is nounwind. This is not possible if the personality of the
2828 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002829 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002830
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002831 KnownDeadEnds.set_union(ToBeExploredFrom);
2832 for (const Instruction *DeadEndI : KnownDeadEnds) {
2833 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002834 if (!CB)
2835 continue;
2836 const auto &NoReturnAA =
2837 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002838 bool MayReturn = !NoReturnAA.isAssumedNoReturn();
2839 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002840 continue;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002841
Johannes Doerferta4088c72020-01-07 16:01:57 -06002842 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
2843 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
2844 else
2845 A.changeToUnreachableAfterManifest(
2846 const_cast<Instruction *>(DeadEndI->getNextNode()));
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002847 HasChanged = ChangeStatus::CHANGED;
2848 }
2849
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002850 for (BasicBlock &BB : F)
2851 if (!AssumedLiveBlocks.count(&BB))
2852 A.deleteAfterManifest(BB);
2853
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002854 return HasChanged;
2855 }
2856
2857 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002858 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002859
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002860 /// See AbstractAttribute::trackStatistics()
2861 void trackStatistics() const override {}
2862
2863 /// Returns true if the function is assumed dead.
2864 bool isAssumedDead() const override { return false; }
2865
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002866 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002867 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002868 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002869 "BB must be in the same anchor scope function.");
2870
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002871 if (!getAssumed())
2872 return false;
2873 return !AssumedLiveBlocks.count(BB);
2874 }
2875
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002876 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002877 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002878 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002879 }
2880
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002881 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002882 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002883 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002884 "Instruction must be in the same anchor scope function.");
2885
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002886 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002887 return false;
2888
2889 // If it is not in AssumedLiveBlocks then it for sure dead.
2890 // Otherwise, it can still be after noreturn call in a live block.
2891 if (!AssumedLiveBlocks.count(I->getParent()))
2892 return true;
2893
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002894 // If it is not after a liveness barrier it is live.
2895 const Instruction *PrevI = I->getPrevNode();
2896 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002897 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002898 return true;
2899 PrevI = PrevI->getPrevNode();
2900 }
2901 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002902 }
2903
2904 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002905 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002906 return getKnown() && isAssumedDead(I);
2907 }
2908
Johannes Doerfert924d2132019-08-05 21:34:45 +00002909 /// Determine if \p F might catch asynchronous exceptions.
2910 static bool mayCatchAsynchronousExceptions(const Function &F) {
2911 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2912 }
2913
Johannes Doerfert2f622062019-09-04 16:35:20 +00002914 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2915 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002916 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002917 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002918 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002919
2920 // We assume that all of BB is (probably) live now and if there are calls to
2921 // internal functions we will assume that those are now live as well. This
2922 // is a performance optimization for blocks with calls to a lot of internal
2923 // functions. It can however cause dead functions to be treated as live.
2924 for (const Instruction &I : BB)
2925 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2926 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00002927 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00002928 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002929 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002930 }
2931
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002932 /// Collection of instructions that need to be explored again, e.g., we
2933 /// did assume they do not transfer control to (one of their) successors.
2934 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002935
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002936 /// Collection of instructions that are known to not transfer control.
2937 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
2938
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002939 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00002940 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002941};
2942
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002943static bool
2944identifyAliveSuccessors(Attributor &A, const CallBase &CB,
2945 AbstractAttribute &AA,
2946 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2947 const IRPosition &IPos = IRPosition::callsite_function(CB);
2948
2949 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
2950 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002951 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002952 if (CB.isTerminator())
2953 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
2954 else
2955 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002956 return false;
2957}
2958
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002959static bool
2960identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
2961 AbstractAttribute &AA,
2962 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
2963 bool UsedAssumedInformation =
2964 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00002965
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002966 // First, determine if we can change an invoke to a call assuming the
2967 // callee is nounwind. This is not possible if the personality of the
2968 // function allows to catch asynchronous exceptions.
2969 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
2970 AliveSuccessors.push_back(&II.getUnwindDest()->front());
2971 } else {
2972 const IRPosition &IPos = IRPosition::callsite_function(II);
2973 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002974 if (AANoUnw.isAssumedNoUnwind()) {
2975 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
2976 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002977 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002978 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002979 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002980 return UsedAssumedInformation;
2981}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002982
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002983static Optional<ConstantInt *>
2984getAssumedConstant(Attributor &A, const Value &V, AbstractAttribute &AA,
2985 bool &UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002986 const auto &ValueSimplifyAA =
2987 A.getAAFor<AAValueSimplify>(AA, IRPosition::value(V));
2988 Optional<Value *> SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(A);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002989 UsedAssumedInformation |= !ValueSimplifyAA.isKnown();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002990 if (!SimplifiedV.hasValue())
2991 return llvm::None;
2992 if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue()))
2993 return llvm::None;
2994 return dyn_cast_or_null<ConstantInt>(SimplifiedV.getValue());
2995}
2996
2997static bool
2998identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
2999 AbstractAttribute &AA,
3000 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3001 bool UsedAssumedInformation = false;
3002 if (BI.getNumSuccessors() == 1) {
3003 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3004 } else {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003005 Optional<ConstantInt *> CI =
3006 getAssumedConstant(A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003007 if (!CI.hasValue()) {
3008 // No value yet, assume both edges are dead.
3009 } else if (CI.getValue()) {
3010 const BasicBlock *SuccBB =
3011 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
3012 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003013 } else {
3014 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3015 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003016 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003017 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003018 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003019 return UsedAssumedInformation;
3020}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003021
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003022static bool
3023identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
3024 AbstractAttribute &AA,
3025 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003026 bool UsedAssumedInformation = false;
3027 Optional<ConstantInt *> CI =
3028 getAssumedConstant(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003029 if (!CI.hasValue()) {
3030 // No value yet, assume all edges are dead.
3031 } else if (CI.getValue()) {
3032 for (auto &CaseIt : SI.cases()) {
3033 if (CaseIt.getCaseValue() == CI.getValue()) {
3034 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003035 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003036 }
3037 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05003038 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003039 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003040 } else {
3041 for (const BasicBlock *SuccBB : successors(SI.getParent()))
3042 AliveSuccessors.push_back(&SuccBB->front());
3043 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003044 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003045}
3046
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003047ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003048 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003049
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003050 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
3051 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003052 << ToBeExploredFrom.size() << " exploration points and "
3053 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003054
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003055 // Copy and clear the list of instructions we need to explore from. It is
3056 // refilled with instructions the next update has to look at.
3057 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
3058 ToBeExploredFrom.end());
3059 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003060
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003061 SmallVector<const Instruction *, 8> AliveSuccessors;
3062 while (!Worklist.empty()) {
3063 const Instruction *I = Worklist.pop_back_val();
3064 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003065
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003066 AliveSuccessors.clear();
3067
3068 bool UsedAssumedInformation = false;
3069 switch (I->getOpcode()) {
3070 // TODO: look for (assumed) UB to backwards propagate "deadness".
3071 default:
3072 if (I->isTerminator()) {
3073 for (const BasicBlock *SuccBB : successors(I->getParent()))
3074 AliveSuccessors.push_back(&SuccBB->front());
3075 } else {
3076 AliveSuccessors.push_back(I->getNextNode());
3077 }
3078 break;
3079 case Instruction::Call:
3080 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
3081 *this, AliveSuccessors);
3082 break;
3083 case Instruction::Invoke:
3084 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
3085 *this, AliveSuccessors);
3086 break;
3087 case Instruction::Br:
3088 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
3089 *this, AliveSuccessors);
3090 break;
3091 case Instruction::Switch:
3092 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
3093 *this, AliveSuccessors);
3094 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00003095 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003096
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003097 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003098 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003099 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003100 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003101 if (AliveSuccessors.empty() ||
3102 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
3103 KnownDeadEnds.insert(I);
3104 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003105
3106 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
3107 << AliveSuccessors.size() << " UsedAssumedInformation: "
3108 << UsedAssumedInformation << "\n");
3109
3110 for (const Instruction *AliveSuccessor : AliveSuccessors) {
3111 if (!I->isTerminator()) {
3112 assert(AliveSuccessors.size() == 1 &&
3113 "Non-terminator expected to have a single successor!");
3114 Worklist.push_back(AliveSuccessor);
3115 } else {
3116 if (assumeLive(A, *AliveSuccessor->getParent()))
3117 Worklist.push_back(AliveSuccessor);
3118 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00003119 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003120 }
3121
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003122 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003123
Johannes Doerfertd6207812019-08-07 22:32:38 +00003124 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003125 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003126 // "invalid" and all queries to be answered conservatively without lookups.
3127 // To be in this state we have to (1) finished the exploration and (3) not
3128 // discovered any non-trivial dead end and (2) not ruled unreachable code
3129 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003130 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003131 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
3132 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
3133 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
3134 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003135 return indicatePessimisticFixpoint();
3136 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003137}
3138
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003139/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003140struct AAIsDeadCallSite final : AAIsDeadFunction {
3141 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003142
3143 /// See AbstractAttribute::initialize(...).
3144 void initialize(Attributor &A) override {
3145 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003146 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003147 // sense to specialize attributes for call sites instead of
3148 // redirecting requests to the callee.
3149 llvm_unreachable("Abstract attributes for liveness are not "
3150 "supported for call sites yet!");
3151 }
3152
3153 /// See AbstractAttribute::updateImpl(...).
3154 ChangeStatus updateImpl(Attributor &A) override {
3155 return indicatePessimisticFixpoint();
3156 }
3157
3158 /// See AbstractAttribute::trackStatistics()
3159 void trackStatistics() const override {}
3160};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003161
Hideto Ueno19c07af2019-07-23 08:16:17 +00003162/// -------------------- Dereferenceable Argument Attribute --------------------
3163
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003164template <>
3165ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
3166 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05003167 ChangeStatus CS0 =
3168 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
3169 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003170 return CS0 | CS1;
3171}
3172
Hideto Ueno70576ca2019-08-22 14:18:29 +00003173struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003174 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003175 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00003176
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003177 void initialize(Attributor &A) override {
3178 SmallVector<Attribute, 4> Attrs;
3179 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
3180 Attrs);
3181 for (const Attribute &Attr : Attrs)
3182 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
3183
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003184 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003185
3186 const IRPosition &IRP = this->getIRPosition();
3187 bool IsFnInterface = IRP.isFnInterfaceKind();
3188 const Function *FnScope = IRP.getAnchorScope();
3189 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
3190 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003191 }
3192
Hideto Ueno19c07af2019-07-23 08:16:17 +00003193 /// See AbstractAttribute::getState()
3194 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00003195 StateType &getState() override { return *this; }
3196 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003197 /// }
3198
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003199 /// Helper function for collecting accessed bytes in must-be-executed-context
3200 void addAccessedBytesForUse(Attributor &A, const Use *U,
3201 const Instruction *I) {
3202 const Value *UseV = U->get();
3203 if (!UseV->getType()->isPointerTy())
3204 return;
3205
3206 Type *PtrTy = UseV->getType();
3207 const DataLayout &DL = A.getDataLayout();
3208 int64_t Offset;
3209 if (const Value *Base = getBasePointerOfAccessPointerOperand(
3210 I, Offset, DL, /*AllowNonInbounds*/ true)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09003211 if (Base == &getAssociatedValue() &&
3212 Attributor::getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003213 uint64_t Size = DL.getTypeStoreSize(PtrTy->getPointerElementType());
3214 addAccessedBytes(Offset, Size);
3215 }
3216 }
3217 return;
3218 }
3219
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003220 /// See AAFromMustBeExecutedContext
3221 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3222 bool IsNonNull = false;
3223 bool TrackUse = false;
3224 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
3225 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003226
3227 addAccessedBytesForUse(A, U, I);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003228 takeKnownDerefBytesMaximum(DerefBytes);
3229 return TrackUse;
3230 }
3231
Hideto Uenodfedae52019-11-29 06:45:07 +00003232 /// See AbstractAttribute::manifest(...).
3233 ChangeStatus manifest(Attributor &A) override {
3234 ChangeStatus Change = AADereferenceable::manifest(A);
3235 if (isAssumedNonNull() && hasAttr(Attribute::DereferenceableOrNull)) {
3236 removeAttrs({Attribute::DereferenceableOrNull});
3237 return ChangeStatus::CHANGED;
3238 }
3239 return Change;
3240 }
3241
Johannes Doerferteccdf082019-08-05 23:35:12 +00003242 void getDeducedAttributes(LLVMContext &Ctx,
3243 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00003244 // TODO: Add *_globally support
3245 if (isAssumedNonNull())
3246 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
3247 Ctx, getAssumedDereferenceableBytes()));
3248 else
3249 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
3250 Ctx, getAssumedDereferenceableBytes()));
3251 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003252
3253 /// See AbstractAttribute::getAsStr().
3254 const std::string getAsStr() const override {
3255 if (!getAssumedDereferenceableBytes())
3256 return "unknown-dereferenceable";
3257 return std::string("dereferenceable") +
3258 (isAssumedNonNull() ? "" : "_or_null") +
3259 (isAssumedGlobal() ? "_globally" : "") + "<" +
3260 std::to_string(getKnownDereferenceableBytes()) + "-" +
3261 std::to_string(getAssumedDereferenceableBytes()) + ">";
3262 }
3263};
3264
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003265/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003266struct AADereferenceableFloating
3267 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
3268 using Base =
3269 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
3270 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00003271
3272 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003273 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003274 ChangeStatus Change = Base::updateImpl(A);
3275
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003276 const DataLayout &DL = A.getDataLayout();
3277
3278 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
3279 unsigned IdxWidth =
3280 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
3281 APInt Offset(IdxWidth, 0);
3282 const Value *Base =
3283 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
3284
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003285 const auto &AA =
3286 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003287 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003288 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003289 // Use IR information if we did not strip anything.
3290 // TODO: track globally.
3291 bool CanBeNull;
3292 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
3293 T.GlobalState.indicatePessimisticFixpoint();
3294 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003295 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003296 DerefBytes = DS.DerefBytesState.getAssumed();
3297 T.GlobalState &= DS.GlobalState;
3298 }
3299
Hideto Ueno188f9a32020-01-15 15:25:52 +09003300 // TODO: Use `AAConstantRange` to infer dereferenceable bytes.
3301
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003302 // For now we do not try to "increase" dereferenceability due to negative
3303 // indices as we first have to come up with code to deal with loops and
3304 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00003305 int64_t OffsetSExt = Offset.getSExtValue();
3306 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00003307 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003308
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003309 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00003310 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003311
Johannes Doerfert785fad32019-08-23 17:29:23 +00003312 if (this == &AA) {
3313 if (!Stripped) {
3314 // If nothing was stripped IR information is all we got.
3315 T.takeKnownDerefBytesMaximum(
3316 std::max(int64_t(0), DerefBytes - OffsetSExt));
3317 T.indicatePessimisticFixpoint();
3318 } else if (OffsetSExt > 0) {
3319 // If something was stripped but there is circular reasoning we look
3320 // for the offset. If it is positive we basically decrease the
3321 // dereferenceable bytes in a circluar loop now, which will simply
3322 // drive them down to the known value in a very slow way which we
3323 // can accelerate.
3324 T.indicatePessimisticFixpoint();
3325 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003326 }
3327
3328 return T.isValidState();
3329 };
3330
3331 DerefState T;
3332 if (!genericValueTraversal<AADereferenceable, DerefState>(
3333 A, getIRPosition(), *this, T, VisitValueCB))
3334 return indicatePessimisticFixpoint();
3335
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003336 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003337 }
3338
3339 /// See AbstractAttribute::trackStatistics()
3340 void trackStatistics() const override {
3341 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
3342 }
3343};
3344
3345/// Dereferenceable attribute for a return value.
3346struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003347 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
3348 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003349 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003350 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
3351 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003352
3353 /// See AbstractAttribute::trackStatistics()
3354 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003355 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003356 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003357};
3358
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003359/// Dereferenceable attribute for an argument
3360struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003361 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
3362 AADereferenceable, AADereferenceableImpl, DerefState> {
3363 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
3364 AADereferenceable, AADereferenceableImpl, DerefState>;
3365 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003366
3367 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003368 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00003369 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
3370 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003371};
3372
Hideto Ueno19c07af2019-07-23 08:16:17 +00003373/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003374struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003375 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003376 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003377
3378 /// See AbstractAttribute::trackStatistics()
3379 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003380 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003381 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003382};
3383
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003384/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003385struct AADereferenceableCallSiteReturned final
3386 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3387 AADereferenceable, AADereferenceableImpl> {
3388 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3389 AADereferenceable, AADereferenceableImpl>;
3390 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003391
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003392 /// See AbstractAttribute::trackStatistics()
3393 void trackStatistics() const override {
3394 STATS_DECLTRACK_CS_ATTR(dereferenceable);
3395 }
3396};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003397
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003398// ------------------------ Align Argument Attribute ------------------------
3399
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003400static unsigned int getKnownAlignForUse(Attributor &A,
3401 AbstractAttribute &QueryingAA,
3402 Value &AssociatedValue, const Use *U,
3403 const Instruction *I, bool &TrackUse) {
Hideto Ueno78a75022019-11-26 07:51:59 +00003404 // We need to follow common pointer manipulation uses to the accesses they
3405 // feed into.
3406 if (isa<CastInst>(I)) {
Johannes Doerfertc90681b2020-01-02 16:41:17 -06003407 // Follow all but ptr2int casts.
3408 TrackUse = !isa<PtrToIntInst>(I);
Hideto Ueno78a75022019-11-26 07:51:59 +00003409 return 0;
3410 }
3411 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
3412 if (GEP->hasAllConstantIndices()) {
3413 TrackUse = true;
3414 return 0;
3415 }
3416 }
3417
3418 unsigned Alignment = 0;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003419 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
3420 if (ICS.isBundleOperand(U) || ICS.isCallee(U))
3421 return 0;
3422
3423 unsigned ArgNo = ICS.getArgumentNo(U);
3424 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
3425 // As long as we only use known information there is no need to track
3426 // dependences here.
3427 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP,
3428 /* TrackDependence */ false);
Hideto Ueno78a75022019-11-26 07:51:59 +00003429 Alignment = AlignAA.getKnownAlign();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003430 }
3431
Hideto Ueno78a75022019-11-26 07:51:59 +00003432 const Value *UseV = U->get();
Johannes Doerfert30ae8592020-01-10 12:13:10 -06003433 if (auto *SI = dyn_cast<StoreInst>(I)) {
3434 if (SI->getPointerOperand() == UseV)
3435 Alignment = SI->getAlignment();
3436 } else if (auto *LI = dyn_cast<LoadInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003437 Alignment = LI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003438
Hideto Ueno78a75022019-11-26 07:51:59 +00003439 if (Alignment <= 1)
3440 return 0;
3441
3442 auto &DL = A.getDataLayout();
3443 int64_t Offset;
3444
3445 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
3446 if (Base == &AssociatedValue) {
3447 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
3448 // So we can say that the maximum power of two which is a divisor of
3449 // gcd(Offset, Alignment) is an alignment.
3450
3451 uint32_t gcd =
3452 greatestCommonDivisor(uint32_t(abs((int32_t)Offset)), Alignment);
3453 Alignment = llvm::PowerOf2Floor(gcd);
3454 }
3455 }
3456
3457 return Alignment;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003458}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003459struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003460 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003461
Johannes Doerfert234eda52019-08-16 19:51:23 +00003462 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003463 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003464 SmallVector<Attribute, 4> Attrs;
3465 getAttrs({Attribute::Alignment}, Attrs);
3466 for (const Attribute &Attr : Attrs)
3467 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003468
3469 if (getIRPosition().isFnInterfaceKind() &&
3470 (!getAssociatedFunction() ||
3471 !getAssociatedFunction()->hasExactDefinition()))
3472 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003473 }
3474
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003475 /// See AbstractAttribute::manifest(...).
3476 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003477 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003478
3479 // Check for users that allow alignment annotations.
3480 Value &AnchorVal = getIRPosition().getAnchorValue();
3481 for (const Use &U : AnchorVal.uses()) {
3482 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
3483 if (SI->getPointerOperand() == &AnchorVal)
3484 if (SI->getAlignment() < getAssumedAlign()) {
3485 STATS_DECLTRACK(AAAlign, Store,
James Hendersond68904f2020-01-06 10:15:44 +00003486 "Number of times alignment added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00003487 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert30179d72020-01-12 00:25:45 -06003488 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003489 }
3490 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
3491 if (LI->getPointerOperand() == &AnchorVal)
3492 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00003493 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003494 STATS_DECLTRACK(AAAlign, Load,
James Hendersond68904f2020-01-06 10:15:44 +00003495 "Number of times alignment added to a load");
Johannes Doerfert30179d72020-01-12 00:25:45 -06003496 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003497 }
3498 }
3499 }
3500
Johannes Doerfert30179d72020-01-12 00:25:45 -06003501 ChangeStatus Changed = AAAlign::manifest(A);
3502
3503 MaybeAlign InheritAlign =
3504 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3505 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3506 return LoadStoreChanged;
3507 return Changed | LoadStoreChanged;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003508 }
3509
Johannes Doerfert81df4522019-08-30 15:22:28 +00003510 // TODO: Provide a helper to determine the implied ABI alignment and check in
3511 // the existing manifest method and a new one for AAAlignImpl that value
3512 // to avoid making the alignment explicit if it did not improve.
3513
3514 /// See AbstractAttribute::getDeducedAttributes
3515 virtual void
3516 getDeducedAttributes(LLVMContext &Ctx,
3517 SmallVectorImpl<Attribute> &Attrs) const override {
3518 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00003519 Attrs.emplace_back(
3520 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00003521 }
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003522 /// See AAFromMustBeExecutedContext
3523 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3524 bool TrackUse = false;
3525
Hideto Ueno4ecf2552019-12-12 13:42:40 +00003526 unsigned int KnownAlign =
3527 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003528 takeKnownMaximum(KnownAlign);
3529
3530 return TrackUse;
3531 }
Johannes Doerfert81df4522019-08-30 15:22:28 +00003532
3533 /// See AbstractAttribute::getAsStr().
3534 const std::string getAsStr() const override {
3535 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
3536 "-" + std::to_string(getAssumedAlign()) + ">")
3537 : "unknown-align";
3538 }
3539};
3540
3541/// Align attribute for a floating value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003542struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
3543 using Base = AAFromMustBeExecutedContext<AAAlign, AAAlignImpl>;
3544 AAAlignFloating(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert81df4522019-08-30 15:22:28 +00003545
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003546 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00003547 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003548 Base::updateImpl(A);
3549
Johannes Doerfert234eda52019-08-16 19:51:23 +00003550 const DataLayout &DL = A.getDataLayout();
3551
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003552 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3553 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003554 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3555 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003556 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003557 const MaybeAlign PA = V.getPointerAlignment(DL);
3558 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003559 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003560 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003561 // Use abstract attribute information.
3562 const AAAlign::StateType &DS =
3563 static_cast<const AAAlign::StateType &>(AA.getState());
3564 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003565 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003566 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003567 };
3568
3569 StateType T;
3570 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3571 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003572 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003573
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003574 // TODO: If we know we visited all incoming values, thus no are assumed
3575 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003576 return clampStateAndIndicateChange(getState(), T);
3577 }
3578
3579 /// See AbstractAttribute::trackStatistics()
3580 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3581};
3582
3583/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003584struct AAAlignReturned final
3585 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003586 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003587 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003588
3589 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003590 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003591};
3592
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003593/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003594struct AAAlignArgument final
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003595 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3596 AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003597 AAAlignArgument(const IRPosition &IRP)
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003598 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3599 AAAlignImpl>(
3600 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003601
3602 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003603 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003604};
3605
Johannes Doerfert234eda52019-08-16 19:51:23 +00003606struct AAAlignCallSiteArgument final : AAAlignFloating {
3607 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003608
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003609 /// See AbstractAttribute::manifest(...).
3610 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003611 ChangeStatus Changed = AAAlignImpl::manifest(A);
3612 MaybeAlign InheritAlign =
3613 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3614 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3615 Changed = ChangeStatus::UNCHANGED;
3616 return Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003617 }
3618
Johannes Doerfertdada8132019-12-31 01:27:50 -06003619 /// See AbstractAttribute::updateImpl(Attributor &A).
3620 ChangeStatus updateImpl(Attributor &A) override {
3621 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
3622 if (Argument *Arg = getAssociatedArgument()) {
3623 const auto &ArgAlignAA = A.getAAFor<AAAlign>(
3624 *this, IRPosition::argument(*Arg), /* TrackDependence */ false,
3625 DepClassTy::OPTIONAL);
3626 takeKnownMaximum(ArgAlignAA.getKnownAlign());
3627 }
3628 return Changed;
3629 }
3630
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003631 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003632 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003633};
3634
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003635/// Align attribute deduction for a call site return value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003636struct AAAlignCallSiteReturned final
3637 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3638 AAAlignImpl> {
3639 using Base =
3640 AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3641 AAAlignImpl>;
3642 AAAlignCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003643
3644 /// See AbstractAttribute::initialize(...).
3645 void initialize(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003646 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003647 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003648 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003649 indicatePessimisticFixpoint();
3650 }
3651
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003652 /// See AbstractAttribute::trackStatistics()
3653 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3654};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003655
Johannes Doerferte83f3032019-08-05 23:22:05 +00003656/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003657struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003658 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003659
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003660 /// See AbstractAttribute::initialize(...).
3661 void initialize(Attributor &A) override {
3662 AANoReturn::initialize(A);
3663 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003664 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003665 indicatePessimisticFixpoint();
3666 }
3667
Johannes Doerferte83f3032019-08-05 23:22:05 +00003668 /// See AbstractAttribute::getAsStr().
3669 const std::string getAsStr() const override {
3670 return getAssumed() ? "noreturn" : "may-return";
3671 }
3672
Johannes Doerferte83f3032019-08-05 23:22:05 +00003673 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00003674 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003675 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003676 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003677 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003678 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003679 return ChangeStatus::UNCHANGED;
3680 }
3681};
3682
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003683struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003684 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003685
3686 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003687 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003688};
3689
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003690/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003691struct AANoReturnCallSite final : AANoReturnImpl {
3692 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3693
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003694 /// See AbstractAttribute::updateImpl(...).
3695 ChangeStatus updateImpl(Attributor &A) override {
3696 // TODO: Once we have call site specific value information we can provide
3697 // call site specific liveness information and then it makes
3698 // sense to specialize attributes for call sites arguments instead of
3699 // redirecting requests to the callee argument.
3700 Function *F = getAssociatedFunction();
3701 const IRPosition &FnPos = IRPosition::function(*F);
3702 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3703 return clampStateAndIndicateChange(
3704 getState(),
3705 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3706 }
3707
3708 /// See AbstractAttribute::trackStatistics()
3709 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3710};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003711
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003712/// ----------------------- Variable Capturing ---------------------------------
3713
3714/// A class to hold the state of for no-capture attributes.
3715struct AANoCaptureImpl : public AANoCapture {
3716 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3717
3718 /// See AbstractAttribute::initialize(...).
3719 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003720 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3721 indicateOptimisticFixpoint();
3722 return;
3723 }
3724 Function *AnchorScope = getAnchorScope();
3725 if (isFnInterfaceKind() &&
3726 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3727 indicatePessimisticFixpoint();
3728 return;
3729 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003730
Johannes Doerfert72adda12019-10-10 05:33:21 +00003731 // You cannot "capture" null in the default address space.
3732 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3733 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3734 indicateOptimisticFixpoint();
3735 return;
3736 }
3737
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003738 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003739
3740 // Check what state the associated function can actually capture.
3741 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003742 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003743 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003744 indicatePessimisticFixpoint();
3745 }
3746
3747 /// See AbstractAttribute::updateImpl(...).
3748 ChangeStatus updateImpl(Attributor &A) override;
3749
3750 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3751 virtual void
3752 getDeducedAttributes(LLVMContext &Ctx,
3753 SmallVectorImpl<Attribute> &Attrs) const override {
3754 if (!isAssumedNoCaptureMaybeReturned())
3755 return;
3756
Hideto Ueno37367642019-09-11 06:52:11 +00003757 if (getArgNo() >= 0) {
3758 if (isAssumedNoCapture())
3759 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3760 else if (ManifestInternal)
3761 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3762 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003763 }
3764
3765 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3766 /// depending on the ability of the function associated with \p IRP to capture
3767 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003768 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3769 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003770 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003771 // TODO: Once we have memory behavior attributes we should use them here.
3772
3773 // If we know we cannot communicate or write to memory, we do not care about
3774 // ptr2int anymore.
3775 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3776 F.getReturnType()->isVoidTy()) {
3777 State.addKnownBits(NO_CAPTURE);
3778 return;
3779 }
3780
3781 // A function cannot capture state in memory if it only reads memory, it can
3782 // however return/throw state and the state might be influenced by the
3783 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3784 if (F.onlyReadsMemory())
3785 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3786
3787 // A function cannot communicate state back if it does not through
3788 // exceptions and doesn not return values.
3789 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
3790 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00003791
3792 // Check existing "returned" attributes.
3793 int ArgNo = IRP.getArgNo();
3794 if (F.doesNotThrow() && ArgNo >= 0) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01003795 for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
Johannes Doerfert3839b572019-10-21 00:48:42 +00003796 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00003797 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00003798 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
3799 else if (F.onlyReadsMemory())
3800 State.addKnownBits(NO_CAPTURE);
3801 else
3802 State.addKnownBits(NOT_CAPTURED_IN_RET);
3803 break;
3804 }
3805 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003806 }
3807
3808 /// See AbstractState::getAsStr().
3809 const std::string getAsStr() const override {
3810 if (isKnownNoCapture())
3811 return "known not-captured";
3812 if (isAssumedNoCapture())
3813 return "assumed not-captured";
3814 if (isKnownNoCaptureMaybeReturned())
3815 return "known not-captured-maybe-returned";
3816 if (isAssumedNoCaptureMaybeReturned())
3817 return "assumed not-captured-maybe-returned";
3818 return "assumed-captured";
3819 }
3820};
3821
3822/// Attributor-aware capture tracker.
3823struct AACaptureUseTracker final : public CaptureTracker {
3824
3825 /// Create a capture tracker that can lookup in-flight abstract attributes
3826 /// through the Attributor \p A.
3827 ///
3828 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
3829 /// search is stopped. If a use leads to a return instruction,
3830 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
3831 /// If a use leads to a ptr2int which may capture the value,
3832 /// \p CapturedInInteger is set. If a use is found that is currently assumed
3833 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
3834 /// set. All values in \p PotentialCopies are later tracked as well. For every
3835 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
3836 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
3837 /// conservatively set to true.
3838 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05003839 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003840 SmallVectorImpl<const Value *> &PotentialCopies,
3841 unsigned &RemainingUsesToExplore)
3842 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
3843 PotentialCopies(PotentialCopies),
3844 RemainingUsesToExplore(RemainingUsesToExplore) {}
3845
3846 /// Determine if \p V maybe captured. *Also updates the state!*
3847 bool valueMayBeCaptured(const Value *V) {
3848 if (V->getType()->isPointerTy()) {
3849 PointerMayBeCaptured(V, this);
3850 } else {
3851 State.indicatePessimisticFixpoint();
3852 }
3853 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3854 }
3855
3856 /// See CaptureTracker::tooManyUses().
3857 void tooManyUses() override {
3858 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3859 }
3860
3861 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3862 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3863 return true;
3864 const auto &DerefAA =
3865 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3866 return DerefAA.getAssumedDereferenceableBytes();
3867 }
3868
3869 /// See CaptureTracker::captured(...).
3870 bool captured(const Use *U) override {
3871 Instruction *UInst = cast<Instruction>(U->getUser());
3872 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3873 << "\n");
3874
3875 // Because we may reuse the tracker multiple times we keep track of the
3876 // number of explored uses ourselves as well.
3877 if (RemainingUsesToExplore-- == 0) {
3878 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3879 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3880 /* Return */ true);
3881 }
3882
3883 // Deal with ptr2int by following uses.
3884 if (isa<PtrToIntInst>(UInst)) {
3885 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3886 return valueMayBeCaptured(UInst);
3887 }
3888
3889 // Explicitly catch return instructions.
3890 if (isa<ReturnInst>(UInst))
3891 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3892 /* Return */ true);
3893
3894 // For now we only use special logic for call sites. However, the tracker
3895 // itself knows about a lot of other non-capturing cases already.
3896 CallSite CS(UInst);
3897 if (!CS || !CS.isArgOperand(U))
3898 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3899 /* Return */ true);
3900
3901 unsigned ArgNo = CS.getArgumentNo(U);
3902 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3903 // If we have a abstract no-capture attribute for the argument we can use
3904 // it to justify a non-capture attribute here. This allows recursion!
3905 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3906 if (ArgNoCaptureAA.isAssumedNoCapture())
3907 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3908 /* Return */ false);
3909 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3910 addPotentialCopy(CS);
3911 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3912 /* Return */ false);
3913 }
3914
3915 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3916 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3917 /* Return */ true);
3918 }
3919
3920 /// Register \p CS as potential copy of the value we are checking.
3921 void addPotentialCopy(CallSite CS) {
3922 PotentialCopies.push_back(CS.getInstruction());
3923 }
3924
3925 /// See CaptureTracker::shouldExplore(...).
3926 bool shouldExplore(const Use *U) override {
3927 // Check liveness.
3928 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3929 }
3930
3931 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3932 /// \p CapturedInRet, then return the appropriate value for use in the
3933 /// CaptureTracker::captured() interface.
3934 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3935 bool CapturedInRet) {
3936 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3937 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3938 if (CapturedInMem)
3939 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3940 if (CapturedInInt)
3941 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3942 if (CapturedInRet)
3943 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3944 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3945 }
3946
3947private:
3948 /// The attributor providing in-flight abstract attributes.
3949 Attributor &A;
3950
3951 /// The abstract attribute currently updated.
3952 AANoCapture &NoCaptureAA;
3953
3954 /// The abstract liveness state.
3955 const AAIsDead &IsDeadAA;
3956
3957 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05003958 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003959
3960 /// Set of potential copies of the tracked value.
3961 SmallVectorImpl<const Value *> &PotentialCopies;
3962
3963 /// Global counter to limit the number of explored uses.
3964 unsigned &RemainingUsesToExplore;
3965};
3966
3967ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
3968 const IRPosition &IRP = getIRPosition();
3969 const Value *V =
3970 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
3971 if (!V)
3972 return indicatePessimisticFixpoint();
3973
3974 const Function *F =
3975 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
3976 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00003977 const IRPosition &FnPos = IRPosition::function(*F);
3978 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, FnPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003979
3980 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003981
Johannes Doerfert3839b572019-10-21 00:48:42 +00003982 // Readonly means we cannot capture through memory.
3983 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
3984 if (FnMemAA.isAssumedReadOnly()) {
3985 T.addKnownBits(NOT_CAPTURED_IN_MEM);
3986 if (FnMemAA.isKnownReadOnly())
3987 addKnownBits(NOT_CAPTURED_IN_MEM);
3988 }
3989
3990 // Make sure all returned values are different than the underlying value.
3991 // TODO: we could do this in a more sophisticated way inside
3992 // AAReturnedValues, e.g., track all values that escape through returns
3993 // directly somehow.
3994 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
3995 bool SeenConstant = false;
3996 for (auto &It : RVAA.returned_values()) {
3997 if (isa<Constant>(It.first)) {
3998 if (SeenConstant)
3999 return false;
4000 SeenConstant = true;
4001 } else if (!isa<Argument>(It.first) ||
4002 It.first == getAssociatedArgument())
4003 return false;
4004 }
4005 return true;
4006 };
4007
4008 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, FnPos);
4009 if (NoUnwindAA.isAssumedNoUnwind()) {
4010 bool IsVoidTy = F->getReturnType()->isVoidTy();
4011 const AAReturnedValues *RVAA =
4012 IsVoidTy ? nullptr : &A.getAAFor<AAReturnedValues>(*this, FnPos);
4013 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
4014 T.addKnownBits(NOT_CAPTURED_IN_RET);
4015 if (T.isKnown(NOT_CAPTURED_IN_MEM))
4016 return ChangeStatus::UNCHANGED;
4017 if (NoUnwindAA.isKnownNoUnwind() &&
4018 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
4019 addKnownBits(NOT_CAPTURED_IN_RET);
4020 if (isKnown(NOT_CAPTURED_IN_MEM))
4021 return indicateOptimisticFixpoint();
4022 }
4023 }
4024 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004025
4026 // Use the CaptureTracker interface and logic with the specialized tracker,
4027 // defined in AACaptureUseTracker, that can look at in-flight abstract
4028 // attributes and directly updates the assumed state.
4029 SmallVector<const Value *, 4> PotentialCopies;
4030 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
4031 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
4032 RemainingUsesToExplore);
4033
4034 // Check all potential copies of the associated value until we can assume
4035 // none will be captured or we have to assume at least one might be.
4036 unsigned Idx = 0;
4037 PotentialCopies.push_back(V);
4038 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
4039 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
4040
Johannes Doerfert1a746452019-10-20 22:28:49 -05004041 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004042 auto Assumed = S.getAssumed();
4043 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05004044 if (!isAssumedNoCaptureMaybeReturned())
4045 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004046 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
4047 : ChangeStatus::CHANGED;
4048}
4049
4050/// NoCapture attribute for function arguments.
4051struct AANoCaptureArgument final : AANoCaptureImpl {
4052 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4053
4054 /// See AbstractAttribute::trackStatistics()
4055 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
4056};
4057
4058/// NoCapture attribute for call site arguments.
4059struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
4060 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4061
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004062 /// See AbstractAttribute::initialize(...).
4063 void initialize(Attributor &A) override {
4064 if (Argument *Arg = getAssociatedArgument())
4065 if (Arg->hasByValAttr())
4066 indicateOptimisticFixpoint();
4067 AANoCaptureImpl::initialize(A);
4068 }
4069
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004070 /// See AbstractAttribute::updateImpl(...).
4071 ChangeStatus updateImpl(Attributor &A) override {
4072 // TODO: Once we have call site specific value information we can provide
4073 // call site specific liveness information and then it makes
4074 // sense to specialize attributes for call sites arguments instead of
4075 // redirecting requests to the callee argument.
4076 Argument *Arg = getAssociatedArgument();
4077 if (!Arg)
4078 return indicatePessimisticFixpoint();
4079 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4080 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
4081 return clampStateAndIndicateChange(
4082 getState(),
4083 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
4084 }
4085
4086 /// See AbstractAttribute::trackStatistics()
4087 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
4088};
4089
4090/// NoCapture attribute for floating values.
4091struct AANoCaptureFloating final : AANoCaptureImpl {
4092 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4093
4094 /// See AbstractAttribute::trackStatistics()
4095 void trackStatistics() const override {
4096 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
4097 }
4098};
4099
4100/// NoCapture attribute for function return value.
4101struct AANoCaptureReturned final : AANoCaptureImpl {
4102 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
4103 llvm_unreachable("NoCapture is not applicable to function returns!");
4104 }
4105
4106 /// See AbstractAttribute::initialize(...).
4107 void initialize(Attributor &A) override {
4108 llvm_unreachable("NoCapture is not applicable to function returns!");
4109 }
4110
4111 /// See AbstractAttribute::updateImpl(...).
4112 ChangeStatus updateImpl(Attributor &A) override {
4113 llvm_unreachable("NoCapture is not applicable to function returns!");
4114 }
4115
4116 /// See AbstractAttribute::trackStatistics()
4117 void trackStatistics() const override {}
4118};
4119
4120/// NoCapture attribute deduction for a call site return value.
4121struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
4122 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4123
4124 /// See AbstractAttribute::trackStatistics()
4125 void trackStatistics() const override {
4126 STATS_DECLTRACK_CSRET_ATTR(nocapture)
4127 }
4128};
4129
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004130/// ------------------ Value Simplify Attribute ----------------------------
4131struct AAValueSimplifyImpl : AAValueSimplify {
4132 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
4133
Johannes Doerfert9dcf8892020-01-11 23:59:36 -06004134 /// See AbstractAttribute::initialize(...).
4135 void initialize(Attributor &A) override {
4136 if (getAssociatedValue().getType()->isVoidTy())
4137 indicatePessimisticFixpoint();
4138 }
4139
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004140 /// See AbstractAttribute::getAsStr().
4141 const std::string getAsStr() const override {
4142 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
4143 : "not-simple";
4144 }
4145
4146 /// See AbstractAttribute::trackStatistics()
4147 void trackStatistics() const override {}
4148
4149 /// See AAValueSimplify::getAssumedSimplifiedValue()
4150 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
4151 if (!getAssumed())
4152 return const_cast<Value *>(&getAssociatedValue());
4153 return SimplifiedAssociatedValue;
4154 }
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004155
4156 /// Helper function for querying AAValueSimplify and updating candicate.
4157 /// \param QueryingValue Value trying to unify with SimplifiedValue
4158 /// \param AccumulatedSimplifiedValue Current simplification result.
4159 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
4160 Value &QueryingValue,
4161 Optional<Value *> &AccumulatedSimplifiedValue) {
4162 // FIXME: Add a typecast support.
4163
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004164 auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004165 QueryingAA, IRPosition::value(QueryingValue));
4166
4167 Optional<Value *> QueryingValueSimplified =
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004168 ValueSimplifyAA.getAssumedSimplifiedValue(A);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004169
4170 if (!QueryingValueSimplified.hasValue())
4171 return true;
4172
4173 if (!QueryingValueSimplified.getValue())
4174 return false;
4175
4176 Value &QueryingValueSimplifiedUnwrapped =
4177 *QueryingValueSimplified.getValue();
4178
4179 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
4180 return true;
4181
4182 if (AccumulatedSimplifiedValue.hasValue())
4183 return AccumulatedSimplifiedValue == QueryingValueSimplified;
4184
4185 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
4186 << " is assumed to be "
4187 << QueryingValueSimplifiedUnwrapped << "\n");
4188
4189 AccumulatedSimplifiedValue = QueryingValueSimplified;
4190 return true;
4191 }
4192
Hideto Ueno188f9a32020-01-15 15:25:52 +09004193 bool askSimplifiedValueForAAValueConstantRange(Attributor &A) {
4194 if (!getAssociatedValue().getType()->isIntegerTy())
4195 return false;
4196
4197 const auto &ValueConstantRangeAA =
4198 A.getAAFor<AAValueConstantRange>(*this, getIRPosition());
4199
4200 Optional<ConstantInt *> COpt =
4201 ValueConstantRangeAA.getAssumedConstantInt(A);
4202 if (COpt.hasValue()) {
4203 if (auto *C = COpt.getValue())
4204 SimplifiedAssociatedValue = C;
4205 else
4206 return false;
4207 } else {
4208 // FIXME: It should be llvm::None but if you set llvm::None,
4209 // values are mistakenly infered as `undef` now.
4210 SimplifiedAssociatedValue = &getAssociatedValue();
4211 }
4212 return true;
4213 }
4214
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004215 /// See AbstractAttribute::manifest(...).
4216 ChangeStatus manifest(Attributor &A) override {
4217 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4218
4219 if (!SimplifiedAssociatedValue.hasValue() ||
4220 !SimplifiedAssociatedValue.getValue())
4221 return Changed;
4222
4223 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
4224 // We can replace the AssociatedValue with the constant.
4225 Value &V = getAssociatedValue();
4226 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
4227 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
4228 << "\n");
Hideto Ueno34fe8d02019-12-30 17:08:48 +09004229 A.changeValueAfterManifest(V, *C);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004230 Changed = ChangeStatus::CHANGED;
4231 }
4232 }
4233
4234 return Changed | AAValueSimplify::manifest(A);
4235 }
4236
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004237 /// See AbstractState::indicatePessimisticFixpoint(...).
4238 ChangeStatus indicatePessimisticFixpoint() override {
4239 // NOTE: Associated value will be returned in a pessimistic fixpoint and is
4240 // regarded as known. That's why`indicateOptimisticFixpoint` is called.
4241 SimplifiedAssociatedValue = &getAssociatedValue();
Johannes Doerferta4b35882019-12-31 13:25:47 -06004242 indicateOptimisticFixpoint();
4243 return ChangeStatus::CHANGED;
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004244 }
4245
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004246protected:
4247 // An assumed simplified value. Initially, it is set to Optional::None, which
4248 // means that the value is not clear under current assumption. If in the
4249 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4250 // returns orignal associated value.
4251 Optional<Value *> SimplifiedAssociatedValue;
4252};
4253
4254struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
4255 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4256
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004257 void initialize(Attributor &A) override {
4258 AAValueSimplifyImpl::initialize(A);
4259 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
4260 indicatePessimisticFixpoint();
4261 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
4262 /* IgnoreSubsumingPositions */ true))
4263 indicatePessimisticFixpoint();
4264 }
4265
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004266 /// See AbstractAttribute::updateImpl(...).
4267 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004268 // Byval is only replacable if it is readonly otherwise we would write into
4269 // the replaced value and not the copy that byval creates implicitly.
4270 Argument *Arg = getAssociatedArgument();
4271 if (Arg->hasByValAttr()) {
4272 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
4273 if (!MemAA.isAssumedReadOnly())
4274 return indicatePessimisticFixpoint();
4275 }
4276
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004277 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4278
Johannes Doerfert661db042019-10-07 23:14:58 +00004279 auto PredForCallSite = [&](AbstractCallSite ACS) {
4280 // Check if we have an associated argument or not (which can happen for
4281 // callback calls).
Johannes Doerferte360ee62019-11-01 18:45:25 -05004282 Value *ArgOp = ACS.getCallArgOperand(getArgNo());
4283 if (!ArgOp)
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004284 return false;
Johannes Doerferte360ee62019-11-01 18:45:25 -05004285 // We can only propagate thread independent values through callbacks.
4286 // This is different to direct/indirect call sites because for them we
4287 // know the thread executing the caller and callee is the same. For
4288 // callbacks this is not guaranteed, thus a thread dependent value could
4289 // be different for the caller and callee, making it invalid to propagate.
4290 if (ACS.isCallbackCall())
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004291 if (auto *C = dyn_cast<Constant>(ArgOp))
Johannes Doerferte360ee62019-11-01 18:45:25 -05004292 if (C->isThreadDependent())
4293 return false;
4294 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004295 };
4296
4297 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004298 if (!askSimplifiedValueForAAValueConstantRange(A))
4299 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004300
4301 // If a candicate was found in this update, return CHANGED.
4302 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4303 ? ChangeStatus::UNCHANGED
4304 : ChangeStatus ::CHANGED;
4305 }
4306
4307 /// See AbstractAttribute::trackStatistics()
4308 void trackStatistics() const override {
4309 STATS_DECLTRACK_ARG_ATTR(value_simplify)
4310 }
4311};
4312
4313struct AAValueSimplifyReturned : AAValueSimplifyImpl {
4314 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4315
4316 /// See AbstractAttribute::updateImpl(...).
4317 ChangeStatus updateImpl(Attributor &A) override {
4318 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4319
4320 auto PredForReturned = [&](Value &V) {
4321 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4322 };
4323
4324 if (!A.checkForAllReturnedValues(PredForReturned, *this))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004325 if (!askSimplifiedValueForAAValueConstantRange(A))
4326 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004327
4328 // If a candicate was found in this update, return CHANGED.
4329 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4330 ? ChangeStatus::UNCHANGED
4331 : ChangeStatus ::CHANGED;
4332 }
4333 /// See AbstractAttribute::trackStatistics()
4334 void trackStatistics() const override {
4335 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
4336 }
4337};
4338
4339struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4340 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4341
4342 /// See AbstractAttribute::initialize(...).
4343 void initialize(Attributor &A) override {
4344 Value &V = getAnchorValue();
4345
4346 // TODO: add other stuffs
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004347 if (isa<Constant>(V))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004348 indicatePessimisticFixpoint();
4349 }
4350
4351 /// See AbstractAttribute::updateImpl(...).
4352 ChangeStatus updateImpl(Attributor &A) override {
4353 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4354
4355 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
4356 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
4357 if (!Stripped && this == &AA) {
4358 // TODO: Look the instruction and check recursively.
Hideto Ueno188f9a32020-01-15 15:25:52 +09004359
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004360 LLVM_DEBUG(
4361 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
4362 << V << "\n");
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004363 return false;
4364 }
4365 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4366 };
4367
4368 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
4369 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
4370 VisitValueCB))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004371 if (!askSimplifiedValueForAAValueConstantRange(A))
4372 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004373
4374 // If a candicate was found in this update, return CHANGED.
4375
4376 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4377 ? ChangeStatus::UNCHANGED
4378 : ChangeStatus ::CHANGED;
4379 }
4380
4381 /// See AbstractAttribute::trackStatistics()
4382 void trackStatistics() const override {
4383 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
4384 }
4385};
4386
4387struct AAValueSimplifyFunction : AAValueSimplifyImpl {
4388 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4389
4390 /// See AbstractAttribute::initialize(...).
4391 void initialize(Attributor &A) override {
4392 SimplifiedAssociatedValue = &getAnchorValue();
4393 indicateOptimisticFixpoint();
4394 }
4395 /// See AbstractAttribute::initialize(...).
4396 ChangeStatus updateImpl(Attributor &A) override {
4397 llvm_unreachable(
4398 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
4399 }
4400 /// See AbstractAttribute::trackStatistics()
4401 void trackStatistics() const override {
4402 STATS_DECLTRACK_FN_ATTR(value_simplify)
4403 }
4404};
4405
4406struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
4407 AAValueSimplifyCallSite(const IRPosition &IRP)
4408 : AAValueSimplifyFunction(IRP) {}
4409 /// See AbstractAttribute::trackStatistics()
4410 void trackStatistics() const override {
4411 STATS_DECLTRACK_CS_ATTR(value_simplify)
4412 }
4413};
4414
4415struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
4416 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
4417 : AAValueSimplifyReturned(IRP) {}
4418
4419 void trackStatistics() const override {
4420 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
4421 }
4422};
4423struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
4424 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
4425 : AAValueSimplifyFloating(IRP) {}
4426
4427 void trackStatistics() const override {
4428 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
4429 }
4430};
4431
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004432/// ----------------------- Heap-To-Stack Conversion ---------------------------
4433struct AAHeapToStackImpl : public AAHeapToStack {
4434 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
4435
4436 const std::string getAsStr() const override {
4437 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
4438 }
4439
4440 ChangeStatus manifest(Attributor &A) override {
4441 assert(getState().isValidState() &&
4442 "Attempted to manifest an invalid state!");
4443
4444 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4445 Function *F = getAssociatedFunction();
4446 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4447
4448 for (Instruction *MallocCall : MallocCalls) {
4449 // This malloc cannot be replaced.
4450 if (BadMallocCalls.count(MallocCall))
4451 continue;
4452
4453 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
4454 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
4455 A.deleteAfterManifest(*FreeCall);
4456 HasChanged = ChangeStatus::CHANGED;
4457 }
4458
4459 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
4460 << "\n");
4461
4462 Constant *Size;
4463 if (isCallocLikeFn(MallocCall, TLI)) {
4464 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
4465 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
4466 APInt TotalSize = SizeT->getValue() * Num->getValue();
4467 Size =
4468 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
4469 } else {
4470 Size = cast<ConstantInt>(MallocCall->getOperand(0));
4471 }
4472
4473 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
4474 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
4475 Size, "", MallocCall->getNextNode());
4476
4477 if (AI->getType() != MallocCall->getType())
4478 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
4479 AI->getNextNode());
4480
Johannes Doerfert5d346022019-12-13 22:11:42 -06004481 replaceAllInstructionUsesWith(*MallocCall, *AI);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004482
4483 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
4484 auto *NBB = II->getNormalDest();
4485 BranchInst::Create(NBB, MallocCall->getParent());
4486 A.deleteAfterManifest(*MallocCall);
4487 } else {
4488 A.deleteAfterManifest(*MallocCall);
4489 }
4490
4491 if (isCallocLikeFn(MallocCall, TLI)) {
4492 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
4493 AI->getNextNode());
4494 Value *Ops[] = {
4495 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
4496 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
4497
4498 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
4499 Module *M = F->getParent();
4500 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
4501 CallInst::Create(Fn, Ops, "", BI->getNextNode());
4502 }
4503 HasChanged = ChangeStatus::CHANGED;
4504 }
4505
4506 return HasChanged;
4507 }
4508
4509 /// Collection of all malloc calls in a function.
4510 SmallSetVector<Instruction *, 4> MallocCalls;
4511
4512 /// Collection of malloc calls that cannot be converted.
4513 DenseSet<const Instruction *> BadMallocCalls;
4514
4515 /// A map for each malloc call to the set of associated free calls.
4516 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
4517
4518 ChangeStatus updateImpl(Attributor &A) override;
4519};
4520
4521ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4522 const Function *F = getAssociatedFunction();
4523 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4524
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004525 MustBeExecutedContextExplorer &Explorer =
4526 A.getInfoCache().getMustBeExecutedContextExplorer();
4527
4528 auto FreeCheck = [&](Instruction &I) {
4529 const auto &Frees = FreesForMalloc.lookup(&I);
4530 if (Frees.size() != 1)
4531 return false;
4532 Instruction *UniqueFree = *Frees.begin();
4533 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
4534 };
4535
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004536 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004537 bool ValidUsesOnly = true;
4538 bool MustUse = true;
Hideto Ueno827bade2019-12-12 12:26:30 +00004539 auto Pred = [&](const Use &U, bool &Follow) -> bool {
4540 Instruction *UserI = cast<Instruction>(U.getUser());
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004541 if (isa<LoadInst>(UserI))
Hideto Ueno827bade2019-12-12 12:26:30 +00004542 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004543 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004544 if (SI->getValueOperand() == U.get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004545 LLVM_DEBUG(dbgs()
4546 << "[H2S] escaping store to memory: " << *UserI << "\n");
4547 ValidUsesOnly = false;
4548 } else {
4549 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004550 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004551 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004552 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004553 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004554 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
4555 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004556 // Record malloc.
4557 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004558 if (MustUse) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004559 FreesForMalloc[&I].insert(UserI);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004560 } else {
4561 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
4562 << *UserI << "\n");
4563 ValidUsesOnly = false;
4564 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004565 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004566 }
4567
Hideto Ueno827bade2019-12-12 12:26:30 +00004568 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004569
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004570 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
4571 *this, IRPosition::callsite_argument(*CB, ArgNo));
4572
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004573 // If a callsite argument use is nofree, we are fine.
4574 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
4575 *this, IRPosition::callsite_argument(*CB, ArgNo));
4576
Hideto Ueno827bade2019-12-12 12:26:30 +00004577 if (!NoCaptureAA.isAssumedNoCapture() ||
4578 !ArgNoFreeAA.isAssumedNoFree()) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004579 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004580 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004581 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004582 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004583 }
4584
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004585 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
4586 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
4587 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Hideto Ueno827bade2019-12-12 12:26:30 +00004588 Follow = true;
4589 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004590 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004591 // Unknown user for which we can not track uses further (in a way that
4592 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004593 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004594 ValidUsesOnly = false;
Hideto Ueno827bade2019-12-12 12:26:30 +00004595 return true;
4596 };
4597 A.checkForAllUses(Pred, *this, I);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004598 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004599 };
4600
4601 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004602 if (BadMallocCalls.count(&I))
4603 return true;
4604
4605 bool IsMalloc = isMallocLikeFn(&I, TLI);
4606 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
4607 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004608 BadMallocCalls.insert(&I);
4609 return true;
4610 }
4611
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004612 if (IsMalloc) {
4613 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004614 if (Size->getValue().ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004615 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004616 MallocCalls.insert(&I);
4617 return true;
4618 }
4619 } else if (IsCalloc) {
4620 bool Overflow = false;
4621 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
4622 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
4623 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004624 .ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004625 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004626 MallocCalls.insert(&I);
4627 return true;
4628 }
4629 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004630
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004631 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004632 return true;
4633 };
4634
4635 size_t NumBadMallocs = BadMallocCalls.size();
4636
4637 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4638
4639 if (NumBadMallocs != BadMallocCalls.size())
4640 return ChangeStatus::CHANGED;
4641
4642 return ChangeStatus::UNCHANGED;
4643}
4644
4645struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4646 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4647
4648 /// See AbstractAttribute::trackStatistics()
4649 void trackStatistics() const override {
4650 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004651 "Number of malloc calls converted to allocas");
4652 for (auto *C : MallocCalls)
4653 if (!BadMallocCalls.count(C))
4654 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004655 }
4656};
4657
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004658/// -------------------- Memory Behavior Attributes ----------------------------
4659/// Includes read-none, read-only, and write-only.
4660/// ----------------------------------------------------------------------------
4661struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
4662 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
4663
4664 /// See AbstractAttribute::initialize(...).
4665 void initialize(Attributor &A) override {
4666 intersectAssumedBits(BEST_STATE);
4667 getKnownStateFromValue(getIRPosition(), getState());
4668 IRAttribute::initialize(A);
4669 }
4670
4671 /// Return the memory behavior information encoded in the IR for \p IRP.
4672 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004673 BitIntegerState &State,
4674 bool IgnoreSubsumingPositions = false) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004675 SmallVector<Attribute, 2> Attrs;
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004676 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004677 for (const Attribute &Attr : Attrs) {
4678 switch (Attr.getKindAsEnum()) {
4679 case Attribute::ReadNone:
4680 State.addKnownBits(NO_ACCESSES);
4681 break;
4682 case Attribute::ReadOnly:
4683 State.addKnownBits(NO_WRITES);
4684 break;
4685 case Attribute::WriteOnly:
4686 State.addKnownBits(NO_READS);
4687 break;
4688 default:
4689 llvm_unreachable("Unexpcted attribute!");
4690 }
4691 }
4692
4693 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
4694 if (!I->mayReadFromMemory())
4695 State.addKnownBits(NO_READS);
4696 if (!I->mayWriteToMemory())
4697 State.addKnownBits(NO_WRITES);
4698 }
4699 }
4700
4701 /// See AbstractAttribute::getDeducedAttributes(...).
4702 void getDeducedAttributes(LLVMContext &Ctx,
4703 SmallVectorImpl<Attribute> &Attrs) const override {
4704 assert(Attrs.size() == 0);
4705 if (isAssumedReadNone())
4706 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
4707 else if (isAssumedReadOnly())
4708 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
4709 else if (isAssumedWriteOnly())
4710 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
4711 assert(Attrs.size() <= 1);
4712 }
4713
4714 /// See AbstractAttribute::manifest(...).
4715 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05004716 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004717
4718 // Check if we would improve the existing attributes first.
4719 SmallVector<Attribute, 4> DeducedAttrs;
4720 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
4721 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
4722 return IRP.hasAttr(Attr.getKindAsEnum(),
4723 /* IgnoreSubsumingPositions */ true);
4724 }))
4725 return ChangeStatus::UNCHANGED;
4726
4727 // Clear existing attributes.
4728 IRP.removeAttrs(AttrKinds);
4729
4730 // Use the generic manifest method.
4731 return IRAttribute::manifest(A);
4732 }
4733
4734 /// See AbstractState::getAsStr().
4735 const std::string getAsStr() const override {
4736 if (isAssumedReadNone())
4737 return "readnone";
4738 if (isAssumedReadOnly())
4739 return "readonly";
4740 if (isAssumedWriteOnly())
4741 return "writeonly";
4742 return "may-read/write";
4743 }
4744
4745 /// The set of IR attributes AAMemoryBehavior deals with.
4746 static const Attribute::AttrKind AttrKinds[3];
4747};
4748
4749const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
4750 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
4751
4752/// Memory behavior attribute for a floating value.
4753struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
4754 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4755
4756 /// See AbstractAttribute::initialize(...).
4757 void initialize(Attributor &A) override {
4758 AAMemoryBehaviorImpl::initialize(A);
4759 // Initialize the use vector with all direct uses of the associated value.
4760 for (const Use &U : getAssociatedValue().uses())
4761 Uses.insert(&U);
4762 }
4763
4764 /// See AbstractAttribute::updateImpl(...).
4765 ChangeStatus updateImpl(Attributor &A) override;
4766
4767 /// See AbstractAttribute::trackStatistics()
4768 void trackStatistics() const override {
4769 if (isAssumedReadNone())
4770 STATS_DECLTRACK_FLOATING_ATTR(readnone)
4771 else if (isAssumedReadOnly())
4772 STATS_DECLTRACK_FLOATING_ATTR(readonly)
4773 else if (isAssumedWriteOnly())
4774 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
4775 }
4776
4777private:
4778 /// Return true if users of \p UserI might access the underlying
4779 /// variable/location described by \p U and should therefore be analyzed.
4780 bool followUsersOfUseIn(Attributor &A, const Use *U,
4781 const Instruction *UserI);
4782
4783 /// Update the state according to the effect of use \p U in \p UserI.
4784 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
4785
4786protected:
4787 /// Container for (transitive) uses of the associated argument.
4788 SetVector<const Use *> Uses;
4789};
4790
4791/// Memory behavior attribute for function argument.
4792struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
4793 AAMemoryBehaviorArgument(const IRPosition &IRP)
4794 : AAMemoryBehaviorFloating(IRP) {}
4795
4796 /// See AbstractAttribute::initialize(...).
4797 void initialize(Attributor &A) override {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004798 intersectAssumedBits(BEST_STATE);
4799 const IRPosition &IRP = getIRPosition();
4800 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
4801 // can query it when we use has/getAttr. That would allow us to reuse the
4802 // initialize of the base class here.
4803 bool HasByVal =
4804 IRP.hasAttr({Attribute::ByVal}, /* IgnoreSubsumingPositions */ true);
4805 getKnownStateFromValue(IRP, getState(),
4806 /* IgnoreSubsumingPositions */ HasByVal);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004807
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004808 // Initialize the use vector with all direct uses of the associated value.
4809 Argument *Arg = getAssociatedArgument();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004810 if (!Arg || !Arg->getParent()->hasExactDefinition()) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004811 indicatePessimisticFixpoint();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004812 } else {
4813 // Initialize the use vector with all direct uses of the associated value.
4814 for (const Use &U : Arg->uses())
4815 Uses.insert(&U);
4816 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004817 }
4818
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004819 ChangeStatus manifest(Attributor &A) override {
4820 // TODO: From readattrs.ll: "inalloca parameters are always
4821 // considered written"
4822 if (hasAttr({Attribute::InAlloca})) {
4823 removeKnownBits(NO_WRITES);
4824 removeAssumedBits(NO_WRITES);
4825 }
4826 return AAMemoryBehaviorFloating::manifest(A);
4827 }
4828
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004829 /// See AbstractAttribute::trackStatistics()
4830 void trackStatistics() const override {
4831 if (isAssumedReadNone())
4832 STATS_DECLTRACK_ARG_ATTR(readnone)
4833 else if (isAssumedReadOnly())
4834 STATS_DECLTRACK_ARG_ATTR(readonly)
4835 else if (isAssumedWriteOnly())
4836 STATS_DECLTRACK_ARG_ATTR(writeonly)
4837 }
4838};
4839
4840struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
4841 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
4842 : AAMemoryBehaviorArgument(IRP) {}
4843
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004844 /// See AbstractAttribute::initialize(...).
4845 void initialize(Attributor &A) override {
4846 if (Argument *Arg = getAssociatedArgument()) {
4847 if (Arg->hasByValAttr()) {
4848 addKnownBits(NO_WRITES);
4849 removeKnownBits(NO_READS);
4850 removeAssumedBits(NO_READS);
4851 }
4852 } else {
4853 }
4854 AAMemoryBehaviorArgument::initialize(A);
4855 }
4856
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004857 /// See AbstractAttribute::updateImpl(...).
4858 ChangeStatus updateImpl(Attributor &A) override {
4859 // TODO: Once we have call site specific value information we can provide
4860 // call site specific liveness liveness information and then it makes
4861 // sense to specialize attributes for call sites arguments instead of
4862 // redirecting requests to the callee argument.
4863 Argument *Arg = getAssociatedArgument();
4864 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4865 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4866 return clampStateAndIndicateChange(
4867 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05004868 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004869 }
4870
4871 /// See AbstractAttribute::trackStatistics()
4872 void trackStatistics() const override {
4873 if (isAssumedReadNone())
4874 STATS_DECLTRACK_CSARG_ATTR(readnone)
4875 else if (isAssumedReadOnly())
4876 STATS_DECLTRACK_CSARG_ATTR(readonly)
4877 else if (isAssumedWriteOnly())
4878 STATS_DECLTRACK_CSARG_ATTR(writeonly)
4879 }
4880};
4881
4882/// Memory behavior attribute for a call site return position.
4883struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
4884 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
4885 : AAMemoryBehaviorFloating(IRP) {}
4886
4887 /// See AbstractAttribute::manifest(...).
4888 ChangeStatus manifest(Attributor &A) override {
4889 // We do not annotate returned values.
4890 return ChangeStatus::UNCHANGED;
4891 }
4892
4893 /// See AbstractAttribute::trackStatistics()
4894 void trackStatistics() const override {}
4895};
4896
4897/// An AA to represent the memory behavior function attributes.
4898struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
4899 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4900
4901 /// See AbstractAttribute::updateImpl(Attributor &A).
4902 virtual ChangeStatus updateImpl(Attributor &A) override;
4903
4904 /// See AbstractAttribute::manifest(...).
4905 ChangeStatus manifest(Attributor &A) override {
4906 Function &F = cast<Function>(getAnchorValue());
4907 if (isAssumedReadNone()) {
4908 F.removeFnAttr(Attribute::ArgMemOnly);
4909 F.removeFnAttr(Attribute::InaccessibleMemOnly);
4910 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
4911 }
4912 return AAMemoryBehaviorImpl::manifest(A);
4913 }
4914
4915 /// See AbstractAttribute::trackStatistics()
4916 void trackStatistics() const override {
4917 if (isAssumedReadNone())
4918 STATS_DECLTRACK_FN_ATTR(readnone)
4919 else if (isAssumedReadOnly())
4920 STATS_DECLTRACK_FN_ATTR(readonly)
4921 else if (isAssumedWriteOnly())
4922 STATS_DECLTRACK_FN_ATTR(writeonly)
4923 }
4924};
4925
4926/// AAMemoryBehavior attribute for call sites.
4927struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
4928 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4929
4930 /// See AbstractAttribute::initialize(...).
4931 void initialize(Attributor &A) override {
4932 AAMemoryBehaviorImpl::initialize(A);
4933 Function *F = getAssociatedFunction();
4934 if (!F || !F->hasExactDefinition())
4935 indicatePessimisticFixpoint();
4936 }
4937
4938 /// See AbstractAttribute::updateImpl(...).
4939 ChangeStatus updateImpl(Attributor &A) override {
4940 // TODO: Once we have call site specific value information we can provide
4941 // call site specific liveness liveness information and then it makes
4942 // sense to specialize attributes for call sites arguments instead of
4943 // redirecting requests to the callee argument.
4944 Function *F = getAssociatedFunction();
4945 const IRPosition &FnPos = IRPosition::function(*F);
4946 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4947 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05004948 getState(),
4949 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004950 }
4951
4952 /// See AbstractAttribute::trackStatistics()
4953 void trackStatistics() const override {
4954 if (isAssumedReadNone())
4955 STATS_DECLTRACK_CS_ATTR(readnone)
4956 else if (isAssumedReadOnly())
4957 STATS_DECLTRACK_CS_ATTR(readonly)
4958 else if (isAssumedWriteOnly())
4959 STATS_DECLTRACK_CS_ATTR(writeonly)
4960 }
4961};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00004962} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004963
4964ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
4965
4966 // The current assumed state used to determine a change.
4967 auto AssumedState = getAssumed();
4968
4969 auto CheckRWInst = [&](Instruction &I) {
4970 // If the instruction has an own memory behavior state, use it to restrict
4971 // the local state. No further analysis is required as the other memory
4972 // state is as optimistic as it gets.
4973 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
4974 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
4975 *this, IRPosition::callsite_function(ICS));
4976 intersectAssumedBits(MemBehaviorAA.getAssumed());
4977 return !isAtFixpoint();
4978 }
4979
4980 // Remove access kind modifiers if necessary.
4981 if (I.mayReadFromMemory())
4982 removeAssumedBits(NO_READS);
4983 if (I.mayWriteToMemory())
4984 removeAssumedBits(NO_WRITES);
4985 return !isAtFixpoint();
4986 };
4987
4988 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
4989 return indicatePessimisticFixpoint();
4990
4991 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
4992 : ChangeStatus::UNCHANGED;
4993}
4994
4995ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
4996
4997 const IRPosition &IRP = getIRPosition();
4998 const IRPosition &FnPos = IRPosition::function_scope(IRP);
4999 AAMemoryBehavior::StateType &S = getState();
5000
5001 // First, check the function scope. We take the known information and we avoid
5002 // work if the assumed information implies the current assumed information for
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005003 // this attribute. This is a valid for all but byval arguments.
5004 Argument *Arg = IRP.getAssociatedArgument();
5005 AAMemoryBehavior::base_t FnMemAssumedState =
5006 AAMemoryBehavior::StateType::getWorstState();
5007 if (!Arg || !Arg->hasByValAttr()) {
5008 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
5009 FnMemAssumedState = FnMemAA.getAssumed();
5010 S.addKnownBits(FnMemAA.getKnown());
5011 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
5012 return ChangeStatus::UNCHANGED;
5013 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005014
5015 // Make sure the value is not captured (except through "return"), if
5016 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005017 // check the potential aliases introduced by the capture. However, no need
5018 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert28880192019-12-31 00:57:00 -06005019 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
5020 *this, IRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005021 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005022 S.intersectAssumedBits(FnMemAssumedState);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005023 return ChangeStatus::CHANGED;
5024 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005025
5026 // The current assumed state used to determine a change.
5027 auto AssumedState = S.getAssumed();
5028
5029 // Liveness information to exclude dead users.
5030 // TODO: Take the FnPos once we have call site specific liveness information.
5031 const auto &LivenessAA = A.getAAFor<AAIsDead>(
5032 *this, IRPosition::function(*IRP.getAssociatedFunction()));
5033
5034 // Visit and expand uses until all are analyzed or a fixpoint is reached.
5035 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
5036 const Use *U = Uses[i];
5037 Instruction *UserI = cast<Instruction>(U->getUser());
5038 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
5039 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
5040 << "]\n");
5041 if (LivenessAA.isAssumedDead(UserI))
5042 continue;
5043
5044 // Check if the users of UserI should also be visited.
5045 if (followUsersOfUseIn(A, U, UserI))
5046 for (const Use &UserIUse : UserI->uses())
5047 Uses.insert(&UserIUse);
5048
5049 // If UserI might touch memory we analyze the use in detail.
5050 if (UserI->mayReadOrWriteMemory())
5051 analyzeUseIn(A, U, UserI);
5052 }
5053
5054 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5055 : ChangeStatus::UNCHANGED;
5056}
5057
5058bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
5059 const Instruction *UserI) {
5060 // The loaded value is unrelated to the pointer argument, no need to
5061 // follow the users of the load.
5062 if (isa<LoadInst>(UserI))
5063 return false;
5064
5065 // By default we follow all uses assuming UserI might leak information on U,
5066 // we have special handling for call sites operands though.
5067 ImmutableCallSite ICS(UserI);
5068 if (!ICS || !ICS.isArgOperand(U))
5069 return true;
5070
5071 // If the use is a call argument known not to be captured, the users of
5072 // the call do not need to be visited because they have to be unrelated to
5073 // the input. Note that this check is not trivial even though we disallow
5074 // general capturing of the underlying argument. The reason is that the
5075 // call might the argument "through return", which we allow and for which we
5076 // need to check call users.
5077 unsigned ArgNo = ICS.getArgumentNo(U);
5078 const auto &ArgNoCaptureAA =
5079 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
5080 return !ArgNoCaptureAA.isAssumedNoCapture();
5081}
5082
5083void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
5084 const Instruction *UserI) {
5085 assert(UserI->mayReadOrWriteMemory());
5086
5087 switch (UserI->getOpcode()) {
5088 default:
5089 // TODO: Handle all atomics and other side-effect operations we know of.
5090 break;
5091 case Instruction::Load:
5092 // Loads cause the NO_READS property to disappear.
5093 removeAssumedBits(NO_READS);
5094 return;
5095
5096 case Instruction::Store:
5097 // Stores cause the NO_WRITES property to disappear if the use is the
5098 // pointer operand. Note that we do assume that capturing was taken care of
5099 // somewhere else.
5100 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
5101 removeAssumedBits(NO_WRITES);
5102 return;
5103
5104 case Instruction::Call:
5105 case Instruction::CallBr:
5106 case Instruction::Invoke: {
5107 // For call sites we look at the argument memory behavior attribute (this
5108 // could be recursive!) in order to restrict our own state.
5109 ImmutableCallSite ICS(UserI);
5110
5111 // Give up on operand bundles.
5112 if (ICS.isBundleOperand(U)) {
5113 indicatePessimisticFixpoint();
5114 return;
5115 }
5116
5117 // Calling a function does read the function pointer, maybe write it if the
5118 // function is self-modifying.
5119 if (ICS.isCallee(U)) {
5120 removeAssumedBits(NO_READS);
5121 break;
5122 }
5123
5124 // Adjust the possible access behavior based on the information on the
5125 // argument.
5126 unsigned ArgNo = ICS.getArgumentNo(U);
5127 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
5128 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
5129 // "assumed" has at most the same bits as the MemBehaviorAA assumed
5130 // and at least "known".
5131 intersectAssumedBits(MemBehaviorAA.getAssumed());
5132 return;
5133 }
5134 };
5135
5136 // Generally, look at the "may-properties" and adjust the assumed state if we
5137 // did not trigger special handling before.
5138 if (UserI->mayReadFromMemory())
5139 removeAssumedBits(NO_READS);
5140 if (UserI->mayWriteToMemory())
5141 removeAssumedBits(NO_WRITES);
5142}
Hideto Ueno188f9a32020-01-15 15:25:52 +09005143/// ------------------ Value Constant Range Attribute -------------------------
Hideto Uenoe9963032020-01-01 15:25:19 +09005144
Hideto Ueno188f9a32020-01-15 15:25:52 +09005145struct AAValueConstantRangeImpl : AAValueConstantRange {
5146 using StateType = IntegerRangeState;
5147 AAValueConstantRangeImpl(const IRPosition &IRP) : AAValueConstantRange(IRP) {}
5148
5149 /// See AbstractAttribute::getAsStr().
5150 const std::string getAsStr() const override {
5151 std::string Str;
5152 llvm::raw_string_ostream OS(Str);
5153 OS << "range(" << getBitWidth() << ")<";
5154 getKnown().print(OS);
5155 OS << " / ";
5156 getAssumed().print(OS);
5157 OS << ">";
5158 return OS.str();
5159 }
5160
5161 /// Helper function to get a SCEV expr for the associated value at program
5162 /// point \p I.
5163 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
5164 if (!getAnchorScope())
5165 return nullptr;
5166
5167 ScalarEvolution *SE =
5168 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
5169 *getAnchorScope());
5170
5171 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
5172 *getAnchorScope());
5173
5174 if (!SE || !LI)
5175 return nullptr;
5176
5177 const SCEV *S = SE->getSCEV(&getAssociatedValue());
5178 if (!I)
5179 return S;
5180
5181 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
5182 }
5183
5184 /// Helper function to get a range from SCEV for the associated value at
5185 /// program point \p I.
5186 ConstantRange getConstantRangeFromSCEV(Attributor &A,
5187 const Instruction *I = nullptr) const {
5188 if (!getAnchorScope())
5189 return getWorstState(getBitWidth());
5190
5191 ScalarEvolution *SE =
5192 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
5193 *getAnchorScope());
5194
5195 const SCEV *S = getSCEV(A, I);
5196 if (!SE || !S)
5197 return getWorstState(getBitWidth());
5198
5199 return SE->getUnsignedRange(S);
5200 }
5201
5202 /// Helper function to get a range from LVI for the associated value at
5203 /// program point \p I.
5204 ConstantRange
5205 getConstantRangeFromLVI(Attributor &A,
5206 const Instruction *CtxI = nullptr) const {
5207 if (!getAnchorScope())
5208 return getWorstState(getBitWidth());
5209
5210 LazyValueInfo *LVI =
5211 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
5212 *getAnchorScope());
5213
5214 if (!LVI || !CtxI)
5215 return getWorstState(getBitWidth());
5216 return LVI->getConstantRange(&getAssociatedValue(),
5217 const_cast<BasicBlock *>(CtxI->getParent()),
5218 const_cast<Instruction *>(CtxI));
5219 }
5220
5221 /// See AAValueConstantRange::getKnownConstantRange(..).
5222 ConstantRange
5223 getKnownConstantRange(Attributor &A,
5224 const Instruction *CtxI = nullptr) const override {
5225 if (!CtxI || CtxI == getCtxI())
5226 return getKnown();
5227
5228 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
5229 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
5230 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
5231 }
5232
5233 /// See AAValueConstantRange::getAssumedConstantRange(..).
5234 ConstantRange
5235 getAssumedConstantRange(Attributor &A,
5236 const Instruction *CtxI = nullptr) const override {
5237 // TODO: Make SCEV use Attributor assumption.
5238 // We may be able to bound a variable range via assumptions in
5239 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
5240 // evolve to x^2 + x, then we can say that y is in [2, 12].
5241
5242 if (!CtxI || CtxI == getCtxI())
5243 return getAssumed();
5244
5245 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
5246 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
5247 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
5248 }
5249
5250 /// See AbstractAttribute::initialize(..).
5251 void initialize(Attributor &A) override {
5252 // Intersect a range given by SCEV.
5253 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
5254
5255 // Intersect a range given by LVI.
5256 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
5257 }
5258
5259 /// Helper function to create MDNode for range metadata.
5260 static MDNode *
5261 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
5262 const ConstantRange &AssumedConstantRange) {
5263 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
5264 Ty, AssumedConstantRange.getLower())),
5265 ConstantAsMetadata::get(ConstantInt::get(
5266 Ty, AssumedConstantRange.getUpper()))};
5267 return MDNode::get(Ctx, LowAndHigh);
5268 }
5269
5270 /// Return true if \p Assumed is included in \p KnownRanges.
5271 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) {
5272
5273 if (Assumed.isFullSet())
5274 return false;
5275
5276 if (!KnownRanges)
5277 return true;
5278
5279 // If multiple ranges are annotated in IR, we give up to annotate assumed
5280 // range for now.
5281
5282 // TODO: If there exists a known range which containts assumed range, we
5283 // can say assumed range is better.
5284 if (KnownRanges->getNumOperands() > 2)
5285 return false;
5286
5287 ConstantInt *Lower =
5288 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
5289 ConstantInt *Upper =
5290 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
5291
5292 ConstantRange Known(Lower->getValue(), Upper->getValue());
5293 return Known.contains(Assumed) && Known != Assumed;
5294 }
5295
5296 /// Helper function to set range metadata.
5297 static bool
5298 setRangeMetadataIfisBetterRange(Instruction *I,
5299 const ConstantRange &AssumedConstantRange) {
5300 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range);
5301 if (isBetterRange(AssumedConstantRange, OldRangeMD)) {
5302 if (!AssumedConstantRange.isEmptySet()) {
5303 I->setMetadata(LLVMContext::MD_range,
5304 getMDNodeForConstantRange(I->getType(), I->getContext(),
5305 AssumedConstantRange));
5306 return true;
5307 }
5308 }
5309 return false;
5310 }
5311
5312 /// See AbstractAttribute::manifest()
5313 ChangeStatus manifest(Attributor &A) override {
5314 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5315 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
5316 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
5317
5318 auto &V = getAssociatedValue();
5319 if (!AssumedConstantRange.isEmptySet() &&
5320 !AssumedConstantRange.isSingleElement()) {
5321 if (Instruction *I = dyn_cast<Instruction>(&V))
5322 if (isa<CallInst>(I) || isa<LoadInst>(I))
5323 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
5324 Changed = ChangeStatus::CHANGED;
5325 }
5326
5327 return Changed;
5328 }
5329};
5330
5331struct AAValueConstantRangeArgument final : public AAValueConstantRangeImpl {
5332
5333 AAValueConstantRangeArgument(const IRPosition &IRP)
5334 : AAValueConstantRangeImpl(IRP) {}
5335
5336 /// See AbstractAttribute::updateImpl(...).
5337 ChangeStatus updateImpl(Attributor &A) override {
5338 // TODO: Use AAArgumentFromCallSiteArguments
5339
5340 IntegerRangeState S(getBitWidth());
5341 clampCallSiteArgumentStates<AAValueConstantRange, IntegerRangeState>(
5342 A, *this, S);
5343
5344 // TODO: If we know we visited all incoming values, thus no are assumed
5345 // dead, we can take the known information from the state T.
5346 return clampStateAndIndicateChange<IntegerRangeState>(this->getState(), S);
5347 }
5348
5349 /// See AbstractAttribute::trackStatistics()
5350 void trackStatistics() const override {
5351 STATS_DECLTRACK_ARG_ATTR(value_range)
5352 }
5353};
5354
5355struct AAValueConstantRangeReturned : AAValueConstantRangeImpl {
5356 AAValueConstantRangeReturned(const IRPosition &IRP)
5357 : AAValueConstantRangeImpl(IRP) {}
5358
5359 /// See AbstractAttribute::updateImpl(...).
5360 ChangeStatus updateImpl(Attributor &A) override {
5361 // TODO: Use AAReturnedFromReturnedValues
5362
5363 // TODO: If we know we visited all returned values, thus no are assumed
5364 // dead, we can take the known information from the state T.
5365
5366 IntegerRangeState S(getBitWidth());
5367
5368 clampReturnedValueStates<AAValueConstantRange, IntegerRangeState>(A, *this,
5369 S);
5370 return clampStateAndIndicateChange<StateType>(this->getState(), S);
5371 }
5372
5373 /// See AbstractAttribute::trackStatistics()
5374 void trackStatistics() const override {
5375 STATS_DECLTRACK_FNRET_ATTR(value_range)
5376 }
5377};
5378
5379struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
5380 AAValueConstantRangeFloating(const IRPosition &IRP)
5381 : AAValueConstantRangeImpl(IRP) {}
5382
5383 /// See AbstractAttribute::initialize(...).
5384 void initialize(Attributor &A) override {
5385 AAValueConstantRange::initialize(A);
5386 Value &V = getAssociatedValue();
5387
5388 if (auto *C = dyn_cast<ConstantInt>(&V)) {
5389 unionAssumed(ConstantRange(C->getValue()));
5390 indicateOptimisticFixpoint();
5391 return;
5392 }
5393
5394 if (isa<UndefValue>(&V)) {
5395 indicateOptimisticFixpoint();
5396 return;
5397 }
5398
5399 if (auto *I = dyn_cast<Instruction>(&V))
5400 if (isa<BinaryOperator>(I) || isa<CmpInst>(I)) {
5401 Value *LHS = I->getOperand(0);
5402 Value *RHS = I->getOperand(1);
5403
5404 if (LHS->getType()->isIntegerTy() && RHS->getType()->isIntegerTy())
5405 return;
5406 }
5407
5408 // If it is a load instruction with range metadata, use it.
5409 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
5410 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
5411 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
5412 return;
5413 }
5414
5415 // Otherwise we give up.
5416 indicatePessimisticFixpoint();
5417
5418 LLVM_DEBUG(dbgs() << "[Attributor][AAValueConstantRange] We give up: "
5419 << getAssociatedValue());
5420 }
5421
5422 bool calculateBinaryOperator(Attributor &A, BinaryOperator *BinOp,
5423 IntegerRangeState &T, Instruction *CtxI) {
5424 Value *LHS = BinOp->getOperand(0);
5425 Value *RHS = BinOp->getOperand(1);
5426
5427 auto &LHSAA =
5428 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
5429 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
5430
5431 auto &RHSAA =
5432 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
5433 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
5434
5435 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
5436
5437 T.unionAssumed(AssumedRange);
5438
5439 // TODO: Track a known state too.
5440
5441 return T.isValidState();
5442 }
5443
5444 bool calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
5445 Instruction *CtxI) {
5446 Value *LHS = CmpI->getOperand(0);
5447 Value *RHS = CmpI->getOperand(1);
5448
5449 auto &LHSAA =
5450 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
5451 auto &RHSAA =
5452 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
5453
5454 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
5455 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
5456
5457 // If one of them is empty set, we can't decide.
5458 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
5459 return true;
5460
5461 bool MustTrue = false, MustFalse = false;
5462
5463 auto AllowedRegion =
5464 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange);
5465
5466 auto SatisfyingRegion = ConstantRange::makeSatisfyingICmpRegion(
5467 CmpI->getPredicate(), RHSAARange);
5468
5469 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
5470 MustFalse = true;
5471
5472 if (SatisfyingRegion.contains(LHSAARange))
5473 MustTrue = true;
5474
5475 assert((!MustTrue || !MustFalse) &&
5476 "Either MustTrue or MustFalse should be false!");
5477
5478 if (MustTrue)
5479 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
5480 else if (MustFalse)
5481 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
5482 else
5483 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
5484
5485 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " " << LHSAA
5486 << " " << RHSAA << "\n");
5487
5488 // TODO: Track a known state too.
5489 return T.isValidState();
5490 }
5491
5492 /// See AbstractAttribute::updateImpl(...).
5493 ChangeStatus updateImpl(Attributor &A) override {
5494 Instruction *CtxI = getCtxI();
5495 auto VisitValueCB = [&](Value &V, IntegerRangeState &T,
5496 bool Stripped) -> bool {
5497 Instruction *I = dyn_cast<Instruction>(&V);
5498 if (!I) {
5499
5500 // If the value is not instruction, we query AA to Attributor.
5501 const auto &AA =
5502 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(V));
5503
5504 // Clamp operator is not used to utilize a program point CtxI.
5505 T.unionAssumed(AA.getAssumedConstantRange(A, CtxI));
5506
5507 return T.isValidState();
5508 }
5509
5510 if (auto *BinOp = dyn_cast<BinaryOperator>(I))
5511 return calculateBinaryOperator(A, BinOp, T, CtxI);
5512 else if (auto *CmpI = dyn_cast<CmpInst>(I))
5513 return calculateCmpInst(A, CmpI, T, CtxI);
5514 else {
5515 // Give up with other instructions.
5516 // TODO: Add other instructions
5517
5518 T.indicatePessimisticFixpoint();
5519 return false;
5520 }
5521 };
5522
5523 IntegerRangeState T(getBitWidth());
5524
5525 if (!genericValueTraversal<AAValueConstantRange, IntegerRangeState>(
5526 A, getIRPosition(), *this, T, VisitValueCB))
5527 return indicatePessimisticFixpoint();
5528
5529 return clampStateAndIndicateChange(getState(), T);
5530 }
5531
5532 /// See AbstractAttribute::trackStatistics()
5533 void trackStatistics() const override {
5534 STATS_DECLTRACK_FLOATING_ATTR(value_range)
5535 }
5536};
5537
5538struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
5539 AAValueConstantRangeFunction(const IRPosition &IRP)
5540 : AAValueConstantRangeImpl(IRP) {}
5541
5542 /// See AbstractAttribute::initialize(...).
5543 ChangeStatus updateImpl(Attributor &A) override {
5544 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
5545 "not be called");
5546 }
5547
5548 /// See AbstractAttribute::trackStatistics()
5549 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
5550};
5551
5552struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
5553 AAValueConstantRangeCallSite(const IRPosition &IRP)
5554 : AAValueConstantRangeFunction(IRP) {}
5555
5556 /// See AbstractAttribute::trackStatistics()
5557 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
5558};
5559
5560struct AAValueConstantRangeCallSiteReturned : AAValueConstantRangeReturned {
5561 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP)
5562 : AAValueConstantRangeReturned(IRP) {}
5563
5564 /// See AbstractAttribute::initialize(...).
5565 void initialize(Attributor &A) override {
5566 // If it is a load instruction with range metadata, use the metadata.
5567 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue()))
5568 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range))
5569 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
5570
5571 AAValueConstantRangeReturned::initialize(A);
5572 }
5573
5574 /// See AbstractAttribute::trackStatistics()
5575 void trackStatistics() const override {
5576 STATS_DECLTRACK_CSRET_ATTR(value_range)
5577 }
5578};
5579struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
5580 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP)
5581 : AAValueConstantRangeFloating(IRP) {}
5582
5583 /// See AbstractAttribute::trackStatistics()
5584 void trackStatistics() const override {
5585 STATS_DECLTRACK_CSARG_ATTR(value_range)
5586 }
5587};
Johannes Doerfertaade7822019-06-05 03:02:24 +00005588/// ----------------------------------------------------------------------------
5589/// Attributor
5590/// ----------------------------------------------------------------------------
5591
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005592bool Attributor::isAssumedDead(const AbstractAttribute &AA,
5593 const AAIsDead *LivenessAA) {
5594 const Instruction *CtxI = AA.getIRPosition().getCtxI();
5595 if (!CtxI)
5596 return false;
5597
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005598 // TODO: Find a good way to utilize fine and coarse grained liveness
5599 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005600 if (!LivenessAA)
5601 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00005602 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
5603 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00005604
5605 // Don't check liveness for AAIsDead.
5606 if (&AA == LivenessAA)
5607 return false;
5608
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005609 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005610 return false;
5611
Johannes Doerfert19b00432019-08-26 17:48:05 +00005612 // We actually used liveness information so we have to record a dependence.
Johannes Doerfert680f6382019-11-02 02:48:05 -05005613 recordDependence(*LivenessAA, AA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005614
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005615 return true;
5616}
5617
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005618bool Attributor::checkForAllUses(
5619 const function_ref<bool(const Use &, bool &)> &Pred,
5620 const AbstractAttribute &QueryingAA, const Value &V) {
5621 const IRPosition &IRP = QueryingAA.getIRPosition();
5622 SmallVector<const Use *, 16> Worklist;
5623 SmallPtrSet<const Use *, 16> Visited;
5624
5625 for (const Use &U : V.uses())
5626 Worklist.push_back(&U);
5627
5628 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
5629 << " initial uses to check\n");
5630
5631 if (Worklist.empty())
5632 return true;
5633
5634 bool AnyDead = false;
5635 const Function *ScopeFn = IRP.getAnchorScope();
5636 const auto *LivenessAA =
5637 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
5638 /* TrackDependence */ false)
5639 : nullptr;
5640
5641 while (!Worklist.empty()) {
5642 const Use *U = Worklist.pop_back_val();
5643 if (!Visited.insert(U).second)
5644 continue;
5645 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << "\n");
5646 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser()))
5647 if (LivenessAA && LivenessAA->isAssumedDead(UserI)) {
5648 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06005649 << *LivenessAA << "\n");
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005650 AnyDead = true;
5651 continue;
5652 }
5653
5654 bool Follow = false;
5655 if (!Pred(*U, Follow))
5656 return false;
5657 if (!Follow)
5658 continue;
5659 for (const Use &UU : U->getUser()->uses())
5660 Worklist.push_back(&UU);
5661 }
5662
5663 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005664 recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005665
5666 return true;
5667}
5668
Johannes Doerfert661db042019-10-07 23:14:58 +00005669bool Attributor::checkForAllCallSites(
5670 const function_ref<bool(AbstractCallSite)> &Pred,
5671 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005672 // We can try to determine information from
5673 // the call sites. However, this is only possible all call sites are known,
5674 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005675 const IRPosition &IRP = QueryingAA.getIRPosition();
5676 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00005677 if (!AssociatedFunction) {
5678 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
5679 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005680 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00005681 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005682
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005683 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
5684 &QueryingAA);
5685}
5686
5687bool Attributor::checkForAllCallSites(
5688 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
5689 bool RequireAllCallSites, const AbstractAttribute *QueryingAA) {
5690 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005691 LLVM_DEBUG(
5692 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005693 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00005694 << " has no internal linkage, hence not all call sites are known\n");
5695 return false;
5696 }
5697
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005698 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00005699 AbstractCallSite ACS(&U);
5700 if (!ACS) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005701 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00005702 << " has non call site use " << *U.get() << " in "
5703 << *U.getUser() << "\n");
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05005704 // BlockAddress users are allowed.
5705 if (isa<BlockAddress>(U.getUser()))
5706 continue;
Johannes Doerfertd98f9752019-08-21 21:48:56 +00005707 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00005708 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00005709
Johannes Doerfert661db042019-10-07 23:14:58 +00005710 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005711 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005712
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005713 const auto *LivenessAA =
5714 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005715 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005716
5717 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005718 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00005719 // We actually used liveness information so we have to record a
5720 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005721 if (QueryingAA)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005722 recordDependence(*LivenessAA, *QueryingAA, DepClassTy::OPTIONAL);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005723 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00005724 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00005725
Johannes Doerfert661db042019-10-07 23:14:58 +00005726 const Use *EffectiveUse =
5727 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
5728 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005729 if (!RequireAllCallSites)
5730 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00005731 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005732 << " is an invalid use of " << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00005733 return false;
5734 }
5735
Johannes Doerfert661db042019-10-07 23:14:58 +00005736 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00005737 continue;
5738
Johannes Doerfert5304b722019-08-14 22:04:28 +00005739 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00005740 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00005741 return false;
5742 }
5743
5744 return true;
5745}
5746
Johannes Doerfert14a04932019-08-07 22:27:24 +00005747bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00005748 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00005749 &Pred,
5750 const AbstractAttribute &QueryingAA) {
5751
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005752 const IRPosition &IRP = QueryingAA.getIRPosition();
5753 // Since we need to provide return instructions we have to have an exact
5754 // definition.
5755 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005756 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00005757 return false;
5758
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005759 // If this is a call site query we use the call site specific return values
5760 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005761 // TODO: use the function scope once we have call site AAReturnedValues.
5762 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005763 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005764 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005765 return false;
5766
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005767 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00005768}
5769
5770bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005771 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00005772 const AbstractAttribute &QueryingAA) {
5773
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005774 const IRPosition &IRP = QueryingAA.getIRPosition();
5775 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005776 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00005777 return false;
5778
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005779 // TODO: use the function scope once we have call site AAReturnedValues.
5780 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005781 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005782 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005783 return false;
5784
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005785 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00005786 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00005787 return Pred(RV);
5788 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00005789}
5790
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005791static bool
5792checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
5793 const function_ref<bool(Instruction &)> &Pred,
5794 const AAIsDead *LivenessAA, bool &AnyDead,
5795 const ArrayRef<unsigned> &Opcodes) {
5796 for (unsigned Opcode : Opcodes) {
5797 for (Instruction *I : OpcodeInstMap[Opcode]) {
5798 // Skip dead instructions.
5799 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
5800 AnyDead = true;
5801 continue;
5802 }
5803
5804 if (!Pred(*I))
5805 return false;
5806 }
5807 }
5808 return true;
5809}
5810
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005811bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005812 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00005813 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005814
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005815 const IRPosition &IRP = QueryingAA.getIRPosition();
5816 // Since we need to provide instructions we have to have an exact definition.
5817 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005818 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005819 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005820
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005821 // TODO: use the function scope once we have call site AAReturnedValues.
5822 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005823 const auto &LivenessAA =
5824 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
5825 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005826
5827 auto &OpcodeInstMap =
5828 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005829 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
5830 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005831 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005832
Johannes Doerfert19b00432019-08-26 17:48:05 +00005833 // If we actually used liveness information so we have to record a dependence.
5834 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005835 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005836
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005837 return true;
5838}
5839
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005840bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005841 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00005842 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005843
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005844 const Function *AssociatedFunction =
5845 QueryingAA.getIRPosition().getAssociatedFunction();
5846 if (!AssociatedFunction)
5847 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005848
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005849 // TODO: use the function scope once we have call site AAReturnedValues.
5850 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
5851 const auto &LivenessAA =
5852 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005853 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005854
5855 for (Instruction *I :
5856 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005857 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00005858 if (LivenessAA.isAssumedDead(I)) {
5859 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005860 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00005861 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005862
5863 if (!Pred(*I))
5864 return false;
5865 }
5866
Johannes Doerfert19b00432019-08-26 17:48:05 +00005867 // If we actually used liveness information so we have to record a dependence.
5868 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005869 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005870
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005871 return true;
5872}
5873
Johannes Doerfert2f622062019-09-04 16:35:20 +00005874ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005875 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
5876 << AllAbstractAttributes.size()
5877 << " abstract attributes.\n");
5878
Stefan Stipanovic53605892019-06-27 11:27:54 +00005879 // Now that all abstract attributes are collected and initialized we start
5880 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00005881
5882 unsigned IterationCounter = 1;
5883
5884 SmallVector<AbstractAttribute *, 64> ChangedAAs;
Johannes Doerfert680f6382019-11-02 02:48:05 -05005885 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005886 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
5887
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005888 bool RecomputeDependences = false;
5889
Johannes Doerfertaade7822019-06-05 03:02:24 +00005890 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005891 // Remember the size to determine new attributes.
5892 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005893 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
5894 << ", Worklist size: " << Worklist.size() << "\n");
5895
Johannes Doerfert680f6382019-11-02 02:48:05 -05005896 // For invalid AAs we can fix dependent AAs that have a required dependence,
5897 // thereby folding long dependence chains in a single step without the need
5898 // to run updates.
5899 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
5900 AbstractAttribute *InvalidAA = InvalidAAs[u];
5901 auto &QuerriedAAs = QueryMap[InvalidAA];
5902 LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
5903 << QuerriedAAs.RequiredAAs.size() << "/"
5904 << QuerriedAAs.OptionalAAs.size()
5905 << " required/optional dependences\n");
5906 for (AbstractAttribute *DepOnInvalidAA : QuerriedAAs.RequiredAAs) {
5907 AbstractState &DOIAAState = DepOnInvalidAA->getState();
5908 DOIAAState.indicatePessimisticFixpoint();
5909 ++NumAttributesFixedDueToRequiredDependences;
5910 assert(DOIAAState.isAtFixpoint() && "Expected fixpoint state!");
5911 if (!DOIAAState.isValidState())
5912 InvalidAAs.insert(DepOnInvalidAA);
5913 }
5914 if (!RecomputeDependences)
5915 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
5916 QuerriedAAs.OptionalAAs.end());
5917 }
5918
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005919 // If dependences (=QueryMap) are recomputed we have to look at all abstract
5920 // attributes again, regardless of what changed in the last iteration.
5921 if (RecomputeDependences) {
5922 LLVM_DEBUG(
5923 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
5924 QueryMap.clear();
5925 ChangedAAs.clear();
5926 Worklist.insert(AllAbstractAttributes.begin(),
5927 AllAbstractAttributes.end());
5928 }
5929
Johannes Doerfertaade7822019-06-05 03:02:24 +00005930 // Add all abstract attributes that are potentially dependent on one that
5931 // changed to the work list.
5932 for (AbstractAttribute *ChangedAA : ChangedAAs) {
5933 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05005934 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
5935 QuerriedAAs.OptionalAAs.end());
5936 Worklist.insert(QuerriedAAs.RequiredAAs.begin(),
5937 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00005938 }
5939
Johannes Doerfertb504eb82019-08-26 18:55:47 +00005940 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
5941 << ", Worklist+Dependent size: " << Worklist.size()
5942 << "\n");
5943
Johannes Doerfert680f6382019-11-02 02:48:05 -05005944 // Reset the changed and invalid set.
Johannes Doerfertaade7822019-06-05 03:02:24 +00005945 ChangedAAs.clear();
Johannes Doerfert680f6382019-11-02 02:48:05 -05005946 InvalidAAs.clear();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005947
5948 // Update all abstract attribute in the work list and record the ones that
5949 // changed.
5950 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005951 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
5952 QueriedNonFixAA = false;
5953 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005954 ChangedAAs.push_back(AA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05005955 if (!AA->getState().isValidState())
5956 InvalidAAs.insert(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005957 } else if (!QueriedNonFixAA) {
5958 // If the attribute did not query any non-fix information, the state
5959 // will not change and we can indicate that right away.
5960 AA->getState().indicateOptimisticFixpoint();
5961 }
5962 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00005963
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005964 // Check if we recompute the dependences in the next iteration.
5965 RecomputeDependences = (DepRecomputeInterval > 0 &&
5966 IterationCounter % DepRecomputeInterval == 0);
5967
Johannes Doerfert9543f142019-08-23 15:24:57 +00005968 // Add attributes to the changed set if they have been created in the last
5969 // iteration.
5970 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
5971 AllAbstractAttributes.end());
5972
Johannes Doerfertaade7822019-06-05 03:02:24 +00005973 // Reset the work list and repopulate with the changed abstract attributes.
5974 // Note that dependent ones are added above.
5975 Worklist.clear();
5976 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
5977
Johannes Doerfertbf112132019-08-29 01:29:44 +00005978 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
5979 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005980
Johannes Doerfertaade7822019-06-05 03:02:24 +00005981 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
5982 << IterationCounter << "/" << MaxFixpointIterations
5983 << " iterations\n");
5984
Johannes Doerfertbf112132019-08-29 01:29:44 +00005985 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00005986
Johannes Doerfertaade7822019-06-05 03:02:24 +00005987 // Reset abstract arguments not settled in a sound fixpoint by now. This
5988 // happens when we stopped the fixpoint iteration early. Note that only the
5989 // ones marked as "changed" *and* the ones transitively depending on them
5990 // need to be reverted to a pessimistic state. Others might not be in a
5991 // fixpoint state but we can use the optimistic results for them anyway.
5992 SmallPtrSet<AbstractAttribute *, 32> Visited;
5993 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
5994 AbstractAttribute *ChangedAA = ChangedAAs[u];
5995 if (!Visited.insert(ChangedAA).second)
5996 continue;
5997
5998 AbstractState &State = ChangedAA->getState();
5999 if (!State.isAtFixpoint()) {
6000 State.indicatePessimisticFixpoint();
6001
6002 NumAttributesTimedOut++;
6003 }
6004
6005 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05006006 ChangedAAs.append(QuerriedAAs.OptionalAAs.begin(),
6007 QuerriedAAs.OptionalAAs.end());
6008 ChangedAAs.append(QuerriedAAs.RequiredAAs.begin(),
6009 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00006010 }
6011
6012 LLVM_DEBUG({
6013 if (!Visited.empty())
6014 dbgs() << "\n[Attributor] Finalized " << Visited.size()
6015 << " abstract attributes.\n";
6016 });
6017
6018 unsigned NumManifested = 0;
6019 unsigned NumAtFixpoint = 0;
6020 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
6021 for (AbstractAttribute *AA : AllAbstractAttributes) {
6022 AbstractState &State = AA->getState();
6023
6024 // If there is not already a fixpoint reached, we can now take the
6025 // optimistic state. This is correct because we enforced a pessimistic one
6026 // on abstract attributes that were transitively dependent on a changed one
6027 // already above.
6028 if (!State.isAtFixpoint())
6029 State.indicateOptimisticFixpoint();
6030
6031 // If the state is invalid, we do not try to manifest it.
6032 if (!State.isValidState())
6033 continue;
6034
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006035 // Skip dead code.
6036 if (isAssumedDead(*AA, nullptr))
6037 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006038 // Manifest the state and record if we changed the IR.
6039 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00006040 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
6041 AA->trackStatistics();
6042
Johannes Doerfertaade7822019-06-05 03:02:24 +00006043 ManifestChange = ManifestChange | LocalChange;
6044
6045 NumAtFixpoint++;
6046 NumManifested += (LocalChange == ChangeStatus::CHANGED);
6047 }
6048
6049 (void)NumManifested;
6050 (void)NumAtFixpoint;
6051 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
6052 << " arguments while " << NumAtFixpoint
6053 << " were in a valid fixpoint state\n");
6054
Johannes Doerfertaade7822019-06-05 03:02:24 +00006055 NumAttributesManifested += NumManifested;
6056 NumAttributesValidFixpoint += NumAtFixpoint;
6057
Fangrui Songf1826172019-08-20 07:21:43 +00006058 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006059 assert(
6060 NumFinalAAs == AllAbstractAttributes.size() &&
6061 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00006062
6063 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00006064 {
6065 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
6066 << ToBeDeletedFunctions.size() << " functions and "
6067 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006068 << ToBeDeletedInsts.size() << " instructions and "
6069 << ToBeChangedUses.size() << " uses\n");
6070
Alina Sbirlea9e66c4e2020-01-23 14:21:08 -08006071 SmallVector<WeakTrackingVH, 32> DeadInsts;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006072 SmallVector<Instruction *, 32> TerminatorsToFold;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006073
6074 for (auto &It : ToBeChangedUses) {
6075 Use *U = It.first;
6076 Value *NewV = It.second;
6077 Value *OldV = U->get();
6078 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
6079 << " instead of " << *OldV << "\n");
6080 U->set(NewV);
6081 if (Instruction *I = dyn_cast<Instruction>(OldV))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006082 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
6083 isInstructionTriviallyDead(I)) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006084 DeadInsts.push_back(I);
6085 }
6086 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
6087 Instruction *UserI = cast<Instruction>(U->getUser());
6088 if (isa<UndefValue>(NewV)) {
Hideto Uenocb5eb132019-12-27 02:39:37 +09006089 ToBeChangedToUnreachableInsts.insert(UserI);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006090 } else {
6091 TerminatorsToFold.push_back(UserI);
6092 }
6093 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00006094 }
Johannes Doerferta4088c72020-01-07 16:01:57 -06006095 for (auto &V : InvokeWithDeadSuccessor)
6096 if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
6097 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
6098 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
6099 bool Invoke2CallAllowed =
6100 !AAIsDeadFunction::mayCatchAsynchronousExceptions(
6101 *II->getFunction());
6102 assert((UnwindBBIsDead || NormalBBIsDead) &&
6103 "Invoke does not have dead successors!");
6104 BasicBlock *BB = II->getParent();
6105 BasicBlock *NormalDestBB = II->getNormalDest();
6106 if (UnwindBBIsDead) {
6107 Instruction *NormalNextIP = &NormalDestBB->front();
6108 if (Invoke2CallAllowed) {
6109 changeToCall(II);
6110 NormalNextIP = BB->getTerminator();
6111 }
6112 if (NormalBBIsDead)
6113 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
6114 } else {
6115 assert(NormalBBIsDead && "Broken invariant!");
6116 if (!NormalDestBB->getUniquePredecessor())
6117 NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
6118 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
6119 }
6120 }
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06006121 for (auto &V : ToBeChangedToUnreachableInsts)
6122 if (Instruction *I = dyn_cast_or_null<Instruction>(V))
6123 changeToUnreachable(I, /* UseLLVMTrap */ false);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006124 for (Instruction *I : TerminatorsToFold)
6125 ConstantFoldTerminator(I->getParent());
6126
6127 for (Instruction *I : ToBeDeletedInsts) {
6128 I->replaceAllUsesWith(UndefValue::get(I->getType()));
6129 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
6130 DeadInsts.push_back(I);
6131 else
6132 I->eraseFromParent();
6133 }
6134
6135 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00006136
Johannes Doerfert2f622062019-09-04 16:35:20 +00006137 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
6138 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
6139 ToBeDeletedBBs.reserve(NumDeadBlocks);
6140 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
Johannes Doerfert5e442a52019-10-30 17:34:59 -05006141 // Actually we do not delete the blocks but squash them into a single
6142 // unreachable but untangling branches that jump here is something we need
6143 // to do in a more generic way.
6144 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
6145 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
6146 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00006147 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00006148
Johannes Doerfert2f622062019-09-04 16:35:20 +00006149 // Identify dead internal functions and delete them. This happens outside
6150 // the other fixpoint analysis as we might treat potentially dead functions
6151 // as live to lower the number of iterations. If they happen to be dead, the
6152 // below fixpoint loop will identify and eliminate them.
6153 SmallVector<Function *, 8> InternalFns;
6154 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00006155 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00006156 InternalFns.push_back(&F);
6157
6158 bool FoundDeadFn = true;
6159 while (FoundDeadFn) {
6160 FoundDeadFn = false;
6161 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
6162 Function *F = InternalFns[u];
6163 if (!F)
6164 continue;
6165
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06006166 if (!checkForAllCallSites(
6167 [this](AbstractCallSite ACS) {
6168 return ToBeDeletedFunctions.count(
6169 ACS.getInstruction()->getFunction());
6170 },
6171 *F, true, nullptr))
Johannes Doerfert2f622062019-09-04 16:35:20 +00006172 continue;
6173
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006174 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00006175 InternalFns[u] = nullptr;
6176 FoundDeadFn = true;
6177 }
6178 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00006179 }
6180
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06006181 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
6182 BUILD_STAT_NAME(AAIsDead, Function) += ToBeDeletedFunctions.size();
6183
Johannes Doerfert75133632019-10-10 01:39:16 -05006184 // Rewrite the functions as requested during manifest.
6185 ManifestChange = ManifestChange | rewriteFunctionSignatures();
6186
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06006187 for (Function *Fn : ToBeDeletedFunctions) {
6188 Fn->deleteBody();
6189 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
6190 Fn->eraseFromParent();
6191 }
6192
Johannes Doerfertbf112132019-08-29 01:29:44 +00006193 if (VerifyMaxFixpointIterations &&
6194 IterationCounter != MaxFixpointIterations) {
6195 errs() << "\n[Attributor] Fixpoint iteration done after: "
6196 << IterationCounter << "/" << MaxFixpointIterations
6197 << " iterations\n";
6198 llvm_unreachable("The fixpoint was not reached with exactly the number of "
6199 "specified iterations!");
6200 }
6201
Johannes Doerfertaade7822019-06-05 03:02:24 +00006202 return ManifestChange;
6203}
6204
Johannes Doerfert75133632019-10-10 01:39:16 -05006205bool Attributor::registerFunctionSignatureRewrite(
6206 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
6207 ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,
6208 ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {
6209
6210 auto CallSiteCanBeChanged = [](AbstractCallSite ACS) {
6211 // Forbid must-tail calls for now.
6212 return !ACS.isCallbackCall() && !ACS.getCallSite().isMustTailCall();
6213 };
6214
6215 Function *Fn = Arg.getParent();
6216 // Avoid var-arg functions for now.
6217 if (Fn->isVarArg()) {
6218 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
6219 return false;
6220 }
6221
6222 // Avoid functions with complicated argument passing semantics.
6223 AttributeList FnAttributeList = Fn->getAttributes();
6224 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
6225 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
6226 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca)) {
6227 LLVM_DEBUG(
6228 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
6229 return false;
6230 }
6231
6232 // Avoid callbacks for now.
6233 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr)) {
6234 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
6235 return false;
6236 }
6237
6238 auto InstPred = [](Instruction &I) {
6239 if (auto *CI = dyn_cast<CallInst>(&I))
6240 return !CI->isMustTailCall();
6241 return true;
6242 };
6243
6244 // Forbid must-tail calls for now.
6245 // TODO:
6246 bool AnyDead;
6247 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
6248 if (!checkForAllInstructionsImpl(OpcodeInstMap, InstPred, nullptr, AnyDead,
6249 {Instruction::Call})) {
6250 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
6251 return false;
6252 }
6253
6254 SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = ArgumentReplacementMap[Fn];
6255 if (ARIs.size() == 0)
6256 ARIs.resize(Fn->arg_size());
6257
6258 // If we have a replacement already with less than or equal new arguments,
6259 // ignore this request.
6260 ArgumentReplacementInfo *&ARI = ARIs[Arg.getArgNo()];
6261 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
6262 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
6263 return false;
6264 }
6265
6266 // If we have a replacement already but we like the new one better, delete
6267 // the old.
6268 if (ARI)
6269 delete ARI;
6270
6271 // Remember the replacement.
6272 ARI = new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
6273 std::move(CalleeRepairCB),
6274 std::move(ACSRepairCB));
6275
6276 return true;
6277}
6278
6279ChangeStatus Attributor::rewriteFunctionSignatures() {
6280 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6281
6282 for (auto &It : ArgumentReplacementMap) {
6283 Function *OldFn = It.getFirst();
6284
6285 // Deleted functions do not require rewrites.
6286 if (ToBeDeletedFunctions.count(OldFn))
6287 continue;
6288
6289 const SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = It.getSecond();
6290 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
6291
6292 SmallVector<Type *, 16> NewArgumentTypes;
6293 SmallVector<AttributeSet, 16> NewArgumentAttributes;
6294
6295 // Collect replacement argument types and copy over existing attributes.
6296 AttributeList OldFnAttributeList = OldFn->getAttributes();
6297 for (Argument &Arg : OldFn->args()) {
6298 if (ArgumentReplacementInfo *ARI = ARIs[Arg.getArgNo()]) {
6299 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
6300 ARI->ReplacementTypes.end());
6301 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
6302 AttributeSet());
6303 } else {
6304 NewArgumentTypes.push_back(Arg.getType());
6305 NewArgumentAttributes.push_back(
6306 OldFnAttributeList.getParamAttributes(Arg.getArgNo()));
6307 }
6308 }
6309
6310 FunctionType *OldFnTy = OldFn->getFunctionType();
6311 Type *RetTy = OldFnTy->getReturnType();
6312
6313 // Construct the new function type using the new arguments types.
6314 FunctionType *NewFnTy =
6315 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
6316
6317 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
6318 << "' from " << *OldFn->getFunctionType() << " to "
6319 << *NewFnTy << "\n");
6320
6321 // Create the new function body and insert it into the module.
6322 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
6323 OldFn->getAddressSpace(), "");
6324 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
6325 NewFn->takeName(OldFn);
6326 NewFn->copyAttributesFrom(OldFn);
6327
6328 // Patch the pointer to LLVM function in debug info descriptor.
6329 NewFn->setSubprogram(OldFn->getSubprogram());
6330 OldFn->setSubprogram(nullptr);
6331
6332 // Recompute the parameter attributes list based on the new arguments for
6333 // the function.
6334 LLVMContext &Ctx = OldFn->getContext();
6335 NewFn->setAttributes(AttributeList::get(
6336 Ctx, OldFnAttributeList.getFnAttributes(),
6337 OldFnAttributeList.getRetAttributes(), NewArgumentAttributes));
6338
6339 // Since we have now created the new function, splice the body of the old
6340 // function right into the new function, leaving the old rotting hulk of the
6341 // function empty.
6342 NewFn->getBasicBlockList().splice(NewFn->begin(),
6343 OldFn->getBasicBlockList());
6344
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06006345 // Set of all "call-like" instructions that invoke the old function mapped
6346 // to their new replacements.
6347 SmallVector<std::pair<CallBase *, CallBase *>, 8> CallSitePairs;
Johannes Doerfert75133632019-10-10 01:39:16 -05006348
6349 // Callback to create a new "call-like" instruction for a given one.
6350 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
6351 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
6352 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
6353
6354 // Collect the new argument operands for the replacement call site.
6355 SmallVector<Value *, 16> NewArgOperands;
6356 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
6357 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
6358 unsigned NewFirstArgNum = NewArgOperands.size();
Ilya Biryukov4f82af82019-12-31 10:21:52 +01006359 (void)NewFirstArgNum; // only used inside assert.
Johannes Doerfert75133632019-10-10 01:39:16 -05006360 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
6361 if (ARI->ACSRepairCB)
6362 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
6363 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
6364 NewArgOperands.size() &&
6365 "ACS repair callback did not provide as many operand as new "
6366 "types were registered!");
6367 // TODO: Exose the attribute set to the ACS repair callback
6368 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
6369 AttributeSet());
6370 } else {
6371 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
6372 NewArgOperandAttributes.push_back(
6373 OldCallAttributeList.getParamAttributes(OldArgNum));
6374 }
6375 }
6376
6377 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
6378 "Mismatch # argument operands vs. # argument operand attributes!");
6379 assert(NewArgOperands.size() == NewFn->arg_size() &&
6380 "Mismatch # argument operands vs. # function arguments!");
6381
6382 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
6383 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
6384
6385 // Create a new call or invoke instruction to replace the old one.
6386 CallBase *NewCB;
6387 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
6388 NewCB =
6389 InvokeInst::Create(NewFn, II->getNormalDest(), II->getUnwindDest(),
6390 NewArgOperands, OperandBundleDefs, "", OldCB);
6391 } else {
6392 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
6393 "", OldCB);
6394 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
6395 NewCB = NewCI;
6396 }
6397
6398 // Copy over various properties and the new attributes.
Johannes Doerfert75133632019-10-10 01:39:16 -05006399 uint64_t W;
6400 if (OldCB->extractProfTotalWeight(W))
6401 NewCB->setProfWeight(W);
6402 NewCB->setCallingConv(OldCB->getCallingConv());
6403 NewCB->setDebugLoc(OldCB->getDebugLoc());
6404 NewCB->takeName(OldCB);
6405 NewCB->setAttributes(AttributeList::get(
6406 Ctx, OldCallAttributeList.getFnAttributes(),
6407 OldCallAttributeList.getRetAttributes(), NewArgOperandAttributes));
6408
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06006409 CallSitePairs.push_back({OldCB, NewCB});
Johannes Doerfert75133632019-10-10 01:39:16 -05006410 return true;
6411 };
6412
6413 // Use the CallSiteReplacementCreator to create replacement call sites.
6414 bool Success =
6415 checkForAllCallSites(CallSiteReplacementCreator, *OldFn, true, nullptr);
Ilya Biryukov4f82af82019-12-31 10:21:52 +01006416 (void)Success;
Johannes Doerfert75133632019-10-10 01:39:16 -05006417 assert(Success && "Assumed call site replacement to succeed!");
6418
6419 // Rewire the arguments.
6420 auto OldFnArgIt = OldFn->arg_begin();
6421 auto NewFnArgIt = NewFn->arg_begin();
6422 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
6423 ++OldArgNum, ++OldFnArgIt) {
6424 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
6425 if (ARI->CalleeRepairCB)
6426 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
6427 NewFnArgIt += ARI->ReplacementTypes.size();
6428 } else {
6429 NewFnArgIt->takeName(&*OldFnArgIt);
6430 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
6431 ++NewFnArgIt;
6432 }
6433 }
6434
6435 // Eliminate the instructions *after* we visited all of them.
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06006436 for (auto &CallSitePair : CallSitePairs) {
6437 CallBase &OldCB = *CallSitePair.first;
6438 CallBase &NewCB = *CallSitePair.second;
6439 OldCB.replaceAllUsesWith(&NewCB);
6440 OldCB.eraseFromParent();
6441 }
Johannes Doerfert75133632019-10-10 01:39:16 -05006442
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06006443 ToBeDeletedFunctions.insert(OldFn);
6444
Johannes Doerfert75133632019-10-10 01:39:16 -05006445 Changed = ChangeStatus::CHANGED;
6446 }
6447
6448 return Changed;
6449}
6450
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006451void Attributor::initializeInformationCache(Function &F) {
6452
6453 // Walk all instructions to find interesting instructions that might be
6454 // queried by abstract attributes during their initialization or update.
6455 // This has to happen before we create attributes.
6456 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
6457 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
6458
6459 for (Instruction &I : instructions(&F)) {
6460 bool IsInterestingOpcode = false;
6461
6462 // To allow easy access to all instructions in a function with a given
6463 // opcode we store them in the InfoCache. As not all opcodes are interesting
6464 // to concrete attributes we only cache the ones that are as identified in
6465 // the following switch.
6466 // Note: There are no concrete attributes now so this is initially empty.
6467 switch (I.getOpcode()) {
6468 default:
6469 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
6470 "New call site/base instruction type needs to be known int the "
6471 "Attributor.");
6472 break;
6473 case Instruction::Load:
6474 // The alignment of a pointer is interesting for loads.
6475 case Instruction::Store:
6476 // The alignment of a pointer is interesting for stores.
6477 case Instruction::Call:
6478 case Instruction::CallBr:
6479 case Instruction::Invoke:
6480 case Instruction::CleanupRet:
6481 case Instruction::CatchSwitch:
Johannes Doerfert5732f562019-12-24 19:25:08 -06006482 case Instruction::AtomicRMW:
6483 case Instruction::AtomicCmpXchg:
Hideto Uenoef4febd2019-12-29 17:34:08 +09006484 case Instruction::Br:
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006485 case Instruction::Resume:
6486 case Instruction::Ret:
6487 IsInterestingOpcode = true;
6488 }
6489 if (IsInterestingOpcode)
6490 InstOpcodeMap[I.getOpcode()].push_back(&I);
6491 if (I.mayReadOrWriteMemory())
6492 ReadOrWriteInsts.push_back(&I);
6493 }
6494}
6495
Johannes Doerfert12173e62019-10-13 20:25:25 -05006496void Attributor::recordDependence(const AbstractAttribute &FromAA,
Johannes Doerfert680f6382019-11-02 02:48:05 -05006497 const AbstractAttribute &ToAA,
6498 DepClassTy DepClass) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006499 if (FromAA.getState().isAtFixpoint())
6500 return;
6501
Johannes Doerfert680f6382019-11-02 02:48:05 -05006502 if (DepClass == DepClassTy::REQUIRED)
6503 QueryMap[&FromAA].RequiredAAs.insert(
6504 const_cast<AbstractAttribute *>(&ToAA));
6505 else
6506 QueryMap[&FromAA].OptionalAAs.insert(
6507 const_cast<AbstractAttribute *>(&ToAA));
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006508 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05006509}
6510
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006511void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00006512 if (!VisitedFunctions.insert(&F).second)
6513 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006514 if (F.isDeclaration())
6515 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006516
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006517 IRPosition FPos = IRPosition::function(F);
6518
Johannes Doerfert305b9612019-08-04 18:40:01 +00006519 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00006520 // We need dead instruction detection because we do not want to deal with
6521 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006522 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00006523
6524 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006525 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00006526
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006527 // Every function might contain instructions that cause "undefined behavior".
6528 getOrCreateAAFor<AAUndefinedBehavior>(FPos);
6529
Stefan Stipanovic53605892019-06-27 11:27:54 +00006530 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006531 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00006532
Stefan Stipanovic06263672019-07-11 21:37:40 +00006533 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006534 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00006535
Hideto Ueno65bbaf92019-07-12 17:38:51 +00006536 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006537 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00006538
Johannes Doerferte83f3032019-08-05 23:22:05 +00006539 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006540 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00006541
Hideto Ueno63f60662019-09-21 15:13:19 +00006542 // Every function might be "no-recurse".
6543 getOrCreateAAFor<AANoRecurse>(FPos);
6544
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006545 // Every function might be "readnone/readonly/writeonly/...".
6546 getOrCreateAAFor<AAMemoryBehavior>(FPos);
6547
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006548 // Every function might be applicable for Heap-To-Stack conversion.
6549 if (EnableHeapToStack)
6550 getOrCreateAAFor<AAHeapToStack>(FPos);
6551
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00006552 // Return attributes are only appropriate if the return type is non void.
6553 Type *ReturnType = F.getReturnType();
6554 if (!ReturnType->isVoidTy()) {
6555 // Argument attribute "returned" --- Create only one per function even
6556 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006557 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00006558
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006559 IRPosition RetPos = IRPosition::returned(F);
6560
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006561 // Every returned value might be dead.
6562 getOrCreateAAFor<AAIsDead>(RetPos);
6563
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006564 // Every function might be simplified.
6565 getOrCreateAAFor<AAValueSimplify>(RetPos);
6566
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006567 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006568
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006569 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006570 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006571
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006572 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006573 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006574
6575 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006576 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006577
6578 // Every function with pointer return type might be marked
6579 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006580 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006581 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00006582 }
6583
Hideto Ueno54869ec2019-07-15 06:49:04 +00006584 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006585 IRPosition ArgPos = IRPosition::argument(Arg);
6586
6587 // Every argument might be simplified.
6588 getOrCreateAAFor<AAValueSimplify>(ArgPos);
6589
Hideto Ueno19c07af2019-07-23 08:16:17 +00006590 if (Arg.getType()->isPointerTy()) {
6591 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006592 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006593
Hideto Uenocbab3342019-08-29 05:52:00 +00006594 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006595 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00006596
Hideto Ueno19c07af2019-07-23 08:16:17 +00006597 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006598 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006599
6600 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006601 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006602
6603 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006604 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006605
6606 // Every argument with pointer type might be marked
6607 // "readnone/readonly/writeonly/..."
6608 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006609
6610 // Every argument with pointer type might be marked nofree.
6611 getOrCreateAAFor<AANoFree>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006612 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00006613 }
6614
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006615 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006616 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006617 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006618 // Skip declerations except if annotations on their call sites were
6619 // explicitly requested.
Johannes Doerfert139c9ef2019-12-13 23:41:02 -06006620 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
6621 !Callee->hasMetadata(LLVMContext::MD_callback))
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006622 return true;
6623
6624 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006625
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006626 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
6627
6628 // Call site return values might be dead.
6629 getOrCreateAAFor<AAIsDead>(CSRetPos);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006630
6631 // Call site return integer values might be limited by a constant range.
6632 if (Callee->getReturnType()->isIntegerTy()) {
6633 getOrCreateAAFor<AAValueConstantRange>(CSRetPos);
6634 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006635 }
6636
Johannes Doerfert28880192019-12-31 00:57:00 -06006637 for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006638
6639 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
6640
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006641 // Every call site argument might be dead.
6642 getOrCreateAAFor<AAIsDead>(CSArgPos);
6643
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006644 // Call site argument might be simplified.
6645 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
6646
Hideto Ueno54869ec2019-07-15 06:49:04 +00006647 if (!CS.getArgument(i)->getType()->isPointerTy())
6648 continue;
6649
6650 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006651 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006652
Hideto Uenocbab3342019-08-29 05:52:00 +00006653 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006654 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00006655
Hideto Ueno19c07af2019-07-23 08:16:17 +00006656 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006657 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006658
6659 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006660 getOrCreateAAFor<AAAlign>(CSArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006661
Johannes Doerfert28880192019-12-31 00:57:00 -06006662 // Call site argument attribute
6663 // "readnone/readonly/writeonly/..."
6664 getOrCreateAAFor<AAMemoryBehavior>(CSArgPos);
6665
Hideto Ueno4ecf2552019-12-12 13:42:40 +00006666 // Call site argument attribute "nofree".
6667 getOrCreateAAFor<AANoFree>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00006668 }
6669 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006670 return true;
6671 };
6672
6673 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
6674 bool Success, AnyDead = false;
6675 Success = checkForAllInstructionsImpl(
6676 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
6677 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
6678 (unsigned)Instruction::Call});
6679 (void)Success;
6680 assert(Success && !AnyDead && "Expected the check call to be successful!");
6681
6682 auto LoadStorePred = [&](Instruction &I) -> bool {
6683 if (isa<LoadInst>(I))
6684 getOrCreateAAFor<AAAlign>(
6685 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
6686 else
6687 getOrCreateAAFor<AAAlign>(
6688 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
6689 return true;
6690 };
6691 Success = checkForAllInstructionsImpl(
6692 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
6693 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
6694 (void)Success;
6695 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00006696}
6697
6698/// Helpers to ease debugging through output streams and print calls.
6699///
6700///{
6701raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
6702 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
6703}
6704
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006705raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006706 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006707 case IRPosition::IRP_INVALID:
6708 return OS << "inv";
6709 case IRPosition::IRP_FLOAT:
6710 return OS << "flt";
6711 case IRPosition::IRP_RETURNED:
6712 return OS << "fn_ret";
6713 case IRPosition::IRP_CALL_SITE_RETURNED:
6714 return OS << "cs_ret";
6715 case IRPosition::IRP_FUNCTION:
6716 return OS << "fn";
6717 case IRPosition::IRP_CALL_SITE:
6718 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006719 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00006720 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006721 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00006722 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00006723 }
6724 llvm_unreachable("Unknown attribute position!");
6725}
6726
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006727raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006728 const Value &AV = Pos.getAssociatedValue();
6729 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006730 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
6731}
6732
Johannes Doerfert1a746452019-10-20 22:28:49 -05006733template <typename base_ty, base_ty BestState, base_ty WorstState>
Hideto Ueno188f9a32020-01-15 15:25:52 +09006734raw_ostream &
6735llvm::operator<<(raw_ostream &OS,
6736 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00006737 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
6738 << static_cast<const AbstractState &>(S);
6739}
6740
Hideto Ueno188f9a32020-01-15 15:25:52 +09006741raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {
6742 OS << "range-state(" << S.getBitWidth() << ")<";
6743 S.getKnown().print(OS);
6744 OS << " / ";
6745 S.getAssumed().print(OS);
6746 OS << ">";
6747
6748 return OS << static_cast<const AbstractState &>(S);
6749}
6750
Johannes Doerfertaade7822019-06-05 03:02:24 +00006751raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
6752 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
6753}
6754
6755raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
6756 AA.print(OS);
6757 return OS;
6758}
6759
6760void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006761 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
6762 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00006763}
6764///}
6765
6766/// ----------------------------------------------------------------------------
6767/// Pass (Manager) Boilerplate
6768/// ----------------------------------------------------------------------------
6769
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006770static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006771 if (DisableAttributor)
6772 return false;
6773
6774 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
6775 << " functions.\n");
6776
6777 // Create an Attributor and initially empty information cache that is filled
6778 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00006779 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006780 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006781
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006782 for (Function &F : M)
6783 A.initializeInformationCache(F);
6784
Johannes Doerfertaade7822019-06-05 03:02:24 +00006785 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006786 if (F.hasExactDefinition())
6787 NumFnWithExactDefinition++;
6788 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00006789 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006790
Johannes Doerfert2f622062019-09-04 16:35:20 +00006791 // We look at internal functions only on-demand but if any use is not a
6792 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00006793 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00006794 if (llvm::all_of(F.uses(), [](const Use &U) {
6795 return ImmutableCallSite(U.getUser()) &&
6796 ImmutableCallSite(U.getUser()).isCallee(&U);
6797 }))
6798 continue;
6799 }
6800
Johannes Doerfertaade7822019-06-05 03:02:24 +00006801 // Populate the Attributor with abstract attribute opportunities in the
6802 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006803 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006804 }
6805
Johannes Doerferta4088c72020-01-07 16:01:57 -06006806 bool Changed = A.run(M) == ChangeStatus::CHANGED;
6807 assert(!verifyModule(M, &errs()) && "Module verification failed!");
6808 return Changed;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006809}
6810
6811PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00006812 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006813 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006814 // FIXME: Think about passes we will preserve and add them here.
6815 return PreservedAnalyses::none();
6816 }
6817 return PreservedAnalyses::all();
6818}
6819
6820namespace {
6821
6822struct AttributorLegacyPass : public ModulePass {
6823 static char ID;
6824
6825 AttributorLegacyPass() : ModulePass(ID) {
6826 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
6827 }
6828
6829 bool runOnModule(Module &M) override {
6830 if (skipModule(M))
6831 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006832
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006833 AnalysisGetter AG;
6834 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006835 }
6836
6837 void getAnalysisUsage(AnalysisUsage &AU) const override {
6838 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006839 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00006840 }
6841};
6842
6843} // end anonymous namespace
6844
6845Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
6846
6847char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006848
6849const char AAReturnedValues::ID = 0;
6850const char AANoUnwind::ID = 0;
6851const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00006852const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006853const char AANonNull::ID = 0;
6854const char AANoRecurse::ID = 0;
6855const char AAWillReturn::ID = 0;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006856const char AAUndefinedBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006857const char AANoAlias::ID = 0;
Pankaj Gode04945c92019-11-22 18:40:47 +05306858const char AAReachability::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006859const char AANoReturn::ID = 0;
6860const char AAIsDead::ID = 0;
6861const char AADereferenceable::ID = 0;
6862const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006863const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006864const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006865const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006866const char AAMemoryBehavior::ID = 0;
Hideto Ueno188f9a32020-01-15 15:25:52 +09006867const char AAValueConstantRange::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006868
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006869// Macro magic to create the static generator function for attributes that
6870// follow the naming scheme.
6871
6872#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
6873 case IRPosition::PK: \
6874 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
6875
6876#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
6877 case IRPosition::PK: \
6878 AA = new CLASS##SUFFIX(IRP); \
6879 break;
6880
6881#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6882 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6883 CLASS *AA = nullptr; \
6884 switch (IRP.getPositionKind()) { \
6885 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6886 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
6887 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
6888 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6889 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
6890 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
6891 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6892 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6893 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006894 return *AA; \
6895 }
6896
6897#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6898 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6899 CLASS *AA = nullptr; \
6900 switch (IRP.getPositionKind()) { \
6901 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6902 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
6903 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
6904 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6905 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6906 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
6907 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6908 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6909 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006910 return *AA; \
6911 }
6912
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006913#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6914 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6915 CLASS *AA = nullptr; \
6916 switch (IRP.getPositionKind()) { \
6917 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6918 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6919 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6920 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6921 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6922 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
6923 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6924 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6925 } \
6926 return *AA; \
6927 }
6928
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006929#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6930 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6931 CLASS *AA = nullptr; \
6932 switch (IRP.getPositionKind()) { \
6933 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6934 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
6935 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
6936 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6937 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
6938 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
6939 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
6940 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6941 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006942 return *AA; \
6943 }
6944
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006945#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6946 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6947 CLASS *AA = nullptr; \
6948 switch (IRP.getPositionKind()) { \
6949 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6950 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6951 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6952 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6953 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6954 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6955 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6956 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6957 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006958 return *AA; \
6959 }
6960
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006961CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
6962CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006963CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
6964CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
6965CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006966CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
6967
6968CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
6969CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
6970CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
6971CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006972CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Hideto Ueno188f9a32020-01-15 15:25:52 +09006973CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006974
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006975CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006976CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006977CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006978
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006979CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
Pankaj Gode04945c92019-11-22 18:40:47 +05306980CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006981CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006982
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006983CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
6984
Johannes Doerfertd4bea882019-10-07 23:28:54 +00006985#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006986#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00006987#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006988#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006989#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006990#undef SWITCH_PK_CREATE
6991#undef SWITCH_PK_INV
6992
Johannes Doerfertaade7822019-06-05 03:02:24 +00006993INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
6994 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006995INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00006996INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
6997 "Deduce and propagate attributes", false, false)