blob: a8d7eb35b98eddec9e103380f24a3676cc8b5179 [file] [log] [blame]
Johannes Doerfertaade7822019-06-05 03:02:24 +00001//===- Attributor.cpp - Module-wide attribute deduction -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements an inter procedural pass that deduces and/or propagating
10// attributes. This is done in an abstract interpretation style fixpoint
11// iteration. See the Attributor.h file comment and the class descriptions in
12// that file for more information.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Transforms/IPO/Attributor.h"
17
Hideto Ueno11d37102019-07-17 15:15:43 +000018#include "llvm/ADT/DepthFirstIterator.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000019#include "llvm/ADT/STLExtras.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000020#include "llvm/ADT/SmallPtrSet.h"
21#include "llvm/ADT/SmallVector.h"
22#include "llvm/ADT/Statistic.h"
Stefan Stipanovic69ebb022019-07-22 19:36:27 +000023#include "llvm/Analysis/CaptureTracking.h"
Johannes Doerfert924d2132019-08-05 21:34:45 +000024#include "llvm/Analysis/EHPersonalities.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000025#include "llvm/Analysis/GlobalsModRef.h"
Hideto Ueno19c07af2019-07-23 08:16:17 +000026#include "llvm/Analysis/Loads.h"
Stefan Stipanovic431141c2019-09-15 21:47:41 +000027#include "llvm/Analysis/MemoryBuiltins.h"
Hideto Ueno54869ec2019-07-15 06:49:04 +000028#include "llvm/Analysis/ValueTracking.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000029#include "llvm/IR/Argument.h"
30#include "llvm/IR/Attributes.h"
Hideto Ueno11d37102019-07-17 15:15:43 +000031#include "llvm/IR/CFG.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000032#include "llvm/IR/InstIterator.h"
Stefan Stipanovic06263672019-07-11 21:37:40 +000033#include "llvm/IR/IntrinsicInst.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080034#include "llvm/InitializePasses.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000035#include "llvm/Support/CommandLine.h"
36#include "llvm/Support/Debug.h"
37#include "llvm/Support/raw_ostream.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000038#include "llvm/Transforms/Utils/BasicBlockUtils.h"
39#include "llvm/Transforms/Utils/Local.h"
40
Johannes Doerfertaade7822019-06-05 03:02:24 +000041#include <cassert>
42
43using namespace llvm;
44
45#define DEBUG_TYPE "attributor"
46
47STATISTIC(NumFnWithExactDefinition,
48 "Number of function with exact definitions");
49STATISTIC(NumFnWithoutExactDefinition,
50 "Number of function without exact definitions");
51STATISTIC(NumAttributesTimedOut,
52 "Number of abstract attributes timed out before fixpoint");
53STATISTIC(NumAttributesValidFixpoint,
54 "Number of abstract attributes in a valid fixpoint state");
55STATISTIC(NumAttributesManifested,
56 "Number of abstract attributes manifested in IR");
Johannes Doerfert680f6382019-11-02 02:48:05 -050057STATISTIC(NumAttributesFixedDueToRequiredDependences,
58 "Number of abstract attributes fixed due to required dependences");
Johannes Doerfertaade7822019-06-05 03:02:24 +000059
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000060// Some helper macros to deal with statistics tracking.
61//
62// Usage:
63// For simple IR attribute tracking overload trackStatistics in the abstract
Johannes Doerfert17b578b2019-08-14 21:46:25 +000064// attribute and choose the right STATS_DECLTRACK_********* macro,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000065// e.g.,:
66// void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +000067// STATS_DECLTRACK_ARG_ATTR(returned)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000068// }
69// If there is a single "increment" side one can use the macro
Johannes Doerfert17b578b2019-08-14 21:46:25 +000070// STATS_DECLTRACK with a custom message. If there are multiple increment
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000071// sides, STATS_DECL and STATS_TRACK can also be used separatly.
72//
73#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
74 ("Number of " #TYPE " marked '" #NAME "'")
75#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
Johannes Doerferta7a3b3a2019-09-04 19:01:08 +000076#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
77#define STATS_DECL(NAME, TYPE, MSG) \
78 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000079#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
Johannes Doerfert17b578b2019-08-14 21:46:25 +000080#define STATS_DECLTRACK(NAME, TYPE, MSG) \
Johannes Doerfert169af992019-08-20 06:09:56 +000081 { \
82 STATS_DECL(NAME, TYPE, MSG) \
83 STATS_TRACK(NAME, TYPE) \
84 }
Johannes Doerfert17b578b2019-08-14 21:46:25 +000085#define STATS_DECLTRACK_ARG_ATTR(NAME) \
86 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
87#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
88 STATS_DECLTRACK(NAME, CSArguments, \
89 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
90#define STATS_DECLTRACK_FN_ATTR(NAME) \
91 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
92#define STATS_DECLTRACK_CS_ATTR(NAME) \
93 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
94#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
95 STATS_DECLTRACK(NAME, FunctionReturn, \
Johannes Doerfert2db85282019-08-21 20:56:56 +000096 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
Johannes Doerfert17b578b2019-08-14 21:46:25 +000097#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
98 STATS_DECLTRACK(NAME, CSReturn, \
99 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
100#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
101 STATS_DECLTRACK(NAME, Floating, \
102 ("Number of floating values known to be '" #NAME "'"))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000103
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600104// Specialization of the operator<< for abstract attributes subclasses. This
105// disambiguates situations where multiple operators are applicable.
106namespace llvm {
107#define PIPE_OPERATOR(CLASS) \
108 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
109 return OS << static_cast<const AbstractAttribute &>(AA); \
110 }
111
112PIPE_OPERATOR(AAIsDead)
113PIPE_OPERATOR(AANoUnwind)
114PIPE_OPERATOR(AANoSync)
115PIPE_OPERATOR(AANoRecurse)
116PIPE_OPERATOR(AAWillReturn)
117PIPE_OPERATOR(AANoReturn)
118PIPE_OPERATOR(AAReturnedValues)
119PIPE_OPERATOR(AANonNull)
120PIPE_OPERATOR(AANoAlias)
121PIPE_OPERATOR(AADereferenceable)
122PIPE_OPERATOR(AAAlign)
123PIPE_OPERATOR(AANoCapture)
124PIPE_OPERATOR(AAValueSimplify)
125PIPE_OPERATOR(AANoFree)
126PIPE_OPERATOR(AAHeapToStack)
127PIPE_OPERATOR(AAReachability)
128PIPE_OPERATOR(AAMemoryBehavior)
129
130#undef PIPE_OPERATOR
131} // namespace llvm
132
Johannes Doerfertaade7822019-06-05 03:02:24 +0000133// TODO: Determine a good default value.
134//
135// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
136// (when run with the first 5 abstract attributes). The results also indicate
137// that we never reach 32 iterations but always find a fixpoint sooner.
138//
139// This will become more evolved once we perform two interleaved fixpoint
140// iterations: bottom-up and top-down.
141static cl::opt<unsigned>
142 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
143 cl::desc("Maximal number of fixpoint iterations."),
144 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000145static cl::opt<bool> VerifyMaxFixpointIterations(
146 "attributor-max-iterations-verify", cl::Hidden,
147 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
148 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000149
150static cl::opt<bool> DisableAttributor(
151 "attributor-disable", cl::Hidden,
152 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000153 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000154
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500155static cl::opt<bool> AnnotateDeclarationCallSites(
156 "attributor-annotate-decl-cs", cl::Hidden,
157 cl::desc("Annoate call sites of function declarations."), cl::init(false));
158
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000159static cl::opt<bool> ManifestInternal(
160 "attributor-manifest-internal", cl::Hidden,
161 cl::desc("Manifest Attributor internal string attributes."),
162 cl::init(false));
163
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000164static cl::opt<unsigned> DepRecInterval(
165 "attributor-dependence-recompute-interval", cl::Hidden,
166 cl::desc("Number of iterations until dependences are recomputed."),
167 cl::init(4));
168
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000169static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
170 cl::init(true), cl::Hidden);
171
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000172static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
173 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000174
Johannes Doerfertaade7822019-06-05 03:02:24 +0000175/// Logic operators for the change status enum class.
176///
177///{
178ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
179 return l == ChangeStatus::CHANGED ? l : r;
180}
181ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
182 return l == ChangeStatus::UNCHANGED ? l : r;
183}
184///}
185
Johannes Doerfertb1b441d2019-10-10 01:19:57 -0500186Argument *IRPosition::getAssociatedArgument() const {
187 if (getPositionKind() == IRP_ARGUMENT)
188 return cast<Argument>(&getAnchorValue());
189
190 // Not an Argument and no argument number means this is not a call site
191 // argument, thus we cannot find a callback argument to return.
192 int ArgNo = getArgNo();
193 if (ArgNo < 0)
194 return nullptr;
195
196 // Use abstract call sites to make the connection between the call site
197 // values and the ones in callbacks. If a callback was found that makes use
198 // of the underlying call site operand, we want the corresponding callback
199 // callee argument and not the direct callee argument.
200 Optional<Argument *> CBCandidateArg;
201 SmallVector<const Use *, 4> CBUses;
202 ImmutableCallSite ICS(&getAnchorValue());
203 AbstractCallSite::getCallbackUses(ICS, CBUses);
204 for (const Use *U : CBUses) {
205 AbstractCallSite ACS(U);
206 assert(ACS && ACS.isCallbackCall());
207 if (!ACS.getCalledFunction())
208 continue;
209
210 for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {
211
212 // Test if the underlying call site operand is argument number u of the
213 // callback callee.
214 if (ACS.getCallArgOperandNo(u) != ArgNo)
215 continue;
216
217 assert(ACS.getCalledFunction()->arg_size() > u &&
218 "ACS mapped into var-args arguments!");
219 if (CBCandidateArg.hasValue()) {
220 CBCandidateArg = nullptr;
221 break;
222 }
223 CBCandidateArg = ACS.getCalledFunction()->getArg(u);
224 }
225 }
226
227 // If we found a unique callback candidate argument, return it.
228 if (CBCandidateArg.hasValue() && CBCandidateArg.getValue())
229 return CBCandidateArg.getValue();
230
231 // If no callbacks were found, or none used the underlying call site operand
232 // exclusively, use the direct callee argument if available.
233 const Function *Callee = ICS.getCalledFunction();
234 if (Callee && Callee->arg_size() > unsigned(ArgNo))
235 return Callee->getArg(ArgNo);
236
237 return nullptr;
238}
239
Johannes Doerfert5d346022019-12-13 22:11:42 -0600240/// For calls (and invokes) we will only replace instruction uses to not disturb
241/// the old style call graph.
242/// TODO: Remove this once we get rid of the old PM.
243static void replaceAllInstructionUsesWith(Value &Old, Value &New) {
244 if (!isa<CallBase>(Old))
245 return Old.replaceAllUsesWith(&New);
246 SmallVector<Use *, 8> Uses;
247 for (Use &U : Old.uses())
248 if (isa<Instruction>(U.getUser()))
249 Uses.push_back(&U);
250 for (Use *U : Uses)
251 U->set(&New);
252}
253
Johannes Doerfertdef99282019-08-14 21:29:37 +0000254/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000255/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000256/// with the "returned" attribute. Once we cannot look through the value any
257/// further, the callback \p VisitValueCB is invoked and passed the current
258/// value, the \p State, and a flag to indicate if we stripped anything. To
259/// limit how much effort is invested, we will never visit more values than
260/// specified by \p MaxValues.
261template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000262static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000263 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000264 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000265 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000266
Johannes Doerfertdef99282019-08-14 21:29:37 +0000267 const AAIsDead *LivenessAA = nullptr;
268 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000269 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000270 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
271 /* TrackDependence */ false);
272 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000273
274 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000275 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000276 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000277 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000278
279 int Iteration = 0;
280 do {
281 Value *V = Worklist.pop_back_val();
282
283 // Check if we should process the current value. To prevent endless
284 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000285 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000286 continue;
287
288 // Make sure we limit the compile time for complex expressions.
289 if (Iteration++ >= MaxValues)
290 return false;
291
292 // Explicitly look through calls with a "returned" attribute if we do
293 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000294 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000295 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000296 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000297 } else {
298 CallSite CS(V);
299 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000300 for (Argument &Arg : CS.getCalledFunction()->args())
301 if (Arg.hasReturnedAttr()) {
302 NewV = CS.getArgOperand(Arg.getArgNo());
303 break;
304 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000305 }
306 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000307 if (NewV && NewV != V) {
308 Worklist.push_back(NewV);
309 continue;
310 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000311
312 // Look through select instructions, visit both potential values.
313 if (auto *SI = dyn_cast<SelectInst>(V)) {
314 Worklist.push_back(SI->getTrueValue());
315 Worklist.push_back(SI->getFalseValue());
316 continue;
317 }
318
Johannes Doerfertdef99282019-08-14 21:29:37 +0000319 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000320 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000321 assert(LivenessAA &&
322 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000323 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
324 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000325 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000326 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000327 continue;
328 }
329 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000330 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000331 continue;
332 }
333
334 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000335 if (!VisitValueCB(*V, State, Iteration > 1))
336 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000337 } while (!Worklist.empty());
338
Johannes Doerfert19b00432019-08-26 17:48:05 +0000339 // If we actually used liveness information so we have to record a dependence.
340 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -0500341 A.recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000342
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000343 // All values have been visited.
344 return true;
345}
346
Johannes Doerfertaade7822019-06-05 03:02:24 +0000347/// Return true if \p New is equal or worse than \p Old.
348static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
349 if (!Old.isIntAttribute())
350 return true;
351
352 return Old.getValueAsInt() >= New.getValueAsInt();
353}
354
355/// Return true if the information provided by \p Attr was added to the
356/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000357/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000358static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000359 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000360
361 if (Attr.isEnumAttribute()) {
362 Attribute::AttrKind Kind = Attr.getKindAsEnum();
363 if (Attrs.hasAttribute(AttrIdx, Kind))
364 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
365 return false;
366 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
367 return true;
368 }
369 if (Attr.isStringAttribute()) {
370 StringRef Kind = Attr.getKindAsString();
371 if (Attrs.hasAttribute(AttrIdx, Kind))
372 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
373 return false;
374 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
375 return true;
376 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000377 if (Attr.isIntAttribute()) {
378 Attribute::AttrKind Kind = Attr.getKindAsEnum();
379 if (Attrs.hasAttribute(AttrIdx, Kind))
380 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
381 return false;
382 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
383 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
384 return true;
385 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000386
387 llvm_unreachable("Expected enum or string attribute!");
388}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000389
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000390static const Value *
391getBasePointerOfAccessPointerOperand(const Instruction *I, int64_t &BytesOffset,
392 const DataLayout &DL,
393 bool AllowNonInbounds = false) {
Hideto Uenoef4febd2019-12-29 17:34:08 +0900394 const Value *Ptr =
395 Attributor::getPointerOperand(I, /* AllowVolatile */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000396 if (!Ptr)
397 return nullptr;
398
399 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000400 AllowNonInbounds);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000401}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000402
Johannes Doerfertece81902019-08-12 22:05:53 +0000403ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000404 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
405 if (getState().isAtFixpoint())
406 return HasChanged;
407
408 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
409
Johannes Doerfertece81902019-08-12 22:05:53 +0000410 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000411
412 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
413 << "\n");
414
415 return HasChanged;
416}
417
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000418ChangeStatus
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500419IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000420 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000421 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000422 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000423
Johannes Doerfertaade7822019-06-05 03:02:24 +0000424 // In the following some generic code that will manifest attributes in
425 // DeducedAttrs if they improve the current IR. Due to the different
426 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000427
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000428 AttributeList Attrs;
429 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000430 case IRPosition::IRP_INVALID:
431 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000432 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000433 case IRPosition::IRP_ARGUMENT:
434 case IRPosition::IRP_FUNCTION:
435 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000436 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000437 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000438 case IRPosition::IRP_CALL_SITE:
439 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000440 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000441 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000442 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000443 }
444
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000445 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000446 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000447 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000448 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000449 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000450
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000451 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000452 }
453
454 if (HasChanged == ChangeStatus::UNCHANGED)
455 return HasChanged;
456
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000457 switch (PK) {
458 case IRPosition::IRP_ARGUMENT:
459 case IRPosition::IRP_FUNCTION:
460 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000461 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000462 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000463 case IRPosition::IRP_CALL_SITE:
464 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000465 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000466 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000467 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000468 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000469 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000470 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000471 }
472
473 return HasChanged;
474}
475
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000476const IRPosition IRPosition::EmptyKey(255);
477const IRPosition IRPosition::TombstoneKey(256);
478
479SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
480 IRPositions.emplace_back(IRP);
481
482 ImmutableCallSite ICS(&IRP.getAnchorValue());
483 switch (IRP.getPositionKind()) {
484 case IRPosition::IRP_INVALID:
485 case IRPosition::IRP_FLOAT:
486 case IRPosition::IRP_FUNCTION:
487 return;
488 case IRPosition::IRP_ARGUMENT:
489 case IRPosition::IRP_RETURNED:
490 IRPositions.emplace_back(
491 IRPosition::function(*IRP.getAssociatedFunction()));
492 return;
493 case IRPosition::IRP_CALL_SITE:
494 assert(ICS && "Expected call site!");
495 // TODO: We need to look at the operand bundles similar to the redirection
496 // in CallBase.
497 if (!ICS.hasOperandBundles())
498 if (const Function *Callee = ICS.getCalledFunction())
499 IRPositions.emplace_back(IRPosition::function(*Callee));
500 return;
501 case IRPosition::IRP_CALL_SITE_RETURNED:
502 assert(ICS && "Expected call site!");
503 // TODO: We need to look at the operand bundles similar to the redirection
504 // in CallBase.
505 if (!ICS.hasOperandBundles()) {
506 if (const Function *Callee = ICS.getCalledFunction()) {
507 IRPositions.emplace_back(IRPosition::returned(*Callee));
508 IRPositions.emplace_back(IRPosition::function(*Callee));
509 }
510 }
511 IRPositions.emplace_back(
512 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
513 return;
514 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
515 int ArgNo = IRP.getArgNo();
516 assert(ICS && ArgNo >= 0 && "Expected call site!");
517 // TODO: We need to look at the operand bundles similar to the redirection
518 // in CallBase.
519 if (!ICS.hasOperandBundles()) {
520 const Function *Callee = ICS.getCalledFunction();
521 if (Callee && Callee->arg_size() > unsigned(ArgNo))
522 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
523 if (Callee)
524 IRPositions.emplace_back(IRPosition::function(*Callee));
525 }
526 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
527 return;
528 }
529 }
530}
531
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000532bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
533 bool IgnoreSubsumingPositions) const {
534 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000535 for (Attribute::AttrKind AK : AKs)
536 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
537 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000538 // The first position returned by the SubsumingPositionIterator is
539 // always the position itself. If we ignore subsuming positions we
540 // are done after the first iteration.
541 if (IgnoreSubsumingPositions)
542 break;
543 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000544 return false;
545}
546
547void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600548 SmallVectorImpl<Attribute> &Attrs,
549 bool IgnoreSubsumingPositions) const {
550 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000551 for (Attribute::AttrKind AK : AKs) {
552 const Attribute &Attr = EquivIRP.getAttr(AK);
553 if (Attr.getKindAsEnum() == AK)
554 Attrs.push_back(Attr);
555 }
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600556 // The first position returned by the SubsumingPositionIterator is
557 // always the position itself. If we ignore subsuming positions we
558 // are done after the first iteration.
559 if (IgnoreSubsumingPositions)
560 break;
561 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000562}
563
564void IRPosition::verify() {
565 switch (KindOrArgNo) {
566 default:
567 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
568 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
569 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000570 if (isa<Argument>(AnchorVal)) {
571 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000572 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000573 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
574 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000575 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000576 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000577 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000578 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
579 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000580 "Associated value mismatch!");
581 }
582 break;
583 case IRP_INVALID:
584 assert(!AnchorVal && "Expected no value for an invalid position!");
585 break;
586 case IRP_FLOAT:
587 assert((!isa<CallBase>(&getAssociatedValue()) &&
588 !isa<Argument>(&getAssociatedValue())) &&
589 "Expected specialized kind for call base and argument values!");
590 break;
591 case IRP_RETURNED:
592 assert(isa<Function>(AnchorVal) &&
593 "Expected function for a 'returned' position!");
594 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
595 break;
596 case IRP_CALL_SITE_RETURNED:
597 assert((isa<CallBase>(AnchorVal)) &&
598 "Expected call base for 'call site returned' position!");
599 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
600 break;
601 case IRP_CALL_SITE:
602 assert((isa<CallBase>(AnchorVal)) &&
603 "Expected call base for 'call site function' position!");
604 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
605 break;
606 case IRP_FUNCTION:
607 assert(isa<Function>(AnchorVal) &&
608 "Expected function for a 'function' position!");
609 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
610 break;
611 }
612}
613
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000614namespace {
Johannes Doerfert1a746452019-10-20 22:28:49 -0500615/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000616/// information in \p R and indicate/return if \p S did change (as-in update is
617/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000618template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500619ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000620 auto Assumed = S.getAssumed();
621 S ^= R;
622 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
623 : ChangeStatus::CHANGED;
624}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000625
Johannes Doerfert234eda52019-08-16 19:51:23 +0000626/// Clamp the information known for all returned values of a function
627/// (identified by \p QueryingAA) into \p S.
628template <typename AAType, typename StateType = typename AAType::StateType>
629static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
630 StateType &S) {
631 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600632 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000633
634 assert((QueryingAA.getIRPosition().getPositionKind() ==
635 IRPosition::IRP_RETURNED ||
636 QueryingAA.getIRPosition().getPositionKind() ==
637 IRPosition::IRP_CALL_SITE_RETURNED) &&
638 "Can only clamp returned value states for a function returned or call "
639 "site returned position!");
640
641 // Use an optional state as there might not be any return values and we want
642 // to join (IntegerState::operator&) the state of all there are.
643 Optional<StateType> T;
644
645 // Callback for each possibly returned value.
646 auto CheckReturnValue = [&](Value &RV) -> bool {
647 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000648 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
649 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
650 << " @ " << RVPos << "\n");
651 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000652 if (T.hasValue())
653 *T &= AAS;
654 else
655 T = AAS;
656 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
657 << "\n");
658 return T->isValidState();
659 };
660
661 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
662 S.indicatePessimisticFixpoint();
663 else if (T.hasValue())
664 S ^= *T;
665}
666
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000667/// Helper class to compose two generic deduction
668template <typename AAType, typename Base, typename StateType,
669 template <typename...> class F, template <typename...> class G>
670struct AAComposeTwoGenericDeduction
671 : public F<AAType, G<AAType, Base, StateType>, StateType> {
672 AAComposeTwoGenericDeduction(const IRPosition &IRP)
673 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
674
675 /// See AbstractAttribute::updateImpl(...).
676 ChangeStatus updateImpl(Attributor &A) override {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100677 ChangeStatus ChangedF =
678 F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000679 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
680 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000681 }
682};
683
Johannes Doerfert234eda52019-08-16 19:51:23 +0000684/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000685template <typename AAType, typename Base,
686 typename StateType = typename AAType::StateType>
687struct AAReturnedFromReturnedValues : public Base {
688 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000689
690 /// See AbstractAttribute::updateImpl(...).
691 ChangeStatus updateImpl(Attributor &A) override {
692 StateType S;
693 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000694 // TODO: If we know we visited all returned values, thus no are assumed
695 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000696 return clampStateAndIndicateChange<StateType>(this->getState(), S);
697 }
698};
699
700/// Clamp the information known at all call sites for a given argument
701/// (identified by \p QueryingAA) into \p S.
702template <typename AAType, typename StateType = typename AAType::StateType>
703static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
704 StateType &S) {
705 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600706 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000707
708 assert(QueryingAA.getIRPosition().getPositionKind() ==
709 IRPosition::IRP_ARGUMENT &&
710 "Can only clamp call site argument states for an argument position!");
711
712 // Use an optional state as there might not be any return values and we want
713 // to join (IntegerState::operator&) the state of all there are.
714 Optional<StateType> T;
715
716 // The argument number which is also the call site argument number.
717 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
718
Johannes Doerfert661db042019-10-07 23:14:58 +0000719 auto CallSiteCheck = [&](AbstractCallSite ACS) {
720 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
721 // Check if a coresponding argument was found or if it is on not associated
722 // (which can happen for callback calls).
723 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
724 return false;
725
726 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
727 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
728 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000729 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000730 if (T.hasValue())
731 *T &= AAS;
732 else
733 T = AAS;
734 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
735 << "\n");
736 return T->isValidState();
737 };
738
739 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true))
740 S.indicatePessimisticFixpoint();
741 else if (T.hasValue())
742 S ^= *T;
743}
744
745/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000746template <typename AAType, typename Base,
747 typename StateType = typename AAType::StateType>
748struct AAArgumentFromCallSiteArguments : public Base {
749 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000750
751 /// See AbstractAttribute::updateImpl(...).
752 ChangeStatus updateImpl(Attributor &A) override {
753 StateType S;
754 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000755 // TODO: If we know we visited all incoming values, thus no are assumed
756 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000757 return clampStateAndIndicateChange<StateType>(this->getState(), S);
758 }
759};
760
761/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000762template <typename AAType, typename Base,
763 typename StateType = typename AAType::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000764struct AACallSiteReturnedFromReturned : public Base {
765 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000766
767 /// See AbstractAttribute::updateImpl(...).
768 ChangeStatus updateImpl(Attributor &A) override {
769 assert(this->getIRPosition().getPositionKind() ==
770 IRPosition::IRP_CALL_SITE_RETURNED &&
771 "Can only wrap function returned positions for call site returned "
772 "positions!");
773 auto &S = this->getState();
774
775 const Function *AssociatedFunction =
776 this->getIRPosition().getAssociatedFunction();
777 if (!AssociatedFunction)
778 return S.indicatePessimisticFixpoint();
779
780 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000781 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000782 return clampStateAndIndicateChange(
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000783 S, static_cast<const typename AAType::StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000784 }
785};
786
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000787/// Helper class for generic deduction using must-be-executed-context
788/// Base class is required to have `followUse` method.
789
790/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000791/// U - Underlying use.
792/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000793/// `followUse` returns true if the value should be tracked transitively.
794
795template <typename AAType, typename Base,
796 typename StateType = typename AAType::StateType>
797struct AAFromMustBeExecutedContext : public Base {
798 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
799
800 void initialize(Attributor &A) override {
801 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500802 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000803 Instruction *CtxI = IRP.getCtxI();
804
805 if (!CtxI)
806 return;
807
808 for (const Use &U : IRP.getAssociatedValue().uses())
809 Uses.insert(&U);
810 }
811
812 /// See AbstractAttribute::updateImpl(...).
813 ChangeStatus updateImpl(Attributor &A) override {
814 auto BeforeState = this->getState();
815 auto &S = this->getState();
816 Instruction *CtxI = this->getIRPosition().getCtxI();
817 if (!CtxI)
818 return ChangeStatus::UNCHANGED;
819
820 MustBeExecutedContextExplorer &Explorer =
821 A.getInfoCache().getMustBeExecutedContextExplorer();
822
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500823 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100824 for (unsigned u = 0; u < Uses.size(); ++u) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500825 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000826 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500827 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000828 if (Found && Base::followUse(A, U, UserI))
829 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500830 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000831 }
832 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000833
834 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
835 }
836
837private:
838 /// Container for (transitive) uses of the associated value.
839 SetVector<const Use *> Uses;
840};
841
842template <typename AAType, typename Base,
843 typename StateType = typename AAType::StateType>
844using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
845 AAComposeTwoGenericDeduction<AAType, Base, StateType,
846 AAFromMustBeExecutedContext,
847 AAArgumentFromCallSiteArguments>;
848
849template <typename AAType, typename Base,
850 typename StateType = typename AAType::StateType>
851using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
852 AAComposeTwoGenericDeduction<AAType, Base, StateType,
853 AAFromMustBeExecutedContext,
854 AACallSiteReturnedFromReturned>;
855
Stefan Stipanovic53605892019-06-27 11:27:54 +0000856/// -----------------------NoUnwind Function Attribute--------------------------
857
Johannes Doerfert344d0382019-08-07 22:34:26 +0000858struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000859 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000860
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000861 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000862 return getAssumed() ? "nounwind" : "may-unwind";
863 }
864
865 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000866 ChangeStatus updateImpl(Attributor &A) override {
867 auto Opcodes = {
868 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
869 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
870 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
871
872 auto CheckForNoUnwind = [&](Instruction &I) {
873 if (!I.mayThrow())
874 return true;
875
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000876 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
877 const auto &NoUnwindAA =
878 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
879 return NoUnwindAA.isAssumedNoUnwind();
880 }
881 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000882 };
883
884 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
885 return indicatePessimisticFixpoint();
886
887 return ChangeStatus::UNCHANGED;
888 }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000889};
890
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000891struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000892 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000893
894 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000895 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000896};
897
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000898/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000899struct AANoUnwindCallSite final : AANoUnwindImpl {
900 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
901
902 /// See AbstractAttribute::initialize(...).
903 void initialize(Attributor &A) override {
904 AANoUnwindImpl::initialize(A);
905 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000906 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +0000907 indicatePessimisticFixpoint();
908 }
909
910 /// See AbstractAttribute::updateImpl(...).
911 ChangeStatus updateImpl(Attributor &A) override {
912 // TODO: Once we have call site specific value information we can provide
913 // call site specific liveness information and then it makes
914 // sense to specialize attributes for call sites arguments instead of
915 // redirecting requests to the callee argument.
916 Function *F = getAssociatedFunction();
917 const IRPosition &FnPos = IRPosition::function(*F);
918 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
919 return clampStateAndIndicateChange(
920 getState(),
921 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
922 }
923
924 /// See AbstractAttribute::trackStatistics()
925 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
926};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +0000927
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000928/// --------------------- Function Return Values -------------------------------
929
930/// "Attribute" that collects all potential returned values and the return
931/// instructions that they arise from.
932///
933/// If there is a unique returned value R, the manifest method will:
934/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +0000935class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000936
937 /// Mapping of values potentially returned by the associated function to the
938 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +0000939 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000940
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000941 /// Mapping to remember the number of returned values for a call site such
942 /// that we can avoid updates if nothing changed.
943 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
944
945 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +0000946 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000947
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000948 /// State flags
949 ///
950 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +0000951 bool IsFixed = false;
952 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000953 ///}
954
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000955public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000956 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000957
958 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +0000959 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000960 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000961 IsFixed = false;
962 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000963 ReturnedValues.clear();
964
Johannes Doerfertdef99282019-08-14 21:29:37 +0000965 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000966 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000967 indicatePessimisticFixpoint();
968 return;
969 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000970
971 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000972 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000973
974 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000975 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000976 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000977 auto &ReturnInstSet = ReturnedValues[&Arg];
978 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
979 ReturnInstSet.insert(cast<ReturnInst>(RI));
980
981 indicateOptimisticFixpoint();
982 return;
983 }
984 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +0000985
986 if (!F->hasExactDefinition())
987 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000988 }
989
990 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000991 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000992
993 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000994 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000995
996 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000997 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000998
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000999 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00001000 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001001
Johannes Doerfertdef99282019-08-14 21:29:37 +00001002 llvm::iterator_range<iterator> returned_values() override {
1003 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1004 }
1005
1006 llvm::iterator_range<const_iterator> returned_values() const override {
1007 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1008 }
1009
Johannes Doerfert695089e2019-08-23 15:23:49 +00001010 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001011 return UnresolvedCalls;
1012 }
1013
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001014 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001015 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001016 return isValidState() ? ReturnedValues.size() : -1;
1017 }
1018
1019 /// Return an assumed unique return value if a single candidate is found. If
1020 /// there cannot be one, return a nullptr. If it is not clear yet, return the
1021 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001022 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001023
Johannes Doerfert14a04932019-08-07 22:27:24 +00001024 /// See AbstractState::checkForAllReturnedValues(...).
1025 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001026 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001027 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001028
1029 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001030 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001031
1032 /// See AbstractState::isAtFixpoint().
1033 bool isAtFixpoint() const override { return IsFixed; }
1034
1035 /// See AbstractState::isValidState().
1036 bool isValidState() const override { return IsValidState; }
1037
1038 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001039 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001040 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001041 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001042 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001043
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001044 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001045 IsFixed = true;
1046 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001047 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001048 }
1049};
1050
1051ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
1052 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1053
1054 // Bookkeeping.
1055 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001056 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
1057 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001058
1059 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001060 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001061
1062 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
1063 return Changed;
1064
1065 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001066 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
1067 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001068
Johannes Doerfert23400e612019-08-23 17:41:37 +00001069 // Callback to replace the uses of CB with the constant C.
1070 auto ReplaceCallSiteUsersWith = [](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +00001071 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +00001072 return ChangeStatus::UNCHANGED;
Johannes Doerfert5d346022019-12-13 22:11:42 -06001073 replaceAllInstructionUsesWith(CB, C);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001074 return ChangeStatus::CHANGED;
1075 };
1076
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001077 // If the assumed unique return value is an argument, annotate it.
1078 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05001079 // TODO: This should be handled differently!
1080 this->AnchorVal = UniqueRVArg;
1081 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +00001082 Changed = IRAttribute::manifest(A);
1083 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
1084 // We can replace the returned value with the unique returned constant.
1085 Value &AnchorValue = getAnchorValue();
1086 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1087 for (const Use &U : F->uses())
1088 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001089 if (CB->isCallee(&U)) {
1090 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001091 CB->getType() == RVC->getType()
1092 ? RVC
1093 : ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001094 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1095 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001096 } else {
1097 assert(isa<CallBase>(AnchorValue) &&
1098 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001099 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001100 AnchorValue.getType() == RVC->getType()
1101 ? RVC
1102 : ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001103 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001104 }
1105 if (Changed == ChangeStatus::CHANGED)
1106 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1107 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001108 }
1109
1110 return Changed;
1111}
1112
1113const std::string AAReturnedValuesImpl::getAsStr() const {
1114 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001115 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001116 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001117}
1118
Johannes Doerfert14a04932019-08-07 22:27:24 +00001119Optional<Value *>
1120AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1121 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001122 // undef values that can also be present, it is assumed to be the actual
1123 // return value and forwarded to the caller of this method. If there are
1124 // multiple, a nullptr is returned indicating there cannot be a unique
1125 // returned value.
1126 Optional<Value *> UniqueRV;
1127
Johannes Doerfert14a04932019-08-07 22:27:24 +00001128 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001129 // If we found a second returned value and neither the current nor the saved
1130 // one is an undef, there is no unique returned value. Undefs are special
1131 // since we can pretend they have any value.
1132 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1133 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1134 UniqueRV = nullptr;
1135 return false;
1136 }
1137
1138 // Do not overwrite a value with an undef.
1139 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1140 UniqueRV = &RV;
1141
1142 return true;
1143 };
1144
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001145 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001146 UniqueRV = nullptr;
1147
1148 return UniqueRV;
1149}
1150
Johannes Doerfert14a04932019-08-07 22:27:24 +00001151bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001152 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001153 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001154 if (!isValidState())
1155 return false;
1156
1157 // Check all returned values but ignore call sites as long as we have not
1158 // encountered an overdefined one during an update.
1159 for (auto &It : ReturnedValues) {
1160 Value *RV = It.first;
1161
Johannes Doerfertdef99282019-08-14 21:29:37 +00001162 CallBase *CB = dyn_cast<CallBase>(RV);
1163 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001164 continue;
1165
Johannes Doerfert695089e2019-08-23 15:23:49 +00001166 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001167 return false;
1168 }
1169
1170 return true;
1171}
1172
Johannes Doerfertece81902019-08-12 22:05:53 +00001173ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001174 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1175 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001176
Johannes Doerfertdef99282019-08-14 21:29:37 +00001177 // State used in the value traversals starting in returned values.
1178 struct RVState {
1179 // The map in which we collect return values -> return instrs.
1180 decltype(ReturnedValues) &RetValsMap;
1181 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001182 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001183 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001184 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001185 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001186
Johannes Doerfertdef99282019-08-14 21:29:37 +00001187 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001188 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001189 auto Size = RVS.RetValsMap[&Val].size();
1190 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1191 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1192 RVS.Changed |= Inserted;
1193 LLVM_DEBUG({
1194 if (Inserted)
1195 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1196 << " => " << RVS.RetInsts.size() << "\n";
1197 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001198 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001199 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001200
Johannes Doerfertdef99282019-08-14 21:29:37 +00001201 // Helper method to invoke the generic value traversal.
1202 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1203 IRPosition RetValPos = IRPosition::value(RV);
1204 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1205 RVS, VisitValueCB);
1206 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001207
Johannes Doerfertdef99282019-08-14 21:29:37 +00001208 // Callback for all "return intructions" live in the associated function.
1209 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1210 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001211 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001212 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001213 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1214 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001215
Johannes Doerfertdef99282019-08-14 21:29:37 +00001216 // Start by discovering returned values from all live returned instructions in
1217 // the associated function.
1218 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1219 return indicatePessimisticFixpoint();
1220
1221 // Once returned values "directly" present in the code are handled we try to
1222 // resolve returned calls.
1223 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001224 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001225 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1226 << " by #" << It.second.size() << " RIs\n");
1227 CallBase *CB = dyn_cast<CallBase>(It.first);
1228 if (!CB || UnresolvedCalls.count(CB))
1229 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001230
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001231 if (!CB->getCalledFunction()) {
1232 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1233 << "\n");
1234 UnresolvedCalls.insert(CB);
1235 continue;
1236 }
1237
1238 // TODO: use the function scope once we have call site AAReturnedValues.
1239 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1240 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001241 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06001242 << RetValAA << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001243
1244 // Skip dead ends, thus if we do not know anything about the returned
1245 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001246 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001247 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1248 << "\n");
1249 UnresolvedCalls.insert(CB);
1250 continue;
1251 }
1252
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001253 // Do not try to learn partial information. If the callee has unresolved
1254 // return values we will treat the call as unresolved/opaque.
1255 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1256 if (!RetValAAUnresolvedCalls.empty()) {
1257 UnresolvedCalls.insert(CB);
1258 continue;
1259 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001260
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001261 // Now check if we can track transitively returned values. If possible, thus
1262 // if all return value can be represented in the current scope, do so.
1263 bool Unresolved = false;
1264 for (auto &RetValAAIt : RetValAA.returned_values()) {
1265 Value *RetVal = RetValAAIt.first;
1266 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1267 isa<Constant>(RetVal))
1268 continue;
1269 // Anything that did not fit in the above categories cannot be resolved,
1270 // mark the call as unresolved.
1271 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1272 "cannot be translated: "
1273 << *RetVal << "\n");
1274 UnresolvedCalls.insert(CB);
1275 Unresolved = true;
1276 break;
1277 }
1278
1279 if (Unresolved)
1280 continue;
1281
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001282 // Now track transitively returned values.
1283 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1284 if (NumRetAA == RetValAA.getNumReturnValues()) {
1285 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1286 "changed since it was seen last\n");
1287 continue;
1288 }
1289 NumRetAA = RetValAA.getNumReturnValues();
1290
Johannes Doerfertdef99282019-08-14 21:29:37 +00001291 for (auto &RetValAAIt : RetValAA.returned_values()) {
1292 Value *RetVal = RetValAAIt.first;
1293 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1294 // Arguments are mapped to call site operands and we begin the traversal
1295 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001296 bool Unused = false;
1297 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001298 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1299 continue;
1300 } else if (isa<CallBase>(RetVal)) {
1301 // Call sites are resolved by the callee attribute over time, no need to
1302 // do anything for us.
1303 continue;
1304 } else if (isa<Constant>(RetVal)) {
1305 // Constants are valid everywhere, we can simply take them.
1306 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1307 continue;
1308 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001309 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001310 }
1311
Johannes Doerfertdef99282019-08-14 21:29:37 +00001312 // To avoid modifications to the ReturnedValues map while we iterate over it
1313 // we kept record of potential new entries in a copy map, NewRVsMap.
1314 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001315 assert(!It.second.empty() && "Entry does not add anything.");
1316 auto &ReturnInsts = ReturnedValues[It.first];
1317 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001318 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001319 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1320 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001321 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001322 }
1323 }
1324
Johannes Doerfertdef99282019-08-14 21:29:37 +00001325 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1326 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001327}
1328
Johannes Doerfertdef99282019-08-14 21:29:37 +00001329struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1330 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1331
1332 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001333 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001334};
1335
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001336/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001337struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1338 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1339
1340 /// See AbstractAttribute::initialize(...).
1341 void initialize(Attributor &A) override {
1342 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001343 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001344 // sense to specialize attributes for call sites instead of
1345 // redirecting requests to the callee.
1346 llvm_unreachable("Abstract attributes for returned values are not "
1347 "supported for call sites yet!");
1348 }
1349
1350 /// See AbstractAttribute::updateImpl(...).
1351 ChangeStatus updateImpl(Attributor &A) override {
1352 return indicatePessimisticFixpoint();
1353 }
1354
1355 /// See AbstractAttribute::trackStatistics()
1356 void trackStatistics() const override {}
1357};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001358
Stefan Stipanovic06263672019-07-11 21:37:40 +00001359/// ------------------------ NoSync Function Attribute -------------------------
1360
Johannes Doerfert344d0382019-08-07 22:34:26 +00001361struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001362 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001363
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001364 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001365 return getAssumed() ? "nosync" : "may-sync";
1366 }
1367
1368 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001369 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001370
Stefan Stipanovic06263672019-07-11 21:37:40 +00001371 /// Helper function used to determine whether an instruction is non-relaxed
1372 /// atomic. In other words, if an atomic instruction does not have unordered
1373 /// or monotonic ordering
1374 static bool isNonRelaxedAtomic(Instruction *I);
1375
1376 /// Helper function used to determine whether an instruction is volatile.
1377 static bool isVolatile(Instruction *I);
1378
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001379 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1380 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001381 static bool isNoSyncIntrinsic(Instruction *I);
1382};
1383
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001384bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001385 if (!I->isAtomic())
1386 return false;
1387
1388 AtomicOrdering Ordering;
1389 switch (I->getOpcode()) {
1390 case Instruction::AtomicRMW:
1391 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1392 break;
1393 case Instruction::Store:
1394 Ordering = cast<StoreInst>(I)->getOrdering();
1395 break;
1396 case Instruction::Load:
1397 Ordering = cast<LoadInst>(I)->getOrdering();
1398 break;
1399 case Instruction::Fence: {
1400 auto *FI = cast<FenceInst>(I);
1401 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1402 return false;
1403 Ordering = FI->getOrdering();
1404 break;
1405 }
1406 case Instruction::AtomicCmpXchg: {
1407 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1408 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1409 // Only if both are relaxed, than it can be treated as relaxed.
1410 // Otherwise it is non-relaxed.
1411 if (Success != AtomicOrdering::Unordered &&
1412 Success != AtomicOrdering::Monotonic)
1413 return true;
1414 if (Failure != AtomicOrdering::Unordered &&
1415 Failure != AtomicOrdering::Monotonic)
1416 return true;
1417 return false;
1418 }
1419 default:
1420 llvm_unreachable(
1421 "New atomic operations need to be known in the attributor.");
1422 }
1423
1424 // Relaxed.
1425 if (Ordering == AtomicOrdering::Unordered ||
1426 Ordering == AtomicOrdering::Monotonic)
1427 return false;
1428 return true;
1429}
1430
1431/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1432/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001433bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001434 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1435 switch (II->getIntrinsicID()) {
1436 /// Element wise atomic memory intrinsics are can only be unordered,
1437 /// therefore nosync.
1438 case Intrinsic::memset_element_unordered_atomic:
1439 case Intrinsic::memmove_element_unordered_atomic:
1440 case Intrinsic::memcpy_element_unordered_atomic:
1441 return true;
1442 case Intrinsic::memset:
1443 case Intrinsic::memmove:
1444 case Intrinsic::memcpy:
1445 if (!cast<MemIntrinsic>(II)->isVolatile())
1446 return true;
1447 return false;
1448 default:
1449 return false;
1450 }
1451 }
1452 return false;
1453}
1454
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001455bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001456 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1457 "Calls should not be checked here");
1458
1459 switch (I->getOpcode()) {
1460 case Instruction::AtomicRMW:
1461 return cast<AtomicRMWInst>(I)->isVolatile();
1462 case Instruction::Store:
1463 return cast<StoreInst>(I)->isVolatile();
1464 case Instruction::Load:
1465 return cast<LoadInst>(I)->isVolatile();
1466 case Instruction::AtomicCmpXchg:
1467 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1468 default:
1469 return false;
1470 }
1471}
1472
Johannes Doerfertece81902019-08-12 22:05:53 +00001473ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001474
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001475 auto CheckRWInstForNoSync = [&](Instruction &I) {
1476 /// We are looking for volatile instructions or Non-Relaxed atomics.
Pankaj Godeb9a26a82019-11-22 14:46:43 +05301477 /// FIXME: We should improve the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001478
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001479 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1480 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001481
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001482 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1483 if (ICS.hasFnAttr(Attribute::NoSync))
1484 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001485
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001486 const auto &NoSyncAA =
1487 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1488 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001489 return true;
1490 return false;
1491 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001492
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001493 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1494 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001495
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001496 return false;
1497 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001498
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001499 auto CheckForNoSync = [&](Instruction &I) {
1500 // At this point we handled all read/write effects and they are all
1501 // nosync, so they can be skipped.
1502 if (I.mayReadOrWriteMemory())
1503 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001504
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001505 // non-convergent and readnone imply nosync.
1506 return !ImmutableCallSite(&I).isConvergent();
1507 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001508
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001509 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1510 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001511 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001512
Stefan Stipanovic06263672019-07-11 21:37:40 +00001513 return ChangeStatus::UNCHANGED;
1514}
1515
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001516struct AANoSyncFunction final : public AANoSyncImpl {
1517 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1518
1519 /// See AbstractAttribute::trackStatistics()
1520 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1521};
1522
1523/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001524struct AANoSyncCallSite final : AANoSyncImpl {
1525 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1526
1527 /// See AbstractAttribute::initialize(...).
1528 void initialize(Attributor &A) override {
1529 AANoSyncImpl::initialize(A);
1530 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001531 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001532 indicatePessimisticFixpoint();
1533 }
1534
1535 /// See AbstractAttribute::updateImpl(...).
1536 ChangeStatus updateImpl(Attributor &A) override {
1537 // TODO: Once we have call site specific value information we can provide
1538 // call site specific liveness information and then it makes
1539 // sense to specialize attributes for call sites arguments instead of
1540 // redirecting requests to the callee argument.
1541 Function *F = getAssociatedFunction();
1542 const IRPosition &FnPos = IRPosition::function(*F);
1543 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1544 return clampStateAndIndicateChange(
1545 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1546 }
1547
1548 /// See AbstractAttribute::trackStatistics()
1549 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1550};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001551
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001552/// ------------------------ No-Free Attributes ----------------------------
1553
Johannes Doerfert344d0382019-08-07 22:34:26 +00001554struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001555 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001556
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001557 /// See AbstractAttribute::updateImpl(...).
1558 ChangeStatus updateImpl(Attributor &A) override {
1559 auto CheckForNoFree = [&](Instruction &I) {
1560 ImmutableCallSite ICS(&I);
1561 if (ICS.hasFnAttr(Attribute::NoFree))
1562 return true;
1563
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001564 const auto &NoFreeAA =
1565 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1566 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001567 };
1568
1569 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1570 return indicatePessimisticFixpoint();
1571 return ChangeStatus::UNCHANGED;
1572 }
1573
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001574 /// See AbstractAttribute::getAsStr().
1575 const std::string getAsStr() const override {
1576 return getAssumed() ? "nofree" : "may-free";
1577 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001578};
1579
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001580struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001581 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001582
1583 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001584 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001585};
1586
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001587/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001588struct AANoFreeCallSite final : AANoFreeImpl {
1589 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1590
1591 /// See AbstractAttribute::initialize(...).
1592 void initialize(Attributor &A) override {
1593 AANoFreeImpl::initialize(A);
1594 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001595 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001596 indicatePessimisticFixpoint();
1597 }
1598
1599 /// See AbstractAttribute::updateImpl(...).
1600 ChangeStatus updateImpl(Attributor &A) override {
1601 // TODO: Once we have call site specific value information we can provide
1602 // call site specific liveness information and then it makes
1603 // sense to specialize attributes for call sites arguments instead of
1604 // redirecting requests to the callee argument.
1605 Function *F = getAssociatedFunction();
1606 const IRPosition &FnPos = IRPosition::function(*F);
1607 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1608 return clampStateAndIndicateChange(
1609 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1610 }
1611
1612 /// See AbstractAttribute::trackStatistics()
1613 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1614};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001615
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001616/// NoFree attribute for floating values.
1617struct AANoFreeFloating : AANoFreeImpl {
1618 AANoFreeFloating(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1619
1620 /// See AbstractAttribute::trackStatistics()
1621 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
1622
1623 /// See Abstract Attribute::updateImpl(...).
1624 ChangeStatus updateImpl(Attributor &A) override {
1625 const IRPosition &IRP = getIRPosition();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001626
1627 const auto &NoFreeAA =
1628 A.getAAFor<AANoFree>(*this, IRPosition::function_scope(IRP));
1629 if (NoFreeAA.isAssumedNoFree())
1630 return ChangeStatus::UNCHANGED;
1631
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001632 Value &AssociatedValue = getIRPosition().getAssociatedValue();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001633 auto Pred = [&](const Use &U, bool &Follow) -> bool {
1634 Instruction *UserI = cast<Instruction>(U.getUser());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001635 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001636 if (CB->isBundleOperand(&U))
1637 return false;
1638 if (!CB->isArgOperand(&U))
1639 return true;
1640 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001641
1642 const auto &NoFreeArg = A.getAAFor<AANoFree>(
1643 *this, IRPosition::callsite_argument(*CB, ArgNo));
Hideto Ueno63599bd2019-12-12 12:26:09 +00001644 return NoFreeArg.isAssumedNoFree();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001645 }
1646
1647 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
1648 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001649 Follow = true;
1650 return true;
Hideto Ueno4ecf2552019-12-12 13:42:40 +00001651 }
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001652
1653 // Unknown user.
Hideto Ueno63599bd2019-12-12 12:26:09 +00001654 return false;
1655 };
1656 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001657 return indicatePessimisticFixpoint();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001658
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001659 return ChangeStatus::UNCHANGED;
1660 }
1661};
1662
1663/// NoFree attribute for a call site argument.
1664struct AANoFreeArgument final : AANoFreeFloating {
1665 AANoFreeArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1666
1667 /// See AbstractAttribute::trackStatistics()
1668 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
1669};
1670
1671/// NoFree attribute for call site arguments.
1672struct AANoFreeCallSiteArgument final : AANoFreeFloating {
1673 AANoFreeCallSiteArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1674
1675 /// See AbstractAttribute::updateImpl(...).
1676 ChangeStatus updateImpl(Attributor &A) override {
1677 // TODO: Once we have call site specific value information we can provide
1678 // call site specific liveness information and then it makes
1679 // sense to specialize attributes for call sites arguments instead of
1680 // redirecting requests to the callee argument.
1681 Argument *Arg = getAssociatedArgument();
1682 if (!Arg)
1683 return indicatePessimisticFixpoint();
1684 const IRPosition &ArgPos = IRPosition::argument(*Arg);
1685 auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
1686 return clampStateAndIndicateChange(
1687 getState(), static_cast<const AANoFree::StateType &>(ArgAA.getState()));
1688 }
1689
1690 /// See AbstractAttribute::trackStatistics()
1691 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
1692};
1693
1694/// NoFree attribute for function return value.
1695struct AANoFreeReturned final : AANoFreeFloating {
1696 AANoFreeReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {
1697 llvm_unreachable("NoFree is not applicable to function returns!");
1698 }
1699
1700 /// See AbstractAttribute::initialize(...).
1701 void initialize(Attributor &A) override {
1702 llvm_unreachable("NoFree is not applicable to function returns!");
1703 }
1704
1705 /// See AbstractAttribute::updateImpl(...).
1706 ChangeStatus updateImpl(Attributor &A) override {
1707 llvm_unreachable("NoFree is not applicable to function returns!");
1708 }
1709
1710 /// See AbstractAttribute::trackStatistics()
1711 void trackStatistics() const override {}
1712};
1713
1714/// NoFree attribute deduction for a call site return value.
1715struct AANoFreeCallSiteReturned final : AANoFreeFloating {
1716 AANoFreeCallSiteReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1717
1718 ChangeStatus manifest(Attributor &A) override {
1719 return ChangeStatus::UNCHANGED;
1720 }
1721 /// See AbstractAttribute::trackStatistics()
1722 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
1723};
1724
Hideto Ueno54869ec2019-07-15 06:49:04 +00001725/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001726static int64_t getKnownNonNullAndDerefBytesForUse(
1727 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1728 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001729 TrackUse = false;
1730
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001731 const Value *UseV = U->get();
1732 if (!UseV->getType()->isPointerTy())
1733 return 0;
1734
1735 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001736 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001737 bool NullPointerIsDefined =
1738 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001739 const DataLayout &DL = A.getInfoCache().getDL();
1740 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1741 if (ICS.isBundleOperand(U))
1742 return 0;
1743
1744 if (ICS.isCallee(U)) {
1745 IsNonNull |= !NullPointerIsDefined;
1746 return 0;
1747 }
1748
1749 unsigned ArgNo = ICS.getArgumentNo(U);
1750 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001751 // As long as we only use known information there is no need to track
1752 // dependences here.
1753 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP,
1754 /* TrackDependence */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001755 IsNonNull |= DerefAA.isKnownNonNull();
1756 return DerefAA.getKnownDereferenceableBytes();
1757 }
1758
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001759 // We need to follow common pointer manipulation uses to the accesses they
1760 // feed into. We can try to be smart to avoid looking through things we do not
1761 // like for now, e.g., non-inbounds GEPs.
1762 if (isa<CastInst>(I)) {
1763 TrackUse = true;
1764 return 0;
1765 }
1766 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001767 if (GEP->hasAllConstantIndices()) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001768 TrackUse = true;
1769 return 0;
1770 }
1771
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001772 int64_t Offset;
1773 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09001774 if (Base == &AssociatedValue &&
1775 Attributor::getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001776 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001777 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001778
1779 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001780 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001781 }
1782 }
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001783
1784 /// Corner case when an offset is 0.
1785 if (const Value *Base = getBasePointerOfAccessPointerOperand(
1786 I, Offset, DL, /*AllowNonInbounds*/ true)) {
1787 if (Offset == 0 && Base == &AssociatedValue &&
Hideto Uenoef4febd2019-12-29 17:34:08 +09001788 Attributor::getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001789 int64_t DerefBytes =
1790 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType());
1791 IsNonNull |= !NullPointerIsDefined;
1792 return std::max(int64_t(0), DerefBytes);
1793 }
1794 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001795
1796 return 0;
1797}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001798
Johannes Doerfert344d0382019-08-07 22:34:26 +00001799struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001800 AANonNullImpl(const IRPosition &IRP)
1801 : AANonNull(IRP),
1802 NullIsDefined(NullPointerIsDefined(
1803 getAnchorScope(),
1804 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001805
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001806 /// See AbstractAttribute::initialize(...).
1807 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001808 if (!NullIsDefined &&
1809 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001810 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001811 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1812 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001813 else
1814 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001815 }
1816
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001817 /// See AAFromMustBeExecutedContext
1818 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1819 bool IsNonNull = false;
1820 bool TrackUse = false;
1821 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1822 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001823 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001824 return TrackUse;
1825 }
1826
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001827 /// See AbstractAttribute::getAsStr().
1828 const std::string getAsStr() const override {
1829 return getAssumed() ? "nonnull" : "may-null";
1830 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001831
1832 /// Flag to determine if the underlying value can be null and still allow
1833 /// valid accesses.
1834 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001835};
1836
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001837/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001838struct AANonNullFloating
1839 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1840 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1841 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001842
Hideto Ueno54869ec2019-07-15 06:49:04 +00001843 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001844 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001845 ChangeStatus Change = Base::updateImpl(A);
1846 if (isKnownNonNull())
1847 return Change;
1848
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001849 if (!NullIsDefined) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001850 const auto &DerefAA =
1851 A.getAAFor<AADereferenceable>(*this, getIRPosition());
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001852 if (DerefAA.getAssumedDereferenceableBytes())
1853 return Change;
1854 }
1855
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001856 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001857
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001858 DominatorTree *DT = nullptr;
1859 InformationCache &InfoCache = A.getInfoCache();
1860 if (const Function *Fn = getAnchorScope())
1861 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
1862
Johannes Doerfert1a746452019-10-20 22:28:49 -05001863 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001864 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001865 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1866 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001867 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001868 T.indicatePessimisticFixpoint();
1869 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001870 // Use abstract attribute information.
1871 const AANonNull::StateType &NS =
1872 static_cast<const AANonNull::StateType &>(AA.getState());
1873 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001874 }
1875 return T.isValidState();
1876 };
1877
1878 StateType T;
1879 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1880 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001881 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001882
1883 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001884 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001885
1886 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001887 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001888};
1889
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001890/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001891struct AANonNullReturned final
1892 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001893 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001894 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001895
1896 /// See AbstractAttribute::trackStatistics()
1897 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1898};
1899
Hideto Ueno54869ec2019-07-15 06:49:04 +00001900/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001901struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001902 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1903 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001904 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001905 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1906 AANonNullImpl>(
1907 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001908
1909 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001910 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001911};
1912
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001913struct AANonNullCallSiteArgument final : AANonNullFloating {
1914 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001915
1916 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001917 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001918};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001919
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001920/// NonNull attribute for a call site return position.
1921struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001922 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1923 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001924 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001925 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1926 AANonNullImpl>(
1927 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001928
1929 /// See AbstractAttribute::trackStatistics()
1930 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1931};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001932
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001933/// ------------------------ No-Recurse Attributes ----------------------------
1934
1935struct AANoRecurseImpl : public AANoRecurse {
1936 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1937
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001938 /// See AbstractAttribute::getAsStr()
1939 const std::string getAsStr() const override {
1940 return getAssumed() ? "norecurse" : "may-recurse";
1941 }
1942};
1943
1944struct AANoRecurseFunction final : AANoRecurseImpl {
1945 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1946
Hideto Ueno63f60662019-09-21 15:13:19 +00001947 /// See AbstractAttribute::initialize(...).
1948 void initialize(Attributor &A) override {
1949 AANoRecurseImpl::initialize(A);
1950 if (const Function *F = getAnchorScope())
1951 if (A.getInfoCache().getSccSize(*F) == 1)
1952 return;
1953 indicatePessimisticFixpoint();
1954 }
1955
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001956 /// See AbstractAttribute::updateImpl(...).
1957 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00001958
1959 auto CheckForNoRecurse = [&](Instruction &I) {
1960 ImmutableCallSite ICS(&I);
1961 if (ICS.hasFnAttr(Attribute::NoRecurse))
1962 return true;
1963
1964 const auto &NoRecurseAA =
1965 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
1966 if (!NoRecurseAA.isAssumedNoRecurse())
1967 return false;
1968
1969 // Recursion to the same function
1970 if (ICS.getCalledFunction() == getAnchorScope())
1971 return false;
1972
1973 return true;
1974 };
1975
1976 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
1977 return indicatePessimisticFixpoint();
1978 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001979 }
1980
1981 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1982};
1983
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001984/// NoRecurse attribute deduction for a call sites.
1985struct AANoRecurseCallSite final : AANoRecurseImpl {
1986 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1987
1988 /// See AbstractAttribute::initialize(...).
1989 void initialize(Attributor &A) override {
1990 AANoRecurseImpl::initialize(A);
1991 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001992 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001993 indicatePessimisticFixpoint();
1994 }
1995
1996 /// See AbstractAttribute::updateImpl(...).
1997 ChangeStatus updateImpl(Attributor &A) override {
1998 // TODO: Once we have call site specific value information we can provide
1999 // call site specific liveness information and then it makes
2000 // sense to specialize attributes for call sites arguments instead of
2001 // redirecting requests to the callee argument.
2002 Function *F = getAssociatedFunction();
2003 const IRPosition &FnPos = IRPosition::function(*F);
2004 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
2005 return clampStateAndIndicateChange(
2006 getState(),
2007 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
2008 }
2009
2010 /// See AbstractAttribute::trackStatistics()
2011 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2012};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002013
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002014/// -------------------- Undefined-Behavior Attributes ------------------------
2015
2016struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2017 AAUndefinedBehaviorImpl(const IRPosition &IRP) : AAUndefinedBehavior(IRP) {}
2018
2019 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert5732f562019-12-24 19:25:08 -06002020 // through a pointer (i.e. also branches etc.)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002021 ChangeStatus updateImpl(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002022 const size_t UBPrevSize = KnownUBInsts.size();
2023 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002024
Johannes Doerfert5732f562019-12-24 19:25:08 -06002025 auto InspectMemAccessInstForUB = [&](Instruction &I) {
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002026 // Skip instructions that are already saved.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002027 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002028 return true;
2029
Hideto Uenoef4febd2019-12-29 17:34:08 +09002030 // If we reach here, we know we have an instruction
2031 // that accesses memory through a pointer operand,
2032 // for which getPointerOperand() should give it to us.
2033 const Value *PtrOp =
2034 Attributor::getPointerOperand(&I, /* AllowVolatile */ true);
2035 assert(PtrOp &&
2036 "Expected pointer operand of memory accessing instruction");
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002037
Johannes Doerfert5732f562019-12-24 19:25:08 -06002038 // A memory access through a pointer is considered UB
2039 // only if the pointer has constant null value.
2040 // TODO: Expand it to not only check constant values.
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002041 if (!isa<ConstantPointerNull>(PtrOp)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002042 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002043 return true;
2044 }
Johannes Doerfert5732f562019-12-24 19:25:08 -06002045 const Type *PtrTy = PtrOp->getType();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002046
Johannes Doerfert5732f562019-12-24 19:25:08 -06002047 // Because we only consider instructions inside functions,
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002048 // assume that a parent function exists.
2049 const Function *F = I.getFunction();
2050
Johannes Doerfert5732f562019-12-24 19:25:08 -06002051 // A memory access using constant null pointer is only considered UB
2052 // if null pointer is _not_ defined for the target platform.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002053 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()))
2054 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002055 else
Hideto Uenoef4febd2019-12-29 17:34:08 +09002056 KnownUBInsts.insert(&I);
2057 return true;
2058 };
2059
2060 auto InspectBrInstForUB = [&](Instruction &I) {
2061 // A conditional branch instruction is considered UB if it has `undef`
2062 // condition.
2063
2064 // Skip instructions that are already saved.
2065 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2066 return true;
2067
2068 // We know we have a branch instruction.
2069 auto BrInst = cast<BranchInst>(&I);
2070
2071 // Unconditional branches are never considered UB.
2072 if (BrInst->isUnconditional())
2073 return true;
2074
2075 // Either we stopped and the appropriate action was taken,
2076 // or we got back a simplified value to continue.
2077 Optional<Value *> SimplifiedCond =
2078 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2079 if (!SimplifiedCond.hasValue())
2080 return true;
2081 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002082 return true;
2083 };
2084
Johannes Doerfert5732f562019-12-24 19:25:08 -06002085 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
2086 {Instruction::Load, Instruction::Store,
2087 Instruction::AtomicCmpXchg,
2088 Instruction::AtomicRMW});
Hideto Uenoef4febd2019-12-29 17:34:08 +09002089 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br});
2090 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
2091 UBPrevSize != KnownUBInsts.size())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002092 return ChangeStatus::CHANGED;
2093 return ChangeStatus::UNCHANGED;
2094 }
2095
Hideto Uenoef4febd2019-12-29 17:34:08 +09002096 bool isKnownToCauseUB(Instruction *I) const override {
2097 return KnownUBInsts.count(I);
2098 }
2099
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002100 bool isAssumedToCauseUB(Instruction *I) const override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002101 // In simple words, if an instruction is not in the assumed to _not_
2102 // cause UB, then it is assumed UB (that includes those
2103 // in the KnownUBInsts set). The rest is boilerplate
2104 // is to ensure that it is one of the instructions we test
2105 // for UB.
2106
2107 switch (I->getOpcode()) {
2108 case Instruction::Load:
2109 case Instruction::Store:
2110 case Instruction::AtomicCmpXchg:
2111 case Instruction::AtomicRMW:
2112 return !AssumedNoUBInsts.count(I);
2113 case Instruction::Br: {
2114 auto BrInst = cast<BranchInst>(I);
2115 if (BrInst->isUnconditional())
2116 return false;
2117 return !AssumedNoUBInsts.count(I);
2118 } break;
2119 default:
2120 return false;
2121 }
2122 return false;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002123 }
2124
2125 ChangeStatus manifest(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002126 if (KnownUBInsts.empty())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002127 return ChangeStatus::UNCHANGED;
Hideto Uenoef4febd2019-12-29 17:34:08 +09002128 for (Instruction *I : KnownUBInsts)
Hideto Uenocb5eb132019-12-27 02:39:37 +09002129 A.changeToUnreachableAfterManifest(I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002130 return ChangeStatus::CHANGED;
2131 }
2132
2133 /// See AbstractAttribute::getAsStr()
2134 const std::string getAsStr() const override {
2135 return getAssumed() ? "undefined-behavior" : "no-ub";
2136 }
2137
Hideto Uenoef4febd2019-12-29 17:34:08 +09002138 /// Note: The correctness of this analysis depends on the fact that the
2139 /// following 2 sets will stop changing after some point.
2140 /// "Change" here means that their size changes.
2141 /// The size of each set is monotonically increasing
2142 /// (we only add items to them) and it is upper bounded by the number of
2143 /// instructions in the processed function (we can never save more
2144 /// elements in either set than this number). Hence, at some point,
2145 /// they will stop increasing.
2146 /// Consequently, at some point, both sets will have stopped
2147 /// changing, effectively making the analysis reach a fixpoint.
2148
2149 /// Note: These 2 sets are disjoint and an instruction can be considered
2150 /// one of 3 things:
2151 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
2152 /// the KnownUBInsts set.
2153 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
2154 /// has a reason to assume it).
2155 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
2156 /// could not find a reason to assume or prove that it can cause UB,
2157 /// hence it assumes it doesn't. We have a set for these instructions
2158 /// so that we don't reprocess them in every update.
2159 /// Note however that instructions in this set may cause UB.
2160
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002161protected:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002162 /// A set of all live instructions _known_ to cause UB.
2163 SmallPtrSet<Instruction *, 8> KnownUBInsts;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002164
2165private:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002166 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
2167 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
2168
2169 // Should be called on updates in which if we're processing an instruction
2170 // \p I that depends on a value \p V, one of the following has to happen:
2171 // - If the value is assumed, then stop.
2172 // - If the value is known but undef, then consider it UB.
2173 // - Otherwise, do specific processing with the simplified value.
2174 // We return None in the first 2 cases to signify that an appropriate
2175 // action was taken and the caller should stop.
2176 // Otherwise, we return the simplified value that the caller should
2177 // use for specific processing.
2178 Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
2179 Instruction *I) {
2180 const auto &ValueSimplifyAA =
2181 A.getAAFor<AAValueSimplify>(*this, IRPosition::value(*V));
2182 Optional<Value *> SimplifiedV =
2183 ValueSimplifyAA.getAssumedSimplifiedValue(A);
2184 if (!ValueSimplifyAA.isKnown()) {
2185 // Don't depend on assumed values.
2186 return llvm::None;
2187 }
2188 if (!SimplifiedV.hasValue()) {
2189 // If it is known (which we tested above) but it doesn't have a value,
2190 // then we can assume `undef` and hence the instruction is UB.
2191 KnownUBInsts.insert(I);
2192 return llvm::None;
2193 }
2194 Value *Val = SimplifiedV.getValue();
2195 if (isa<UndefValue>(Val)) {
2196 KnownUBInsts.insert(I);
2197 return llvm::None;
2198 }
2199 return Val;
2200 }
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002201};
2202
2203struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
2204 AAUndefinedBehaviorFunction(const IRPosition &IRP)
2205 : AAUndefinedBehaviorImpl(IRP) {}
2206
2207 /// See AbstractAttribute::trackStatistics()
2208 void trackStatistics() const override {
2209 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
2210 "Number of instructions known to have UB");
2211 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
Hideto Uenoef4febd2019-12-29 17:34:08 +09002212 KnownUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002213 }
2214};
2215
Hideto Ueno11d37102019-07-17 15:15:43 +00002216/// ------------------------ Will-Return Attributes ----------------------------
2217
Hideto Ueno11d37102019-07-17 15:15:43 +00002218// Helper function that checks whether a function has any cycle.
2219// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002220static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00002221 SmallPtrSet<BasicBlock *, 32> Visited;
2222
2223 // Traverse BB by dfs and check whether successor is already visited.
2224 for (BasicBlock *BB : depth_first(&F)) {
2225 Visited.insert(BB);
2226 for (auto *SuccBB : successors(BB)) {
2227 if (Visited.count(SuccBB))
2228 return true;
2229 }
2230 }
2231 return false;
2232}
2233
2234// Helper function that checks the function have a loop which might become an
2235// endless loop
2236// FIXME: Any cycle is regarded as endless loop for now.
2237// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002238static bool containsPossiblyEndlessLoop(Function *F) {
2239 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00002240}
2241
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002242struct AAWillReturnImpl : public AAWillReturn {
2243 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00002244
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002245 /// See AbstractAttribute::initialize(...).
2246 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002247 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00002248
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002249 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002250 if (containsPossiblyEndlessLoop(F))
2251 indicatePessimisticFixpoint();
2252 }
Hideto Ueno11d37102019-07-17 15:15:43 +00002253
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002254 /// See AbstractAttribute::updateImpl(...).
2255 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002256 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002257 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
2258 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
2259 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002260 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002261 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002262 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002263 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
2264 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002265 };
2266
2267 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
2268 return indicatePessimisticFixpoint();
2269
2270 return ChangeStatus::UNCHANGED;
2271 }
2272
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002273 /// See AbstractAttribute::getAsStr()
2274 const std::string getAsStr() const override {
2275 return getAssumed() ? "willreturn" : "may-noreturn";
2276 }
2277};
2278
2279struct AAWillReturnFunction final : AAWillReturnImpl {
2280 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2281
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002282 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002283 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002284};
Hideto Ueno11d37102019-07-17 15:15:43 +00002285
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002286/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002287struct AAWillReturnCallSite final : AAWillReturnImpl {
2288 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2289
2290 /// See AbstractAttribute::initialize(...).
2291 void initialize(Attributor &A) override {
2292 AAWillReturnImpl::initialize(A);
2293 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002294 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002295 indicatePessimisticFixpoint();
2296 }
2297
2298 /// See AbstractAttribute::updateImpl(...).
2299 ChangeStatus updateImpl(Attributor &A) override {
2300 // TODO: Once we have call site specific value information we can provide
2301 // call site specific liveness information and then it makes
2302 // sense to specialize attributes for call sites arguments instead of
2303 // redirecting requests to the callee argument.
2304 Function *F = getAssociatedFunction();
2305 const IRPosition &FnPos = IRPosition::function(*F);
2306 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
2307 return clampStateAndIndicateChange(
2308 getState(),
2309 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
2310 }
2311
2312 /// See AbstractAttribute::trackStatistics()
2313 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
2314};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002315
Pankaj Gode04945c92019-11-22 18:40:47 +05302316/// -------------------AAReachability Attribute--------------------------
2317
2318struct AAReachabilityImpl : AAReachability {
2319 AAReachabilityImpl(const IRPosition &IRP) : AAReachability(IRP) {}
2320
2321 const std::string getAsStr() const override {
2322 // TODO: Return the number of reachable queries.
2323 return "reachable";
2324 }
2325
2326 /// See AbstractAttribute::initialize(...).
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002327 void initialize(Attributor &A) override { indicatePessimisticFixpoint(); }
Pankaj Gode04945c92019-11-22 18:40:47 +05302328
2329 /// See AbstractAttribute::updateImpl(...).
2330 ChangeStatus updateImpl(Attributor &A) override {
2331 return indicatePessimisticFixpoint();
2332 }
2333};
2334
2335struct AAReachabilityFunction final : public AAReachabilityImpl {
2336 AAReachabilityFunction(const IRPosition &IRP) : AAReachabilityImpl(IRP) {}
2337
2338 /// See AbstractAttribute::trackStatistics()
2339 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); }
2340};
2341
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002342/// ------------------------ NoAlias Argument Attribute ------------------------
2343
Johannes Doerfert344d0382019-08-07 22:34:26 +00002344struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002345 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002346
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002347 const std::string getAsStr() const override {
2348 return getAssumed() ? "noalias" : "may-alias";
2349 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002350};
2351
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002352/// NoAlias attribute for a floating value.
2353struct AANoAliasFloating final : AANoAliasImpl {
2354 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2355
Hideto Uenocbab3342019-08-29 05:52:00 +00002356 /// See AbstractAttribute::initialize(...).
2357 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002358 AANoAliasImpl::initialize(A);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002359 Value &Val = getAssociatedValue();
2360 if (isa<AllocaInst>(Val))
2361 indicateOptimisticFixpoint();
2362 if (isa<ConstantPointerNull>(Val) &&
2363 Val.getType()->getPointerAddressSpace() == 0)
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002364 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002365 }
2366
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002367 /// See AbstractAttribute::updateImpl(...).
2368 ChangeStatus updateImpl(Attributor &A) override {
2369 // TODO: Implement this.
2370 return indicatePessimisticFixpoint();
2371 }
2372
2373 /// See AbstractAttribute::trackStatistics()
2374 void trackStatistics() const override {
2375 STATS_DECLTRACK_FLOATING_ATTR(noalias)
2376 }
2377};
2378
2379/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00002380struct AANoAliasArgument final
2381 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002382 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
2383 AANoAliasArgument(const IRPosition &IRP) : Base(IRP) {}
2384
2385 /// See AbstractAttribute::update(...).
2386 ChangeStatus updateImpl(Attributor &A) override {
2387 // We have to make sure no-alias on the argument does not break
2388 // synchronization when this is a callback argument, see also [1] below.
2389 // If synchronization cannot be affected, we delegate to the base updateImpl
2390 // function, otherwise we give up for now.
2391
2392 // If the function is no-sync, no-alias cannot break synchronization.
2393 const auto &NoSyncAA = A.getAAFor<AANoSync>(
2394 *this, IRPosition::function_scope(getIRPosition()));
2395 if (NoSyncAA.isAssumedNoSync())
2396 return Base::updateImpl(A);
2397
2398 // If the argument is read-only, no-alias cannot break synchronization.
2399 const auto &MemBehaviorAA =
2400 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
2401 if (MemBehaviorAA.isAssumedReadOnly())
2402 return Base::updateImpl(A);
2403
2404 // If the argument is never passed through callbacks, no-alias cannot break
2405 // synchronization.
2406 if (A.checkForAllCallSites(
2407 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
2408 true))
2409 return Base::updateImpl(A);
2410
2411 // TODO: add no-alias but make sure it doesn't break synchronization by
2412 // introducing fake uses. See:
2413 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
2414 // International Workshop on OpenMP 2018,
2415 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
2416
2417 return indicatePessimisticFixpoint();
2418 }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002419
2420 /// See AbstractAttribute::trackStatistics()
2421 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
2422};
2423
2424struct AANoAliasCallSiteArgument final : AANoAliasImpl {
2425 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2426
Hideto Uenocbab3342019-08-29 05:52:00 +00002427 /// See AbstractAttribute::initialize(...).
2428 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00002429 // See callsite argument attribute and callee argument attribute.
2430 ImmutableCallSite ICS(&getAnchorValue());
2431 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
2432 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002433 }
2434
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002435 /// See AbstractAttribute::updateImpl(...).
2436 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002437 // We can deduce "noalias" if the following conditions hold.
2438 // (i) Associated value is assumed to be noalias in the definition.
2439 // (ii) Associated value is assumed to be no-capture in all the uses
2440 // possibly executed before this callsite.
2441 // (iii) There is no other pointer argument which could alias with the
2442 // value.
2443
2444 const Value &V = getAssociatedValue();
2445 const IRPosition IRP = IRPosition::value(V);
2446
2447 // (i) Check whether noalias holds in the definition.
2448
2449 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002450 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] check definition: " << V
2451 << " :: " << NoAliasAA << "\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002452
2453 if (!NoAliasAA.isAssumedNoAlias())
2454 return indicatePessimisticFixpoint();
2455
2456 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
2457 << " is assumed NoAlias in the definition\n");
2458
2459 // (ii) Check whether the value is captured in the scope using AANoCapture.
2460 // FIXME: This is conservative though, it is better to look at CFG and
2461 // check only uses possibly executed before this callsite.
2462
2463 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002464 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2465 LLVM_DEBUG(
2466 dbgs() << "[Attributor][AANoAliasCSArg] " << V
2467 << " cannot be noalias as it is potentially captured\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002468 return indicatePessimisticFixpoint();
Johannes Doerfert72adda12019-10-10 05:33:21 +00002469 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002470
2471 // (iii) Check there is no other pointer argument which could alias with the
2472 // value.
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002473 // TODO: AbstractCallSite
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002474 ImmutableCallSite ICS(&getAnchorValue());
2475 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
2476 if (getArgNo() == (int)i)
2477 continue;
2478 const Value *ArgOp = ICS.getArgOperand(i);
2479 if (!ArgOp->getType()->isPointerTy())
2480 continue;
2481
Hideto Ueno30d86f12019-09-17 06:53:27 +00002482 if (const Function *F = getAnchorScope()) {
2483 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002484 bool IsAliasing = !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
Hideto Ueno30d86f12019-09-17 06:53:27 +00002485 LLVM_DEBUG(dbgs()
2486 << "[Attributor][NoAliasCSArg] Check alias between "
2487 "callsite arguments "
2488 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
Johannes Doerfert72adda12019-10-10 05:33:21 +00002489 << getAssociatedValue() << " " << *ArgOp << " => "
2490 << (IsAliasing ? "" : "no-") << "alias \n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002491
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002492 if (!IsAliasing)
Hideto Ueno30d86f12019-09-17 06:53:27 +00002493 continue;
2494 }
2495 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002496 return indicatePessimisticFixpoint();
2497 }
2498
2499 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002500 }
2501
2502 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002503 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002504};
2505
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002506/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002507struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002508 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002509
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002510 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002511 virtual ChangeStatus updateImpl(Attributor &A) override {
2512
2513 auto CheckReturnValue = [&](Value &RV) -> bool {
2514 if (Constant *C = dyn_cast<Constant>(&RV))
2515 if (C->isNullValue() || isa<UndefValue>(C))
2516 return true;
2517
2518 /// For now, we can only deduce noalias if we have call sites.
2519 /// FIXME: add more support.
2520 ImmutableCallSite ICS(&RV);
2521 if (!ICS)
2522 return false;
2523
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002524 const IRPosition &RVPos = IRPosition::value(RV);
2525 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002526 if (!NoAliasAA.isAssumedNoAlias())
2527 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002528
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002529 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2530 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002531 };
2532
2533 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2534 return indicatePessimisticFixpoint();
2535
2536 return ChangeStatus::UNCHANGED;
2537 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002538
2539 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002540 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002541};
2542
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002543/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002544struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2545 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2546
2547 /// See AbstractAttribute::initialize(...).
2548 void initialize(Attributor &A) override {
2549 AANoAliasImpl::initialize(A);
2550 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002551 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002552 indicatePessimisticFixpoint();
2553 }
2554
2555 /// See AbstractAttribute::updateImpl(...).
2556 ChangeStatus updateImpl(Attributor &A) override {
2557 // TODO: Once we have call site specific value information we can provide
2558 // call site specific liveness information and then it makes
2559 // sense to specialize attributes for call sites arguments instead of
2560 // redirecting requests to the callee argument.
2561 Function *F = getAssociatedFunction();
2562 const IRPosition &FnPos = IRPosition::returned(*F);
2563 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2564 return clampStateAndIndicateChange(
2565 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2566 }
2567
2568 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002569 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002570};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002571
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002572/// -------------------AAIsDead Function Attribute-----------------------
2573
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002574struct AAIsDeadValueImpl : public AAIsDead {
2575 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002576
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002577 /// See AAIsDead::isAssumedDead().
2578 bool isAssumedDead() const override { return getAssumed(); }
2579
2580 /// See AAIsDead::isAssumedDead(BasicBlock *).
2581 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2582
2583 /// See AAIsDead::isKnownDead(BasicBlock *).
2584 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2585
2586 /// See AAIsDead::isAssumedDead(Instruction *I).
2587 bool isAssumedDead(const Instruction *I) const override {
2588 return I == getCtxI() && isAssumedDead();
2589 }
2590
2591 /// See AAIsDead::isKnownDead(Instruction *I).
2592 bool isKnownDead(const Instruction *I) const override {
2593 return I == getCtxI() && getKnown();
2594 }
2595
2596 /// See AbstractAttribute::getAsStr().
2597 const std::string getAsStr() const override {
2598 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2599 }
2600};
2601
2602struct AAIsDeadFloating : public AAIsDeadValueImpl {
2603 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2604
2605 /// See AbstractAttribute::initialize(...).
2606 void initialize(Attributor &A) override {
2607 if (Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()))
2608 if (!wouldInstructionBeTriviallyDead(I))
2609 indicatePessimisticFixpoint();
2610 if (isa<UndefValue>(getAssociatedValue()))
2611 indicatePessimisticFixpoint();
2612 }
2613
2614 /// See AbstractAttribute::updateImpl(...).
2615 ChangeStatus updateImpl(Attributor &A) override {
2616 auto UsePred = [&](const Use &U, bool &Follow) {
2617 Instruction *UserI = cast<Instruction>(U.getUser());
2618 if (CallSite CS = CallSite(UserI)) {
2619 if (!CS.isArgOperand(&U))
2620 return false;
2621 const IRPosition &CSArgPos =
2622 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
2623 const auto &CSArgIsDead = A.getAAFor<AAIsDead>(*this, CSArgPos);
2624 return CSArgIsDead.isAssumedDead();
2625 }
2626 if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
2627 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
2628 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, RetPos);
2629 return RetIsDeadAA.isAssumedDead();
2630 }
2631 Follow = true;
2632 return wouldInstructionBeTriviallyDead(UserI);
2633 };
2634
2635 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
2636 return indicatePessimisticFixpoint();
2637 return ChangeStatus::UNCHANGED;
2638 }
2639
2640 /// See AbstractAttribute::manifest(...).
2641 ChangeStatus manifest(Attributor &A) override {
2642 Value &V = getAssociatedValue();
2643 if (auto *I = dyn_cast<Instruction>(&V))
2644 if (wouldInstructionBeTriviallyDead(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002645 A.deleteAfterManifest(*I);
2646 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002647 }
2648
2649 if (V.use_empty())
2650 return ChangeStatus::UNCHANGED;
2651
2652 UndefValue &UV = *UndefValue::get(V.getType());
Hideto Ueno34fe8d02019-12-30 17:08:48 +09002653 bool AnyChange = A.changeValueAfterManifest(V, UV);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002654 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2655 }
2656
2657 /// See AbstractAttribute::trackStatistics()
2658 void trackStatistics() const override {
2659 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2660 }
2661};
2662
2663struct AAIsDeadArgument : public AAIsDeadFloating {
2664 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2665
2666 /// See AbstractAttribute::initialize(...).
2667 void initialize(Attributor &A) override {
2668 if (!getAssociatedFunction()->hasExactDefinition())
2669 indicatePessimisticFixpoint();
2670 }
2671
Johannes Doerfert75133632019-10-10 01:39:16 -05002672 /// See AbstractAttribute::manifest(...).
2673 ChangeStatus manifest(Attributor &A) override {
2674 ChangeStatus Changed = AAIsDeadFloating::manifest(A);
2675 Argument &Arg = *getAssociatedArgument();
2676 if (Arg.getParent()->hasLocalLinkage())
2677 if (A.registerFunctionSignatureRewrite(
2678 Arg, /* ReplacementTypes */ {},
2679 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{},
2680 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{}))
2681 return ChangeStatus::CHANGED;
2682 return Changed;
2683 }
2684
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002685 /// See AbstractAttribute::trackStatistics()
2686 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2687};
2688
2689struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2690 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2691
2692 /// See AbstractAttribute::initialize(...).
2693 void initialize(Attributor &A) override {
2694 if (isa<UndefValue>(getAssociatedValue()))
2695 indicatePessimisticFixpoint();
2696 }
2697
2698 /// See AbstractAttribute::updateImpl(...).
2699 ChangeStatus updateImpl(Attributor &A) override {
2700 // TODO: Once we have call site specific value information we can provide
2701 // call site specific liveness information and then it makes
2702 // sense to specialize attributes for call sites arguments instead of
2703 // redirecting requests to the callee argument.
2704 Argument *Arg = getAssociatedArgument();
2705 if (!Arg)
2706 return indicatePessimisticFixpoint();
2707 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2708 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
2709 return clampStateAndIndicateChange(
2710 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
2711 }
2712
2713 /// See AbstractAttribute::manifest(...).
2714 ChangeStatus manifest(Attributor &A) override {
2715 CallBase &CB = cast<CallBase>(getAnchorValue());
2716 Use &U = CB.getArgOperandUse(getArgNo());
2717 assert(!isa<UndefValue>(U.get()) &&
2718 "Expected undef values to be filtered out!");
2719 UndefValue &UV = *UndefValue::get(U->getType());
2720 if (A.changeUseAfterManifest(U, UV))
2721 return ChangeStatus::CHANGED;
2722 return ChangeStatus::UNCHANGED;
2723 }
2724
2725 /// See AbstractAttribute::trackStatistics()
2726 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
2727};
2728
2729struct AAIsDeadReturned : public AAIsDeadValueImpl {
2730 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2731
2732 /// See AbstractAttribute::updateImpl(...).
2733 ChangeStatus updateImpl(Attributor &A) override {
2734
2735 auto PredForCallSite = [&](AbstractCallSite ACS) {
2736 if (ACS.isCallbackCall())
2737 return false;
2738 const IRPosition &CSRetPos =
2739 IRPosition::callsite_returned(ACS.getCallSite());
2740 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, CSRetPos);
2741 return RetIsDeadAA.isAssumedDead();
2742 };
2743
2744 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
2745 return indicatePessimisticFixpoint();
2746
2747 return ChangeStatus::UNCHANGED;
2748 }
2749
2750 /// See AbstractAttribute::manifest(...).
2751 ChangeStatus manifest(Attributor &A) override {
2752 // TODO: Rewrite the signature to return void?
2753 bool AnyChange = false;
2754 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
2755 auto RetInstPred = [&](Instruction &I) {
2756 ReturnInst &RI = cast<ReturnInst>(I);
2757 if (!isa<UndefValue>(RI.getReturnValue()))
2758 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
2759 return true;
2760 };
2761 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
2762 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2763 }
2764
2765 /// See AbstractAttribute::trackStatistics()
2766 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
2767};
2768
2769struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
2770 AAIsDeadCallSiteReturned(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2771
2772 /// See AbstractAttribute::initialize(...).
2773 void initialize(Attributor &A) override {}
2774
2775 /// See AbstractAttribute::trackStatistics()
2776 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(IsDead) }
2777};
2778
2779struct AAIsDeadFunction : public AAIsDead {
2780 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
2781
2782 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002783 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002784 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002785 if (F && !F->isDeclaration()) {
2786 ToBeExploredFrom.insert(&F->getEntryBlock().front());
2787 assumeLive(A, F->getEntryBlock());
2788 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002789 }
2790
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002791 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002792 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002793 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002794 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002795 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
2796 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002797 }
2798
2799 /// See AbstractAttribute::manifest(...).
2800 ChangeStatus manifest(Attributor &A) override {
2801 assert(getState().isValidState() &&
2802 "Attempted to manifest an invalid state!");
2803
2804 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002805 Function &F = *getAssociatedFunction();
2806
2807 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002808 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002809 return ChangeStatus::CHANGED;
2810 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002811
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002812 // Flag to determine if we can change an invoke to a call assuming the
2813 // callee is nounwind. This is not possible if the personality of the
2814 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002815 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002816
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002817 KnownDeadEnds.set_union(ToBeExploredFrom);
2818 for (const Instruction *DeadEndI : KnownDeadEnds) {
2819 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002820 if (!CB)
2821 continue;
2822 const auto &NoReturnAA =
2823 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002824 bool MayReturn = !NoReturnAA.isAssumedNoReturn();
2825 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002826 continue;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002827 Instruction *I = const_cast<Instruction *>(DeadEndI);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002828 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002829 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00002830 // TODO: mark stuff before unreachable instructions as dead.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002831
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002832 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002833 // If we keep the invoke the split position is at the beginning of the
2834 // normal desitination block (it invokes a noreturn function after all).
2835 BasicBlock *NormalDestBB = II->getNormalDest();
2836 SplitPos = &NormalDestBB->front();
2837
Johannes Doerfert4361da22019-08-04 18:38:53 +00002838 /// Invoke is replaced with a call and unreachable is placed after it if
2839 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
2840 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002841 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00002842 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002843 const IRPosition &IPos = IRPosition::callsite_function(*II);
2844 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2845 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00002846 LLVM_DEBUG(dbgs()
2847 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002848 CallInst *CI = createCallMatchingInvoke(II);
2849 CI->insertBefore(II);
2850 CI->takeName(II);
Johannes Doerfert5d346022019-12-13 22:11:42 -06002851 replaceAllInstructionUsesWith(*II, *CI);
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002852
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002853 // If this is a nounwind + mayreturn invoke we only remove the
2854 // unwind edge. This is done by moving the invoke into a new and
2855 // dead block and connecting the normal destination of the invoke
2856 // with a branch that follows the call replacement we created
2857 // above.
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002858 if (MayReturn) {
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002859 BasicBlock *NewDeadBB =
2860 SplitBlock(BB, II, nullptr, nullptr, nullptr, ".i2c");
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002861 assert(isa<BranchInst>(BB->getTerminator()) &&
2862 BB->getTerminator()->getNumSuccessors() == 1 &&
2863 BB->getTerminator()->getSuccessor(0) == NewDeadBB);
2864 new UnreachableInst(I->getContext(), NewDeadBB);
2865 BB->getTerminator()->setOperand(0, NormalDestBB);
2866 A.deleteAfterManifest(*II);
2867 continue;
2868 }
2869
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002870 // We do not need an invoke (II) but instead want a call followed
2871 // by an unreachable. However, we do not remove II as other
2872 // abstract attributes might have it cached as part of their
2873 // results. Given that we modify the CFG anyway, we simply keep II
2874 // around but in a new dead block. To avoid II being live through
2875 // a different edge we have to ensure the block we place it in is
2876 // only reached from the current block of II and then not reached
2877 // at all when we insert the unreachable.
2878 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002879 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002880 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002881 }
2882 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002883
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002884 if (SplitPos == &NormalDestBB->front()) {
2885 // If this is an invoke of a noreturn function the edge to the normal
2886 // destination block is dead but not necessarily the block itself.
2887 // TODO: We need to move to an edge based system during deduction and
2888 // also manifest.
2889 assert(!NormalDestBB->isLandingPad() &&
2890 "Expected the normal destination not to be a landingpad!");
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002891 if (NormalDestBB->getUniquePredecessor() == BB) {
2892 assumeLive(A, *NormalDestBB);
2893 } else {
2894 BasicBlock *SplitBB =
2895 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2896 // The split block is live even if it contains only an unreachable
2897 // instruction at the end.
2898 assumeLive(A, *SplitBB);
2899 SplitPos = SplitBB->getTerminator();
2900 HasChanged = ChangeStatus::CHANGED;
2901 }
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002902 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002903 }
2904
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002905 if (isa_and_nonnull<UnreachableInst>(SplitPos))
2906 continue;
2907
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002908 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002909 SplitBlock(BB, SplitPos);
Hideto Uenocb5eb132019-12-27 02:39:37 +09002910 A.changeToUnreachableAfterManifest(BB->getTerminator());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002911 HasChanged = ChangeStatus::CHANGED;
2912 }
2913
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002914 for (BasicBlock &BB : F)
2915 if (!AssumedLiveBlocks.count(&BB))
2916 A.deleteAfterManifest(BB);
2917
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002918 return HasChanged;
2919 }
2920
2921 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002922 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002923
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002924 /// See AbstractAttribute::trackStatistics()
2925 void trackStatistics() const override {}
2926
2927 /// Returns true if the function is assumed dead.
2928 bool isAssumedDead() const override { return false; }
2929
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002930 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002931 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002932 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002933 "BB must be in the same anchor scope function.");
2934
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002935 if (!getAssumed())
2936 return false;
2937 return !AssumedLiveBlocks.count(BB);
2938 }
2939
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002940 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002941 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002942 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002943 }
2944
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002945 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002946 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002947 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002948 "Instruction must be in the same anchor scope function.");
2949
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002950 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002951 return false;
2952
2953 // If it is not in AssumedLiveBlocks then it for sure dead.
2954 // Otherwise, it can still be after noreturn call in a live block.
2955 if (!AssumedLiveBlocks.count(I->getParent()))
2956 return true;
2957
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002958 // If it is not after a liveness barrier it is live.
2959 const Instruction *PrevI = I->getPrevNode();
2960 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002961 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002962 return true;
2963 PrevI = PrevI->getPrevNode();
2964 }
2965 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002966 }
2967
2968 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002969 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002970 return getKnown() && isAssumedDead(I);
2971 }
2972
Johannes Doerfert924d2132019-08-05 21:34:45 +00002973 /// Determine if \p F might catch asynchronous exceptions.
2974 static bool mayCatchAsynchronousExceptions(const Function &F) {
2975 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2976 }
2977
Johannes Doerfert2f622062019-09-04 16:35:20 +00002978 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2979 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002980 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002981 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002982 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002983
2984 // We assume that all of BB is (probably) live now and if there are calls to
2985 // internal functions we will assume that those are now live as well. This
2986 // is a performance optimization for blocks with calls to a lot of internal
2987 // functions. It can however cause dead functions to be treated as live.
2988 for (const Instruction &I : BB)
2989 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
2990 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00002991 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00002992 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002993 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002994 }
2995
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002996 /// Collection of instructions that need to be explored again, e.g., we
2997 /// did assume they do not transfer control to (one of their) successors.
2998 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002999
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003000 /// Collection of instructions that are known to not transfer control.
3001 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
3002
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003003 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00003004 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003005};
3006
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003007static bool
3008identifyAliveSuccessors(Attributor &A, const CallBase &CB,
3009 AbstractAttribute &AA,
3010 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3011 const IRPosition &IPos = IRPosition::callsite_function(CB);
3012
3013 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
3014 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003015 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003016 if (CB.isTerminator())
3017 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
3018 else
3019 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003020 return false;
3021}
3022
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003023static bool
3024identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
3025 AbstractAttribute &AA,
3026 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3027 bool UsedAssumedInformation =
3028 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00003029
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003030 // First, determine if we can change an invoke to a call assuming the
3031 // callee is nounwind. This is not possible if the personality of the
3032 // function allows to catch asynchronous exceptions.
3033 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
3034 AliveSuccessors.push_back(&II.getUnwindDest()->front());
3035 } else {
3036 const IRPosition &IPos = IRPosition::callsite_function(II);
3037 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003038 if (AANoUnw.isAssumedNoUnwind()) {
3039 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
3040 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003041 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003042 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003043 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003044 return UsedAssumedInformation;
3045}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003046
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003047static Optional<ConstantInt *>
3048getAssumedConstant(Attributor &A, const Value &V, AbstractAttribute &AA,
3049 bool &UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003050 const auto &ValueSimplifyAA =
3051 A.getAAFor<AAValueSimplify>(AA, IRPosition::value(V));
3052 Optional<Value *> SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(A);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003053 UsedAssumedInformation |= !ValueSimplifyAA.isKnown();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003054 if (!SimplifiedV.hasValue())
3055 return llvm::None;
3056 if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue()))
3057 return llvm::None;
3058 return dyn_cast_or_null<ConstantInt>(SimplifiedV.getValue());
3059}
3060
3061static bool
3062identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
3063 AbstractAttribute &AA,
3064 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3065 bool UsedAssumedInformation = false;
3066 if (BI.getNumSuccessors() == 1) {
3067 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3068 } else {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003069 Optional<ConstantInt *> CI =
3070 getAssumedConstant(A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003071 if (!CI.hasValue()) {
3072 // No value yet, assume both edges are dead.
3073 } else if (CI.getValue()) {
3074 const BasicBlock *SuccBB =
3075 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
3076 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003077 } else {
3078 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3079 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003080 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003081 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003082 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003083 return UsedAssumedInformation;
3084}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003085
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003086static bool
3087identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
3088 AbstractAttribute &AA,
3089 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003090 bool UsedAssumedInformation = false;
3091 Optional<ConstantInt *> CI =
3092 getAssumedConstant(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003093 if (!CI.hasValue()) {
3094 // No value yet, assume all edges are dead.
3095 } else if (CI.getValue()) {
3096 for (auto &CaseIt : SI.cases()) {
3097 if (CaseIt.getCaseValue() == CI.getValue()) {
3098 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003099 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003100 }
3101 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05003102 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003103 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003104 } else {
3105 for (const BasicBlock *SuccBB : successors(SI.getParent()))
3106 AliveSuccessors.push_back(&SuccBB->front());
3107 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003108 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003109}
3110
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003111ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003112 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003113
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003114 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
3115 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003116 << ToBeExploredFrom.size() << " exploration points and "
3117 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003118
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003119 // Copy and clear the list of instructions we need to explore from. It is
3120 // refilled with instructions the next update has to look at.
3121 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
3122 ToBeExploredFrom.end());
3123 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003124
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003125 SmallVector<const Instruction *, 8> AliveSuccessors;
3126 while (!Worklist.empty()) {
3127 const Instruction *I = Worklist.pop_back_val();
3128 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003129
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003130 AliveSuccessors.clear();
3131
3132 bool UsedAssumedInformation = false;
3133 switch (I->getOpcode()) {
3134 // TODO: look for (assumed) UB to backwards propagate "deadness".
3135 default:
3136 if (I->isTerminator()) {
3137 for (const BasicBlock *SuccBB : successors(I->getParent()))
3138 AliveSuccessors.push_back(&SuccBB->front());
3139 } else {
3140 AliveSuccessors.push_back(I->getNextNode());
3141 }
3142 break;
3143 case Instruction::Call:
3144 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
3145 *this, AliveSuccessors);
3146 break;
3147 case Instruction::Invoke:
3148 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
3149 *this, AliveSuccessors);
3150 break;
3151 case Instruction::Br:
3152 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
3153 *this, AliveSuccessors);
3154 break;
3155 case Instruction::Switch:
3156 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
3157 *this, AliveSuccessors);
3158 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00003159 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003160
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003161 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003162 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003163 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003164 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003165 if (AliveSuccessors.empty() ||
3166 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
3167 KnownDeadEnds.insert(I);
3168 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003169
3170 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
3171 << AliveSuccessors.size() << " UsedAssumedInformation: "
3172 << UsedAssumedInformation << "\n");
3173
3174 for (const Instruction *AliveSuccessor : AliveSuccessors) {
3175 if (!I->isTerminator()) {
3176 assert(AliveSuccessors.size() == 1 &&
3177 "Non-terminator expected to have a single successor!");
3178 Worklist.push_back(AliveSuccessor);
3179 } else {
3180 if (assumeLive(A, *AliveSuccessor->getParent()))
3181 Worklist.push_back(AliveSuccessor);
3182 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00003183 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003184 }
3185
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003186 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003187
Johannes Doerfertd6207812019-08-07 22:32:38 +00003188 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003189 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003190 // "invalid" and all queries to be answered conservatively without lookups.
3191 // To be in this state we have to (1) finished the exploration and (3) not
3192 // discovered any non-trivial dead end and (2) not ruled unreachable code
3193 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003194 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003195 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
3196 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
3197 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
3198 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003199 return indicatePessimisticFixpoint();
3200 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003201}
3202
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003203/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003204struct AAIsDeadCallSite final : AAIsDeadFunction {
3205 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003206
3207 /// See AbstractAttribute::initialize(...).
3208 void initialize(Attributor &A) override {
3209 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003210 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003211 // sense to specialize attributes for call sites instead of
3212 // redirecting requests to the callee.
3213 llvm_unreachable("Abstract attributes for liveness are not "
3214 "supported for call sites yet!");
3215 }
3216
3217 /// See AbstractAttribute::updateImpl(...).
3218 ChangeStatus updateImpl(Attributor &A) override {
3219 return indicatePessimisticFixpoint();
3220 }
3221
3222 /// See AbstractAttribute::trackStatistics()
3223 void trackStatistics() const override {}
3224};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003225
Hideto Ueno19c07af2019-07-23 08:16:17 +00003226/// -------------------- Dereferenceable Argument Attribute --------------------
3227
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003228template <>
3229ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
3230 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05003231 ChangeStatus CS0 =
3232 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
3233 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003234 return CS0 | CS1;
3235}
3236
Hideto Ueno70576ca2019-08-22 14:18:29 +00003237struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003238 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003239 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00003240
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003241 void initialize(Attributor &A) override {
3242 SmallVector<Attribute, 4> Attrs;
3243 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
3244 Attrs);
3245 for (const Attribute &Attr : Attrs)
3246 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
3247
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003248 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003249
3250 const IRPosition &IRP = this->getIRPosition();
3251 bool IsFnInterface = IRP.isFnInterfaceKind();
3252 const Function *FnScope = IRP.getAnchorScope();
3253 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
3254 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003255 }
3256
Hideto Ueno19c07af2019-07-23 08:16:17 +00003257 /// See AbstractAttribute::getState()
3258 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00003259 StateType &getState() override { return *this; }
3260 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003261 /// }
3262
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003263 /// Helper function for collecting accessed bytes in must-be-executed-context
3264 void addAccessedBytesForUse(Attributor &A, const Use *U,
3265 const Instruction *I) {
3266 const Value *UseV = U->get();
3267 if (!UseV->getType()->isPointerTy())
3268 return;
3269
3270 Type *PtrTy = UseV->getType();
3271 const DataLayout &DL = A.getDataLayout();
3272 int64_t Offset;
3273 if (const Value *Base = getBasePointerOfAccessPointerOperand(
3274 I, Offset, DL, /*AllowNonInbounds*/ true)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09003275 if (Base == &getAssociatedValue() &&
3276 Attributor::getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003277 uint64_t Size = DL.getTypeStoreSize(PtrTy->getPointerElementType());
3278 addAccessedBytes(Offset, Size);
3279 }
3280 }
3281 return;
3282 }
3283
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003284 /// See AAFromMustBeExecutedContext
3285 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3286 bool IsNonNull = false;
3287 bool TrackUse = false;
3288 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
3289 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003290
3291 addAccessedBytesForUse(A, U, I);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003292 takeKnownDerefBytesMaximum(DerefBytes);
3293 return TrackUse;
3294 }
3295
Hideto Uenodfedae52019-11-29 06:45:07 +00003296 /// See AbstractAttribute::manifest(...).
3297 ChangeStatus manifest(Attributor &A) override {
3298 ChangeStatus Change = AADereferenceable::manifest(A);
3299 if (isAssumedNonNull() && hasAttr(Attribute::DereferenceableOrNull)) {
3300 removeAttrs({Attribute::DereferenceableOrNull});
3301 return ChangeStatus::CHANGED;
3302 }
3303 return Change;
3304 }
3305
Johannes Doerferteccdf082019-08-05 23:35:12 +00003306 void getDeducedAttributes(LLVMContext &Ctx,
3307 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00003308 // TODO: Add *_globally support
3309 if (isAssumedNonNull())
3310 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
3311 Ctx, getAssumedDereferenceableBytes()));
3312 else
3313 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
3314 Ctx, getAssumedDereferenceableBytes()));
3315 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003316
3317 /// See AbstractAttribute::getAsStr().
3318 const std::string getAsStr() const override {
3319 if (!getAssumedDereferenceableBytes())
3320 return "unknown-dereferenceable";
3321 return std::string("dereferenceable") +
3322 (isAssumedNonNull() ? "" : "_or_null") +
3323 (isAssumedGlobal() ? "_globally" : "") + "<" +
3324 std::to_string(getKnownDereferenceableBytes()) + "-" +
3325 std::to_string(getAssumedDereferenceableBytes()) + ">";
3326 }
3327};
3328
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003329/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003330struct AADereferenceableFloating
3331 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
3332 using Base =
3333 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
3334 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00003335
3336 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003337 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003338 ChangeStatus Change = Base::updateImpl(A);
3339
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003340 const DataLayout &DL = A.getDataLayout();
3341
3342 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
3343 unsigned IdxWidth =
3344 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
3345 APInt Offset(IdxWidth, 0);
3346 const Value *Base =
3347 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
3348
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003349 const auto &AA =
3350 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003351 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003352 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003353 // Use IR information if we did not strip anything.
3354 // TODO: track globally.
3355 bool CanBeNull;
3356 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
3357 T.GlobalState.indicatePessimisticFixpoint();
3358 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003359 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003360 DerefBytes = DS.DerefBytesState.getAssumed();
3361 T.GlobalState &= DS.GlobalState;
3362 }
3363
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003364 // For now we do not try to "increase" dereferenceability due to negative
3365 // indices as we first have to come up with code to deal with loops and
3366 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00003367 int64_t OffsetSExt = Offset.getSExtValue();
3368 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00003369 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003370
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003371 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00003372 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003373
Johannes Doerfert785fad32019-08-23 17:29:23 +00003374 if (this == &AA) {
3375 if (!Stripped) {
3376 // If nothing was stripped IR information is all we got.
3377 T.takeKnownDerefBytesMaximum(
3378 std::max(int64_t(0), DerefBytes - OffsetSExt));
3379 T.indicatePessimisticFixpoint();
3380 } else if (OffsetSExt > 0) {
3381 // If something was stripped but there is circular reasoning we look
3382 // for the offset. If it is positive we basically decrease the
3383 // dereferenceable bytes in a circluar loop now, which will simply
3384 // drive them down to the known value in a very slow way which we
3385 // can accelerate.
3386 T.indicatePessimisticFixpoint();
3387 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003388 }
3389
3390 return T.isValidState();
3391 };
3392
3393 DerefState T;
3394 if (!genericValueTraversal<AADereferenceable, DerefState>(
3395 A, getIRPosition(), *this, T, VisitValueCB))
3396 return indicatePessimisticFixpoint();
3397
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003398 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003399 }
3400
3401 /// See AbstractAttribute::trackStatistics()
3402 void trackStatistics() const override {
3403 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
3404 }
3405};
3406
3407/// Dereferenceable attribute for a return value.
3408struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003409 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
3410 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003411 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003412 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
3413 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003414
3415 /// See AbstractAttribute::trackStatistics()
3416 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003417 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003418 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003419};
3420
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003421/// Dereferenceable attribute for an argument
3422struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003423 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
3424 AADereferenceable, AADereferenceableImpl, DerefState> {
3425 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
3426 AADereferenceable, AADereferenceableImpl, DerefState>;
3427 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003428
3429 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003430 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00003431 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
3432 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003433};
3434
Hideto Ueno19c07af2019-07-23 08:16:17 +00003435/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003436struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003437 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003438 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003439
3440 /// See AbstractAttribute::trackStatistics()
3441 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003442 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003443 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003444};
3445
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003446/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003447struct AADereferenceableCallSiteReturned final
3448 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3449 AADereferenceable, AADereferenceableImpl> {
3450 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3451 AADereferenceable, AADereferenceableImpl>;
3452 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003453
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003454 /// See AbstractAttribute::trackStatistics()
3455 void trackStatistics() const override {
3456 STATS_DECLTRACK_CS_ATTR(dereferenceable);
3457 }
3458};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003459
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003460// ------------------------ Align Argument Attribute ------------------------
3461
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003462static unsigned int getKnownAlignForUse(Attributor &A,
3463 AbstractAttribute &QueryingAA,
3464 Value &AssociatedValue, const Use *U,
3465 const Instruction *I, bool &TrackUse) {
Hideto Ueno78a75022019-11-26 07:51:59 +00003466 // We need to follow common pointer manipulation uses to the accesses they
3467 // feed into.
3468 if (isa<CastInst>(I)) {
Johannes Doerfertc90681b2020-01-02 16:41:17 -06003469 // Follow all but ptr2int casts.
3470 TrackUse = !isa<PtrToIntInst>(I);
Hideto Ueno78a75022019-11-26 07:51:59 +00003471 return 0;
3472 }
3473 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
3474 if (GEP->hasAllConstantIndices()) {
3475 TrackUse = true;
3476 return 0;
3477 }
3478 }
3479
3480 unsigned Alignment = 0;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003481 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
3482 if (ICS.isBundleOperand(U) || ICS.isCallee(U))
3483 return 0;
3484
3485 unsigned ArgNo = ICS.getArgumentNo(U);
3486 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
3487 // As long as we only use known information there is no need to track
3488 // dependences here.
3489 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP,
3490 /* TrackDependence */ false);
Hideto Ueno78a75022019-11-26 07:51:59 +00003491 Alignment = AlignAA.getKnownAlign();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003492 }
3493
Hideto Ueno78a75022019-11-26 07:51:59 +00003494 const Value *UseV = U->get();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003495 if (auto *SI = dyn_cast<StoreInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003496 Alignment = SI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003497 else if (auto *LI = dyn_cast<LoadInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003498 Alignment = LI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003499
Hideto Ueno78a75022019-11-26 07:51:59 +00003500 if (Alignment <= 1)
3501 return 0;
3502
3503 auto &DL = A.getDataLayout();
3504 int64_t Offset;
3505
3506 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
3507 if (Base == &AssociatedValue) {
3508 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
3509 // So we can say that the maximum power of two which is a divisor of
3510 // gcd(Offset, Alignment) is an alignment.
3511
3512 uint32_t gcd =
3513 greatestCommonDivisor(uint32_t(abs((int32_t)Offset)), Alignment);
3514 Alignment = llvm::PowerOf2Floor(gcd);
3515 }
3516 }
3517
3518 return Alignment;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003519}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003520struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003521 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003522
Johannes Doerfert234eda52019-08-16 19:51:23 +00003523 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003524 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003525 SmallVector<Attribute, 4> Attrs;
3526 getAttrs({Attribute::Alignment}, Attrs);
3527 for (const Attribute &Attr : Attrs)
3528 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003529
3530 if (getIRPosition().isFnInterfaceKind() &&
3531 (!getAssociatedFunction() ||
3532 !getAssociatedFunction()->hasExactDefinition()))
3533 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003534 }
3535
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003536 /// See AbstractAttribute::manifest(...).
3537 ChangeStatus manifest(Attributor &A) override {
3538 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3539
3540 // Check for users that allow alignment annotations.
3541 Value &AnchorVal = getIRPosition().getAnchorValue();
3542 for (const Use &U : AnchorVal.uses()) {
3543 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
3544 if (SI->getPointerOperand() == &AnchorVal)
3545 if (SI->getAlignment() < getAssumedAlign()) {
3546 STATS_DECLTRACK(AAAlign, Store,
3547 "Number of times alignemnt added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00003548 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003549 Changed = ChangeStatus::CHANGED;
3550 }
3551 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
3552 if (LI->getPointerOperand() == &AnchorVal)
3553 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00003554 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003555 STATS_DECLTRACK(AAAlign, Load,
3556 "Number of times alignemnt added to a load");
3557 Changed = ChangeStatus::CHANGED;
3558 }
3559 }
3560 }
3561
Johannes Doerfert81df4522019-08-30 15:22:28 +00003562 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003563 }
3564
Johannes Doerfert81df4522019-08-30 15:22:28 +00003565 // TODO: Provide a helper to determine the implied ABI alignment and check in
3566 // the existing manifest method and a new one for AAAlignImpl that value
3567 // to avoid making the alignment explicit if it did not improve.
3568
3569 /// See AbstractAttribute::getDeducedAttributes
3570 virtual void
3571 getDeducedAttributes(LLVMContext &Ctx,
3572 SmallVectorImpl<Attribute> &Attrs) const override {
3573 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00003574 Attrs.emplace_back(
3575 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00003576 }
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003577 /// See AAFromMustBeExecutedContext
3578 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3579 bool TrackUse = false;
3580
Hideto Ueno4ecf2552019-12-12 13:42:40 +00003581 unsigned int KnownAlign =
3582 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003583 takeKnownMaximum(KnownAlign);
3584
3585 return TrackUse;
3586 }
Johannes Doerfert81df4522019-08-30 15:22:28 +00003587
3588 /// See AbstractAttribute::getAsStr().
3589 const std::string getAsStr() const override {
3590 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
3591 "-" + std::to_string(getAssumedAlign()) + ">")
3592 : "unknown-align";
3593 }
3594};
3595
3596/// Align attribute for a floating value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003597struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
3598 using Base = AAFromMustBeExecutedContext<AAAlign, AAAlignImpl>;
3599 AAAlignFloating(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert81df4522019-08-30 15:22:28 +00003600
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003601 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00003602 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003603 Base::updateImpl(A);
3604
Johannes Doerfert234eda52019-08-16 19:51:23 +00003605 const DataLayout &DL = A.getDataLayout();
3606
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003607 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3608 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003609 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3610 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003611 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003612 const MaybeAlign PA = V.getPointerAlignment(DL);
3613 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003614 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003615 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003616 // Use abstract attribute information.
3617 const AAAlign::StateType &DS =
3618 static_cast<const AAAlign::StateType &>(AA.getState());
3619 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003620 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003621 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003622 };
3623
3624 StateType T;
3625 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3626 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003627 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003628
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003629 // TODO: If we know we visited all incoming values, thus no are assumed
3630 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003631 return clampStateAndIndicateChange(getState(), T);
3632 }
3633
3634 /// See AbstractAttribute::trackStatistics()
3635 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3636};
3637
3638/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003639struct AAAlignReturned final
3640 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003641 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003642 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003643
3644 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003645 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003646};
3647
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003648/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003649struct AAAlignArgument final
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003650 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3651 AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003652 AAAlignArgument(const IRPosition &IRP)
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003653 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3654 AAAlignImpl>(
3655 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003656
3657 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003658 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003659};
3660
Johannes Doerfert234eda52019-08-16 19:51:23 +00003661struct AAAlignCallSiteArgument final : AAAlignFloating {
3662 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003663
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003664 /// See AbstractAttribute::manifest(...).
3665 ChangeStatus manifest(Attributor &A) override {
3666 return AAAlignImpl::manifest(A);
3667 }
3668
Johannes Doerfertdada8132019-12-31 01:27:50 -06003669 /// See AbstractAttribute::updateImpl(Attributor &A).
3670 ChangeStatus updateImpl(Attributor &A) override {
3671 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
3672 if (Argument *Arg = getAssociatedArgument()) {
3673 const auto &ArgAlignAA = A.getAAFor<AAAlign>(
3674 *this, IRPosition::argument(*Arg), /* TrackDependence */ false,
3675 DepClassTy::OPTIONAL);
3676 takeKnownMaximum(ArgAlignAA.getKnownAlign());
3677 }
3678 return Changed;
3679 }
3680
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003681 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003682 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003683};
3684
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003685/// Align attribute deduction for a call site return value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003686struct AAAlignCallSiteReturned final
3687 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3688 AAAlignImpl> {
3689 using Base =
3690 AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3691 AAAlignImpl>;
3692 AAAlignCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003693
3694 /// See AbstractAttribute::initialize(...).
3695 void initialize(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003696 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003697 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003698 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003699 indicatePessimisticFixpoint();
3700 }
3701
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003702 /// See AbstractAttribute::trackStatistics()
3703 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3704};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003705
Johannes Doerferte83f3032019-08-05 23:22:05 +00003706/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003707struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003708 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003709
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003710 /// See AbstractAttribute::initialize(...).
3711 void initialize(Attributor &A) override {
3712 AANoReturn::initialize(A);
3713 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003714 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003715 indicatePessimisticFixpoint();
3716 }
3717
Johannes Doerferte83f3032019-08-05 23:22:05 +00003718 /// See AbstractAttribute::getAsStr().
3719 const std::string getAsStr() const override {
3720 return getAssumed() ? "noreturn" : "may-return";
3721 }
3722
Johannes Doerferte83f3032019-08-05 23:22:05 +00003723 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00003724 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003725 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003726 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003727 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003728 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003729 return ChangeStatus::UNCHANGED;
3730 }
3731};
3732
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003733struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003734 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003735
3736 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003737 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003738};
3739
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003740/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003741struct AANoReturnCallSite final : AANoReturnImpl {
3742 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3743
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003744 /// See AbstractAttribute::updateImpl(...).
3745 ChangeStatus updateImpl(Attributor &A) override {
3746 // TODO: Once we have call site specific value information we can provide
3747 // call site specific liveness information and then it makes
3748 // sense to specialize attributes for call sites arguments instead of
3749 // redirecting requests to the callee argument.
3750 Function *F = getAssociatedFunction();
3751 const IRPosition &FnPos = IRPosition::function(*F);
3752 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3753 return clampStateAndIndicateChange(
3754 getState(),
3755 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3756 }
3757
3758 /// See AbstractAttribute::trackStatistics()
3759 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3760};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003761
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003762/// ----------------------- Variable Capturing ---------------------------------
3763
3764/// A class to hold the state of for no-capture attributes.
3765struct AANoCaptureImpl : public AANoCapture {
3766 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3767
3768 /// See AbstractAttribute::initialize(...).
3769 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003770 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3771 indicateOptimisticFixpoint();
3772 return;
3773 }
3774 Function *AnchorScope = getAnchorScope();
3775 if (isFnInterfaceKind() &&
3776 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3777 indicatePessimisticFixpoint();
3778 return;
3779 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003780
Johannes Doerfert72adda12019-10-10 05:33:21 +00003781 // You cannot "capture" null in the default address space.
3782 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3783 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3784 indicateOptimisticFixpoint();
3785 return;
3786 }
3787
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003788 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003789
3790 // Check what state the associated function can actually capture.
3791 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003792 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003793 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003794 indicatePessimisticFixpoint();
3795 }
3796
3797 /// See AbstractAttribute::updateImpl(...).
3798 ChangeStatus updateImpl(Attributor &A) override;
3799
3800 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3801 virtual void
3802 getDeducedAttributes(LLVMContext &Ctx,
3803 SmallVectorImpl<Attribute> &Attrs) const override {
3804 if (!isAssumedNoCaptureMaybeReturned())
3805 return;
3806
Hideto Ueno37367642019-09-11 06:52:11 +00003807 if (getArgNo() >= 0) {
3808 if (isAssumedNoCapture())
3809 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3810 else if (ManifestInternal)
3811 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3812 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003813 }
3814
3815 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3816 /// depending on the ability of the function associated with \p IRP to capture
3817 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003818 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3819 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003820 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003821 // TODO: Once we have memory behavior attributes we should use them here.
3822
3823 // If we know we cannot communicate or write to memory, we do not care about
3824 // ptr2int anymore.
3825 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3826 F.getReturnType()->isVoidTy()) {
3827 State.addKnownBits(NO_CAPTURE);
3828 return;
3829 }
3830
3831 // A function cannot capture state in memory if it only reads memory, it can
3832 // however return/throw state and the state might be influenced by the
3833 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3834 if (F.onlyReadsMemory())
3835 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3836
3837 // A function cannot communicate state back if it does not through
3838 // exceptions and doesn not return values.
3839 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
3840 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00003841
3842 // Check existing "returned" attributes.
3843 int ArgNo = IRP.getArgNo();
3844 if (F.doesNotThrow() && ArgNo >= 0) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01003845 for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
Johannes Doerfert3839b572019-10-21 00:48:42 +00003846 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00003847 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00003848 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
3849 else if (F.onlyReadsMemory())
3850 State.addKnownBits(NO_CAPTURE);
3851 else
3852 State.addKnownBits(NOT_CAPTURED_IN_RET);
3853 break;
3854 }
3855 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003856 }
3857
3858 /// See AbstractState::getAsStr().
3859 const std::string getAsStr() const override {
3860 if (isKnownNoCapture())
3861 return "known not-captured";
3862 if (isAssumedNoCapture())
3863 return "assumed not-captured";
3864 if (isKnownNoCaptureMaybeReturned())
3865 return "known not-captured-maybe-returned";
3866 if (isAssumedNoCaptureMaybeReturned())
3867 return "assumed not-captured-maybe-returned";
3868 return "assumed-captured";
3869 }
3870};
3871
3872/// Attributor-aware capture tracker.
3873struct AACaptureUseTracker final : public CaptureTracker {
3874
3875 /// Create a capture tracker that can lookup in-flight abstract attributes
3876 /// through the Attributor \p A.
3877 ///
3878 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
3879 /// search is stopped. If a use leads to a return instruction,
3880 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
3881 /// If a use leads to a ptr2int which may capture the value,
3882 /// \p CapturedInInteger is set. If a use is found that is currently assumed
3883 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
3884 /// set. All values in \p PotentialCopies are later tracked as well. For every
3885 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
3886 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
3887 /// conservatively set to true.
3888 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05003889 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003890 SmallVectorImpl<const Value *> &PotentialCopies,
3891 unsigned &RemainingUsesToExplore)
3892 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
3893 PotentialCopies(PotentialCopies),
3894 RemainingUsesToExplore(RemainingUsesToExplore) {}
3895
3896 /// Determine if \p V maybe captured. *Also updates the state!*
3897 bool valueMayBeCaptured(const Value *V) {
3898 if (V->getType()->isPointerTy()) {
3899 PointerMayBeCaptured(V, this);
3900 } else {
3901 State.indicatePessimisticFixpoint();
3902 }
3903 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3904 }
3905
3906 /// See CaptureTracker::tooManyUses().
3907 void tooManyUses() override {
3908 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3909 }
3910
3911 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3912 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3913 return true;
3914 const auto &DerefAA =
3915 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3916 return DerefAA.getAssumedDereferenceableBytes();
3917 }
3918
3919 /// See CaptureTracker::captured(...).
3920 bool captured(const Use *U) override {
3921 Instruction *UInst = cast<Instruction>(U->getUser());
3922 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3923 << "\n");
3924
3925 // Because we may reuse the tracker multiple times we keep track of the
3926 // number of explored uses ourselves as well.
3927 if (RemainingUsesToExplore-- == 0) {
3928 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3929 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3930 /* Return */ true);
3931 }
3932
3933 // Deal with ptr2int by following uses.
3934 if (isa<PtrToIntInst>(UInst)) {
3935 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3936 return valueMayBeCaptured(UInst);
3937 }
3938
3939 // Explicitly catch return instructions.
3940 if (isa<ReturnInst>(UInst))
3941 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3942 /* Return */ true);
3943
3944 // For now we only use special logic for call sites. However, the tracker
3945 // itself knows about a lot of other non-capturing cases already.
3946 CallSite CS(UInst);
3947 if (!CS || !CS.isArgOperand(U))
3948 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3949 /* Return */ true);
3950
3951 unsigned ArgNo = CS.getArgumentNo(U);
3952 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3953 // If we have a abstract no-capture attribute for the argument we can use
3954 // it to justify a non-capture attribute here. This allows recursion!
3955 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3956 if (ArgNoCaptureAA.isAssumedNoCapture())
3957 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3958 /* Return */ false);
3959 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3960 addPotentialCopy(CS);
3961 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3962 /* Return */ false);
3963 }
3964
3965 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3966 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3967 /* Return */ true);
3968 }
3969
3970 /// Register \p CS as potential copy of the value we are checking.
3971 void addPotentialCopy(CallSite CS) {
3972 PotentialCopies.push_back(CS.getInstruction());
3973 }
3974
3975 /// See CaptureTracker::shouldExplore(...).
3976 bool shouldExplore(const Use *U) override {
3977 // Check liveness.
3978 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3979 }
3980
3981 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3982 /// \p CapturedInRet, then return the appropriate value for use in the
3983 /// CaptureTracker::captured() interface.
3984 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3985 bool CapturedInRet) {
3986 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
3987 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
3988 if (CapturedInMem)
3989 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
3990 if (CapturedInInt)
3991 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
3992 if (CapturedInRet)
3993 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
3994 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3995 }
3996
3997private:
3998 /// The attributor providing in-flight abstract attributes.
3999 Attributor &A;
4000
4001 /// The abstract attribute currently updated.
4002 AANoCapture &NoCaptureAA;
4003
4004 /// The abstract liveness state.
4005 const AAIsDead &IsDeadAA;
4006
4007 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05004008 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004009
4010 /// Set of potential copies of the tracked value.
4011 SmallVectorImpl<const Value *> &PotentialCopies;
4012
4013 /// Global counter to limit the number of explored uses.
4014 unsigned &RemainingUsesToExplore;
4015};
4016
4017ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
4018 const IRPosition &IRP = getIRPosition();
4019 const Value *V =
4020 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
4021 if (!V)
4022 return indicatePessimisticFixpoint();
4023
4024 const Function *F =
4025 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
4026 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00004027 const IRPosition &FnPos = IRPosition::function(*F);
4028 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, FnPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004029
4030 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004031
Johannes Doerfert3839b572019-10-21 00:48:42 +00004032 // Readonly means we cannot capture through memory.
4033 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4034 if (FnMemAA.isAssumedReadOnly()) {
4035 T.addKnownBits(NOT_CAPTURED_IN_MEM);
4036 if (FnMemAA.isKnownReadOnly())
4037 addKnownBits(NOT_CAPTURED_IN_MEM);
4038 }
4039
4040 // Make sure all returned values are different than the underlying value.
4041 // TODO: we could do this in a more sophisticated way inside
4042 // AAReturnedValues, e.g., track all values that escape through returns
4043 // directly somehow.
4044 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
4045 bool SeenConstant = false;
4046 for (auto &It : RVAA.returned_values()) {
4047 if (isa<Constant>(It.first)) {
4048 if (SeenConstant)
4049 return false;
4050 SeenConstant = true;
4051 } else if (!isa<Argument>(It.first) ||
4052 It.first == getAssociatedArgument())
4053 return false;
4054 }
4055 return true;
4056 };
4057
4058 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, FnPos);
4059 if (NoUnwindAA.isAssumedNoUnwind()) {
4060 bool IsVoidTy = F->getReturnType()->isVoidTy();
4061 const AAReturnedValues *RVAA =
4062 IsVoidTy ? nullptr : &A.getAAFor<AAReturnedValues>(*this, FnPos);
4063 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
4064 T.addKnownBits(NOT_CAPTURED_IN_RET);
4065 if (T.isKnown(NOT_CAPTURED_IN_MEM))
4066 return ChangeStatus::UNCHANGED;
4067 if (NoUnwindAA.isKnownNoUnwind() &&
4068 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
4069 addKnownBits(NOT_CAPTURED_IN_RET);
4070 if (isKnown(NOT_CAPTURED_IN_MEM))
4071 return indicateOptimisticFixpoint();
4072 }
4073 }
4074 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004075
4076 // Use the CaptureTracker interface and logic with the specialized tracker,
4077 // defined in AACaptureUseTracker, that can look at in-flight abstract
4078 // attributes and directly updates the assumed state.
4079 SmallVector<const Value *, 4> PotentialCopies;
4080 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
4081 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
4082 RemainingUsesToExplore);
4083
4084 // Check all potential copies of the associated value until we can assume
4085 // none will be captured or we have to assume at least one might be.
4086 unsigned Idx = 0;
4087 PotentialCopies.push_back(V);
4088 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
4089 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
4090
Johannes Doerfert1a746452019-10-20 22:28:49 -05004091 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004092 auto Assumed = S.getAssumed();
4093 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05004094 if (!isAssumedNoCaptureMaybeReturned())
4095 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004096 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
4097 : ChangeStatus::CHANGED;
4098}
4099
4100/// NoCapture attribute for function arguments.
4101struct AANoCaptureArgument final : AANoCaptureImpl {
4102 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4103
4104 /// See AbstractAttribute::trackStatistics()
4105 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
4106};
4107
4108/// NoCapture attribute for call site arguments.
4109struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
4110 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4111
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004112 /// See AbstractAttribute::initialize(...).
4113 void initialize(Attributor &A) override {
4114 if (Argument *Arg = getAssociatedArgument())
4115 if (Arg->hasByValAttr())
4116 indicateOptimisticFixpoint();
4117 AANoCaptureImpl::initialize(A);
4118 }
4119
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004120 /// See AbstractAttribute::updateImpl(...).
4121 ChangeStatus updateImpl(Attributor &A) override {
4122 // TODO: Once we have call site specific value information we can provide
4123 // call site specific liveness information and then it makes
4124 // sense to specialize attributes for call sites arguments instead of
4125 // redirecting requests to the callee argument.
4126 Argument *Arg = getAssociatedArgument();
4127 if (!Arg)
4128 return indicatePessimisticFixpoint();
4129 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4130 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
4131 return clampStateAndIndicateChange(
4132 getState(),
4133 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
4134 }
4135
4136 /// See AbstractAttribute::trackStatistics()
4137 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
4138};
4139
4140/// NoCapture attribute for floating values.
4141struct AANoCaptureFloating final : AANoCaptureImpl {
4142 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4143
4144 /// See AbstractAttribute::trackStatistics()
4145 void trackStatistics() const override {
4146 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
4147 }
4148};
4149
4150/// NoCapture attribute for function return value.
4151struct AANoCaptureReturned final : AANoCaptureImpl {
4152 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
4153 llvm_unreachable("NoCapture is not applicable to function returns!");
4154 }
4155
4156 /// See AbstractAttribute::initialize(...).
4157 void initialize(Attributor &A) override {
4158 llvm_unreachable("NoCapture is not applicable to function returns!");
4159 }
4160
4161 /// See AbstractAttribute::updateImpl(...).
4162 ChangeStatus updateImpl(Attributor &A) override {
4163 llvm_unreachable("NoCapture is not applicable to function returns!");
4164 }
4165
4166 /// See AbstractAttribute::trackStatistics()
4167 void trackStatistics() const override {}
4168};
4169
4170/// NoCapture attribute deduction for a call site return value.
4171struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
4172 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4173
4174 /// See AbstractAttribute::trackStatistics()
4175 void trackStatistics() const override {
4176 STATS_DECLTRACK_CSRET_ATTR(nocapture)
4177 }
4178};
4179
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004180/// ------------------ Value Simplify Attribute ----------------------------
4181struct AAValueSimplifyImpl : AAValueSimplify {
4182 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
4183
4184 /// See AbstractAttribute::getAsStr().
4185 const std::string getAsStr() const override {
4186 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
4187 : "not-simple";
4188 }
4189
4190 /// See AbstractAttribute::trackStatistics()
4191 void trackStatistics() const override {}
4192
4193 /// See AAValueSimplify::getAssumedSimplifiedValue()
4194 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
4195 if (!getAssumed())
4196 return const_cast<Value *>(&getAssociatedValue());
4197 return SimplifiedAssociatedValue;
4198 }
4199 void initialize(Attributor &A) override {}
4200
4201 /// Helper function for querying AAValueSimplify and updating candicate.
4202 /// \param QueryingValue Value trying to unify with SimplifiedValue
4203 /// \param AccumulatedSimplifiedValue Current simplification result.
4204 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
4205 Value &QueryingValue,
4206 Optional<Value *> &AccumulatedSimplifiedValue) {
4207 // FIXME: Add a typecast support.
4208
4209 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
4210 QueryingAA, IRPosition::value(QueryingValue));
4211
4212 Optional<Value *> QueryingValueSimplified =
4213 ValueSimpifyAA.getAssumedSimplifiedValue(A);
4214
4215 if (!QueryingValueSimplified.hasValue())
4216 return true;
4217
4218 if (!QueryingValueSimplified.getValue())
4219 return false;
4220
4221 Value &QueryingValueSimplifiedUnwrapped =
4222 *QueryingValueSimplified.getValue();
4223
4224 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
4225 return true;
4226
4227 if (AccumulatedSimplifiedValue.hasValue())
4228 return AccumulatedSimplifiedValue == QueryingValueSimplified;
4229
4230 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
4231 << " is assumed to be "
4232 << QueryingValueSimplifiedUnwrapped << "\n");
4233
4234 AccumulatedSimplifiedValue = QueryingValueSimplified;
4235 return true;
4236 }
4237
4238 /// See AbstractAttribute::manifest(...).
4239 ChangeStatus manifest(Attributor &A) override {
4240 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4241
4242 if (!SimplifiedAssociatedValue.hasValue() ||
4243 !SimplifiedAssociatedValue.getValue())
4244 return Changed;
4245
4246 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
4247 // We can replace the AssociatedValue with the constant.
4248 Value &V = getAssociatedValue();
4249 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
4250 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
4251 << "\n");
Hideto Ueno34fe8d02019-12-30 17:08:48 +09004252 A.changeValueAfterManifest(V, *C);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004253 Changed = ChangeStatus::CHANGED;
4254 }
4255 }
4256
4257 return Changed | AAValueSimplify::manifest(A);
4258 }
4259
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004260 /// See AbstractState::indicatePessimisticFixpoint(...).
4261 ChangeStatus indicatePessimisticFixpoint() override {
4262 // NOTE: Associated value will be returned in a pessimistic fixpoint and is
4263 // regarded as known. That's why`indicateOptimisticFixpoint` is called.
4264 SimplifiedAssociatedValue = &getAssociatedValue();
Johannes Doerferta4b35882019-12-31 13:25:47 -06004265 indicateOptimisticFixpoint();
4266 return ChangeStatus::CHANGED;
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004267 }
4268
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004269protected:
4270 // An assumed simplified value. Initially, it is set to Optional::None, which
4271 // means that the value is not clear under current assumption. If in the
4272 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4273 // returns orignal associated value.
4274 Optional<Value *> SimplifiedAssociatedValue;
4275};
4276
4277struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
4278 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4279
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004280 void initialize(Attributor &A) override {
4281 AAValueSimplifyImpl::initialize(A);
4282 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
4283 indicatePessimisticFixpoint();
4284 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
4285 /* IgnoreSubsumingPositions */ true))
4286 indicatePessimisticFixpoint();
4287 }
4288
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004289 /// See AbstractAttribute::updateImpl(...).
4290 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004291 // Byval is only replacable if it is readonly otherwise we would write into
4292 // the replaced value and not the copy that byval creates implicitly.
4293 Argument *Arg = getAssociatedArgument();
4294 if (Arg->hasByValAttr()) {
4295 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
4296 if (!MemAA.isAssumedReadOnly())
4297 return indicatePessimisticFixpoint();
4298 }
4299
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004300 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4301
Johannes Doerfert661db042019-10-07 23:14:58 +00004302 auto PredForCallSite = [&](AbstractCallSite ACS) {
4303 // Check if we have an associated argument or not (which can happen for
4304 // callback calls).
Johannes Doerferte360ee62019-11-01 18:45:25 -05004305 Value *ArgOp = ACS.getCallArgOperand(getArgNo());
4306 if (!ArgOp)
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004307 return false;
Johannes Doerferte360ee62019-11-01 18:45:25 -05004308 // We can only propagate thread independent values through callbacks.
4309 // This is different to direct/indirect call sites because for them we
4310 // know the thread executing the caller and callee is the same. For
4311 // callbacks this is not guaranteed, thus a thread dependent value could
4312 // be different for the caller and callee, making it invalid to propagate.
4313 if (ACS.isCallbackCall())
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004314 if (auto *C = dyn_cast<Constant>(ArgOp))
Johannes Doerferte360ee62019-11-01 18:45:25 -05004315 if (C->isThreadDependent())
4316 return false;
4317 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004318 };
4319
4320 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
Hideto Ueno5fc02dc2020-01-03 11:03:56 +09004321 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004322
4323 // If a candicate was found in this update, return CHANGED.
4324 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4325 ? ChangeStatus::UNCHANGED
4326 : ChangeStatus ::CHANGED;
4327 }
4328
4329 /// See AbstractAttribute::trackStatistics()
4330 void trackStatistics() const override {
4331 STATS_DECLTRACK_ARG_ATTR(value_simplify)
4332 }
4333};
4334
4335struct AAValueSimplifyReturned : AAValueSimplifyImpl {
4336 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4337
4338 /// See AbstractAttribute::updateImpl(...).
4339 ChangeStatus updateImpl(Attributor &A) override {
4340 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4341
4342 auto PredForReturned = [&](Value &V) {
4343 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4344 };
4345
4346 if (!A.checkForAllReturnedValues(PredForReturned, *this))
Hideto Ueno5fc02dc2020-01-03 11:03:56 +09004347 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004348
4349 // If a candicate was found in this update, return CHANGED.
4350 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4351 ? ChangeStatus::UNCHANGED
4352 : ChangeStatus ::CHANGED;
4353 }
4354 /// See AbstractAttribute::trackStatistics()
4355 void trackStatistics() const override {
4356 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
4357 }
4358};
4359
4360struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4361 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4362
4363 /// See AbstractAttribute::initialize(...).
4364 void initialize(Attributor &A) override {
4365 Value &V = getAnchorValue();
4366
4367 // TODO: add other stuffs
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004368 if (isa<Constant>(V))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004369 indicatePessimisticFixpoint();
4370 }
4371
4372 /// See AbstractAttribute::updateImpl(...).
4373 ChangeStatus updateImpl(Attributor &A) override {
4374 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4375
4376 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
4377 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
4378 if (!Stripped && this == &AA) {
4379 // TODO: Look the instruction and check recursively.
4380 LLVM_DEBUG(
4381 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
4382 << V << "\n");
Hideto Ueno5fc02dc2020-01-03 11:03:56 +09004383 indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004384 return false;
4385 }
4386 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4387 };
4388
4389 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
4390 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
4391 VisitValueCB))
Hideto Ueno5fc02dc2020-01-03 11:03:56 +09004392 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004393
4394 // If a candicate was found in this update, return CHANGED.
4395
4396 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4397 ? ChangeStatus::UNCHANGED
4398 : ChangeStatus ::CHANGED;
4399 }
4400
4401 /// See AbstractAttribute::trackStatistics()
4402 void trackStatistics() const override {
4403 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
4404 }
4405};
4406
4407struct AAValueSimplifyFunction : AAValueSimplifyImpl {
4408 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4409
4410 /// See AbstractAttribute::initialize(...).
4411 void initialize(Attributor &A) override {
4412 SimplifiedAssociatedValue = &getAnchorValue();
4413 indicateOptimisticFixpoint();
4414 }
4415 /// See AbstractAttribute::initialize(...).
4416 ChangeStatus updateImpl(Attributor &A) override {
4417 llvm_unreachable(
4418 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
4419 }
4420 /// See AbstractAttribute::trackStatistics()
4421 void trackStatistics() const override {
4422 STATS_DECLTRACK_FN_ATTR(value_simplify)
4423 }
4424};
4425
4426struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
4427 AAValueSimplifyCallSite(const IRPosition &IRP)
4428 : AAValueSimplifyFunction(IRP) {}
4429 /// See AbstractAttribute::trackStatistics()
4430 void trackStatistics() const override {
4431 STATS_DECLTRACK_CS_ATTR(value_simplify)
4432 }
4433};
4434
4435struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
4436 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
4437 : AAValueSimplifyReturned(IRP) {}
4438
4439 void trackStatistics() const override {
4440 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
4441 }
4442};
4443struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
4444 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
4445 : AAValueSimplifyFloating(IRP) {}
4446
4447 void trackStatistics() const override {
4448 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
4449 }
4450};
4451
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004452/// ----------------------- Heap-To-Stack Conversion ---------------------------
4453struct AAHeapToStackImpl : public AAHeapToStack {
4454 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
4455
4456 const std::string getAsStr() const override {
4457 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
4458 }
4459
4460 ChangeStatus manifest(Attributor &A) override {
4461 assert(getState().isValidState() &&
4462 "Attempted to manifest an invalid state!");
4463
4464 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4465 Function *F = getAssociatedFunction();
4466 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4467
4468 for (Instruction *MallocCall : MallocCalls) {
4469 // This malloc cannot be replaced.
4470 if (BadMallocCalls.count(MallocCall))
4471 continue;
4472
4473 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
4474 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
4475 A.deleteAfterManifest(*FreeCall);
4476 HasChanged = ChangeStatus::CHANGED;
4477 }
4478
4479 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
4480 << "\n");
4481
4482 Constant *Size;
4483 if (isCallocLikeFn(MallocCall, TLI)) {
4484 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
4485 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
4486 APInt TotalSize = SizeT->getValue() * Num->getValue();
4487 Size =
4488 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
4489 } else {
4490 Size = cast<ConstantInt>(MallocCall->getOperand(0));
4491 }
4492
4493 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
4494 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
4495 Size, "", MallocCall->getNextNode());
4496
4497 if (AI->getType() != MallocCall->getType())
4498 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
4499 AI->getNextNode());
4500
Johannes Doerfert5d346022019-12-13 22:11:42 -06004501 replaceAllInstructionUsesWith(*MallocCall, *AI);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004502
4503 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
4504 auto *NBB = II->getNormalDest();
4505 BranchInst::Create(NBB, MallocCall->getParent());
4506 A.deleteAfterManifest(*MallocCall);
4507 } else {
4508 A.deleteAfterManifest(*MallocCall);
4509 }
4510
4511 if (isCallocLikeFn(MallocCall, TLI)) {
4512 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
4513 AI->getNextNode());
4514 Value *Ops[] = {
4515 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
4516 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
4517
4518 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
4519 Module *M = F->getParent();
4520 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
4521 CallInst::Create(Fn, Ops, "", BI->getNextNode());
4522 }
4523 HasChanged = ChangeStatus::CHANGED;
4524 }
4525
4526 return HasChanged;
4527 }
4528
4529 /// Collection of all malloc calls in a function.
4530 SmallSetVector<Instruction *, 4> MallocCalls;
4531
4532 /// Collection of malloc calls that cannot be converted.
4533 DenseSet<const Instruction *> BadMallocCalls;
4534
4535 /// A map for each malloc call to the set of associated free calls.
4536 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
4537
4538 ChangeStatus updateImpl(Attributor &A) override;
4539};
4540
4541ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4542 const Function *F = getAssociatedFunction();
4543 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4544
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004545 MustBeExecutedContextExplorer &Explorer =
4546 A.getInfoCache().getMustBeExecutedContextExplorer();
4547
4548 auto FreeCheck = [&](Instruction &I) {
4549 const auto &Frees = FreesForMalloc.lookup(&I);
4550 if (Frees.size() != 1)
4551 return false;
4552 Instruction *UniqueFree = *Frees.begin();
4553 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
4554 };
4555
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004556 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004557 bool ValidUsesOnly = true;
4558 bool MustUse = true;
Hideto Ueno827bade2019-12-12 12:26:30 +00004559 auto Pred = [&](const Use &U, bool &Follow) -> bool {
4560 Instruction *UserI = cast<Instruction>(U.getUser());
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004561 if (isa<LoadInst>(UserI))
Hideto Ueno827bade2019-12-12 12:26:30 +00004562 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004563 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004564 if (SI->getValueOperand() == U.get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004565 LLVM_DEBUG(dbgs()
4566 << "[H2S] escaping store to memory: " << *UserI << "\n");
4567 ValidUsesOnly = false;
4568 } else {
4569 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004570 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004571 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004572 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004573 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004574 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
4575 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004576 // Record malloc.
4577 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004578 if (MustUse) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004579 FreesForMalloc[&I].insert(UserI);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004580 } else {
4581 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
4582 << *UserI << "\n");
4583 ValidUsesOnly = false;
4584 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004585 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004586 }
4587
Hideto Ueno827bade2019-12-12 12:26:30 +00004588 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004589
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004590 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
4591 *this, IRPosition::callsite_argument(*CB, ArgNo));
4592
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004593 // If a callsite argument use is nofree, we are fine.
4594 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
4595 *this, IRPosition::callsite_argument(*CB, ArgNo));
4596
Hideto Ueno827bade2019-12-12 12:26:30 +00004597 if (!NoCaptureAA.isAssumedNoCapture() ||
4598 !ArgNoFreeAA.isAssumedNoFree()) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004599 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004600 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004601 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004602 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004603 }
4604
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004605 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
4606 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
4607 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Hideto Ueno827bade2019-12-12 12:26:30 +00004608 Follow = true;
4609 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004610 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004611 // Unknown user for which we can not track uses further (in a way that
4612 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004613 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004614 ValidUsesOnly = false;
Hideto Ueno827bade2019-12-12 12:26:30 +00004615 return true;
4616 };
4617 A.checkForAllUses(Pred, *this, I);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004618 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004619 };
4620
4621 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004622 if (BadMallocCalls.count(&I))
4623 return true;
4624
4625 bool IsMalloc = isMallocLikeFn(&I, TLI);
4626 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
4627 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004628 BadMallocCalls.insert(&I);
4629 return true;
4630 }
4631
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004632 if (IsMalloc) {
4633 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004634 if (Size->getValue().ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004635 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004636 MallocCalls.insert(&I);
4637 return true;
4638 }
4639 } else if (IsCalloc) {
4640 bool Overflow = false;
4641 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
4642 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
4643 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004644 .ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004645 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004646 MallocCalls.insert(&I);
4647 return true;
4648 }
4649 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004650
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004651 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004652 return true;
4653 };
4654
4655 size_t NumBadMallocs = BadMallocCalls.size();
4656
4657 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4658
4659 if (NumBadMallocs != BadMallocCalls.size())
4660 return ChangeStatus::CHANGED;
4661
4662 return ChangeStatus::UNCHANGED;
4663}
4664
4665struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4666 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4667
4668 /// See AbstractAttribute::trackStatistics()
4669 void trackStatistics() const override {
4670 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004671 "Number of malloc calls converted to allocas");
4672 for (auto *C : MallocCalls)
4673 if (!BadMallocCalls.count(C))
4674 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004675 }
4676};
4677
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004678/// -------------------- Memory Behavior Attributes ----------------------------
4679/// Includes read-none, read-only, and write-only.
4680/// ----------------------------------------------------------------------------
4681struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
4682 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
4683
4684 /// See AbstractAttribute::initialize(...).
4685 void initialize(Attributor &A) override {
4686 intersectAssumedBits(BEST_STATE);
4687 getKnownStateFromValue(getIRPosition(), getState());
4688 IRAttribute::initialize(A);
4689 }
4690
4691 /// Return the memory behavior information encoded in the IR for \p IRP.
4692 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004693 BitIntegerState &State,
4694 bool IgnoreSubsumingPositions = false) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004695 SmallVector<Attribute, 2> Attrs;
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004696 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004697 for (const Attribute &Attr : Attrs) {
4698 switch (Attr.getKindAsEnum()) {
4699 case Attribute::ReadNone:
4700 State.addKnownBits(NO_ACCESSES);
4701 break;
4702 case Attribute::ReadOnly:
4703 State.addKnownBits(NO_WRITES);
4704 break;
4705 case Attribute::WriteOnly:
4706 State.addKnownBits(NO_READS);
4707 break;
4708 default:
4709 llvm_unreachable("Unexpcted attribute!");
4710 }
4711 }
4712
4713 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
4714 if (!I->mayReadFromMemory())
4715 State.addKnownBits(NO_READS);
4716 if (!I->mayWriteToMemory())
4717 State.addKnownBits(NO_WRITES);
4718 }
4719 }
4720
4721 /// See AbstractAttribute::getDeducedAttributes(...).
4722 void getDeducedAttributes(LLVMContext &Ctx,
4723 SmallVectorImpl<Attribute> &Attrs) const override {
4724 assert(Attrs.size() == 0);
4725 if (isAssumedReadNone())
4726 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
4727 else if (isAssumedReadOnly())
4728 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
4729 else if (isAssumedWriteOnly())
4730 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
4731 assert(Attrs.size() <= 1);
4732 }
4733
4734 /// See AbstractAttribute::manifest(...).
4735 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05004736 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004737
4738 // Check if we would improve the existing attributes first.
4739 SmallVector<Attribute, 4> DeducedAttrs;
4740 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
4741 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
4742 return IRP.hasAttr(Attr.getKindAsEnum(),
4743 /* IgnoreSubsumingPositions */ true);
4744 }))
4745 return ChangeStatus::UNCHANGED;
4746
4747 // Clear existing attributes.
4748 IRP.removeAttrs(AttrKinds);
4749
4750 // Use the generic manifest method.
4751 return IRAttribute::manifest(A);
4752 }
4753
4754 /// See AbstractState::getAsStr().
4755 const std::string getAsStr() const override {
4756 if (isAssumedReadNone())
4757 return "readnone";
4758 if (isAssumedReadOnly())
4759 return "readonly";
4760 if (isAssumedWriteOnly())
4761 return "writeonly";
4762 return "may-read/write";
4763 }
4764
4765 /// The set of IR attributes AAMemoryBehavior deals with.
4766 static const Attribute::AttrKind AttrKinds[3];
4767};
4768
4769const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
4770 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
4771
4772/// Memory behavior attribute for a floating value.
4773struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
4774 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4775
4776 /// See AbstractAttribute::initialize(...).
4777 void initialize(Attributor &A) override {
4778 AAMemoryBehaviorImpl::initialize(A);
4779 // Initialize the use vector with all direct uses of the associated value.
4780 for (const Use &U : getAssociatedValue().uses())
4781 Uses.insert(&U);
4782 }
4783
4784 /// See AbstractAttribute::updateImpl(...).
4785 ChangeStatus updateImpl(Attributor &A) override;
4786
4787 /// See AbstractAttribute::trackStatistics()
4788 void trackStatistics() const override {
4789 if (isAssumedReadNone())
4790 STATS_DECLTRACK_FLOATING_ATTR(readnone)
4791 else if (isAssumedReadOnly())
4792 STATS_DECLTRACK_FLOATING_ATTR(readonly)
4793 else if (isAssumedWriteOnly())
4794 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
4795 }
4796
4797private:
4798 /// Return true if users of \p UserI might access the underlying
4799 /// variable/location described by \p U and should therefore be analyzed.
4800 bool followUsersOfUseIn(Attributor &A, const Use *U,
4801 const Instruction *UserI);
4802
4803 /// Update the state according to the effect of use \p U in \p UserI.
4804 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
4805
4806protected:
4807 /// Container for (transitive) uses of the associated argument.
4808 SetVector<const Use *> Uses;
4809};
4810
4811/// Memory behavior attribute for function argument.
4812struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
4813 AAMemoryBehaviorArgument(const IRPosition &IRP)
4814 : AAMemoryBehaviorFloating(IRP) {}
4815
4816 /// See AbstractAttribute::initialize(...).
4817 void initialize(Attributor &A) override {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004818 intersectAssumedBits(BEST_STATE);
4819 const IRPosition &IRP = getIRPosition();
4820 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
4821 // can query it when we use has/getAttr. That would allow us to reuse the
4822 // initialize of the base class here.
4823 bool HasByVal =
4824 IRP.hasAttr({Attribute::ByVal}, /* IgnoreSubsumingPositions */ true);
4825 getKnownStateFromValue(IRP, getState(),
4826 /* IgnoreSubsumingPositions */ HasByVal);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004827
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004828 // Initialize the use vector with all direct uses of the associated value.
4829 Argument *Arg = getAssociatedArgument();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004830 if (!Arg || !Arg->getParent()->hasExactDefinition()) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004831 indicatePessimisticFixpoint();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004832 } else {
4833 // Initialize the use vector with all direct uses of the associated value.
4834 for (const Use &U : Arg->uses())
4835 Uses.insert(&U);
4836 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004837 }
4838
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004839 ChangeStatus manifest(Attributor &A) override {
4840 // TODO: From readattrs.ll: "inalloca parameters are always
4841 // considered written"
4842 if (hasAttr({Attribute::InAlloca})) {
4843 removeKnownBits(NO_WRITES);
4844 removeAssumedBits(NO_WRITES);
4845 }
4846 return AAMemoryBehaviorFloating::manifest(A);
4847 }
4848
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004849 /// See AbstractAttribute::trackStatistics()
4850 void trackStatistics() const override {
4851 if (isAssumedReadNone())
4852 STATS_DECLTRACK_ARG_ATTR(readnone)
4853 else if (isAssumedReadOnly())
4854 STATS_DECLTRACK_ARG_ATTR(readonly)
4855 else if (isAssumedWriteOnly())
4856 STATS_DECLTRACK_ARG_ATTR(writeonly)
4857 }
4858};
4859
4860struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
4861 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
4862 : AAMemoryBehaviorArgument(IRP) {}
4863
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004864 /// See AbstractAttribute::initialize(...).
4865 void initialize(Attributor &A) override {
4866 if (Argument *Arg = getAssociatedArgument()) {
4867 if (Arg->hasByValAttr()) {
4868 addKnownBits(NO_WRITES);
4869 removeKnownBits(NO_READS);
4870 removeAssumedBits(NO_READS);
4871 }
4872 } else {
4873 }
4874 AAMemoryBehaviorArgument::initialize(A);
4875 }
4876
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004877 /// See AbstractAttribute::updateImpl(...).
4878 ChangeStatus updateImpl(Attributor &A) override {
4879 // TODO: Once we have call site specific value information we can provide
4880 // call site specific liveness liveness information and then it makes
4881 // sense to specialize attributes for call sites arguments instead of
4882 // redirecting requests to the callee argument.
4883 Argument *Arg = getAssociatedArgument();
4884 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4885 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4886 return clampStateAndIndicateChange(
4887 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05004888 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004889 }
4890
4891 /// See AbstractAttribute::trackStatistics()
4892 void trackStatistics() const override {
4893 if (isAssumedReadNone())
4894 STATS_DECLTRACK_CSARG_ATTR(readnone)
4895 else if (isAssumedReadOnly())
4896 STATS_DECLTRACK_CSARG_ATTR(readonly)
4897 else if (isAssumedWriteOnly())
4898 STATS_DECLTRACK_CSARG_ATTR(writeonly)
4899 }
4900};
4901
4902/// Memory behavior attribute for a call site return position.
4903struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
4904 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
4905 : AAMemoryBehaviorFloating(IRP) {}
4906
4907 /// See AbstractAttribute::manifest(...).
4908 ChangeStatus manifest(Attributor &A) override {
4909 // We do not annotate returned values.
4910 return ChangeStatus::UNCHANGED;
4911 }
4912
4913 /// See AbstractAttribute::trackStatistics()
4914 void trackStatistics() const override {}
4915};
4916
4917/// An AA to represent the memory behavior function attributes.
4918struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
4919 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4920
4921 /// See AbstractAttribute::updateImpl(Attributor &A).
4922 virtual ChangeStatus updateImpl(Attributor &A) override;
4923
4924 /// See AbstractAttribute::manifest(...).
4925 ChangeStatus manifest(Attributor &A) override {
4926 Function &F = cast<Function>(getAnchorValue());
4927 if (isAssumedReadNone()) {
4928 F.removeFnAttr(Attribute::ArgMemOnly);
4929 F.removeFnAttr(Attribute::InaccessibleMemOnly);
4930 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
4931 }
4932 return AAMemoryBehaviorImpl::manifest(A);
4933 }
4934
4935 /// See AbstractAttribute::trackStatistics()
4936 void trackStatistics() const override {
4937 if (isAssumedReadNone())
4938 STATS_DECLTRACK_FN_ATTR(readnone)
4939 else if (isAssumedReadOnly())
4940 STATS_DECLTRACK_FN_ATTR(readonly)
4941 else if (isAssumedWriteOnly())
4942 STATS_DECLTRACK_FN_ATTR(writeonly)
4943 }
4944};
4945
4946/// AAMemoryBehavior attribute for call sites.
4947struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
4948 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4949
4950 /// See AbstractAttribute::initialize(...).
4951 void initialize(Attributor &A) override {
4952 AAMemoryBehaviorImpl::initialize(A);
4953 Function *F = getAssociatedFunction();
4954 if (!F || !F->hasExactDefinition())
4955 indicatePessimisticFixpoint();
4956 }
4957
4958 /// See AbstractAttribute::updateImpl(...).
4959 ChangeStatus updateImpl(Attributor &A) override {
4960 // TODO: Once we have call site specific value information we can provide
4961 // call site specific liveness liveness information and then it makes
4962 // sense to specialize attributes for call sites arguments instead of
4963 // redirecting requests to the callee argument.
4964 Function *F = getAssociatedFunction();
4965 const IRPosition &FnPos = IRPosition::function(*F);
4966 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4967 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05004968 getState(),
4969 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004970 }
4971
4972 /// See AbstractAttribute::trackStatistics()
4973 void trackStatistics() const override {
4974 if (isAssumedReadNone())
4975 STATS_DECLTRACK_CS_ATTR(readnone)
4976 else if (isAssumedReadOnly())
4977 STATS_DECLTRACK_CS_ATTR(readonly)
4978 else if (isAssumedWriteOnly())
4979 STATS_DECLTRACK_CS_ATTR(writeonly)
4980 }
4981};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00004982} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004983
4984ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
4985
4986 // The current assumed state used to determine a change.
4987 auto AssumedState = getAssumed();
4988
4989 auto CheckRWInst = [&](Instruction &I) {
4990 // If the instruction has an own memory behavior state, use it to restrict
4991 // the local state. No further analysis is required as the other memory
4992 // state is as optimistic as it gets.
4993 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
4994 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
4995 *this, IRPosition::callsite_function(ICS));
4996 intersectAssumedBits(MemBehaviorAA.getAssumed());
4997 return !isAtFixpoint();
4998 }
4999
5000 // Remove access kind modifiers if necessary.
5001 if (I.mayReadFromMemory())
5002 removeAssumedBits(NO_READS);
5003 if (I.mayWriteToMemory())
5004 removeAssumedBits(NO_WRITES);
5005 return !isAtFixpoint();
5006 };
5007
5008 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
5009 return indicatePessimisticFixpoint();
5010
5011 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5012 : ChangeStatus::UNCHANGED;
5013}
5014
5015ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
5016
5017 const IRPosition &IRP = getIRPosition();
5018 const IRPosition &FnPos = IRPosition::function_scope(IRP);
5019 AAMemoryBehavior::StateType &S = getState();
5020
5021 // First, check the function scope. We take the known information and we avoid
5022 // work if the assumed information implies the current assumed information for
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005023 // this attribute. This is a valid for all but byval arguments.
5024 Argument *Arg = IRP.getAssociatedArgument();
5025 AAMemoryBehavior::base_t FnMemAssumedState =
5026 AAMemoryBehavior::StateType::getWorstState();
5027 if (!Arg || !Arg->hasByValAttr()) {
5028 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
5029 FnMemAssumedState = FnMemAA.getAssumed();
5030 S.addKnownBits(FnMemAA.getKnown());
5031 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
5032 return ChangeStatus::UNCHANGED;
5033 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005034
5035 // Make sure the value is not captured (except through "return"), if
5036 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005037 // check the potential aliases introduced by the capture. However, no need
5038 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert28880192019-12-31 00:57:00 -06005039 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
5040 *this, IRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005041 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005042 S.intersectAssumedBits(FnMemAssumedState);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005043 return ChangeStatus::CHANGED;
5044 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005045
5046 // The current assumed state used to determine a change.
5047 auto AssumedState = S.getAssumed();
5048
5049 // Liveness information to exclude dead users.
5050 // TODO: Take the FnPos once we have call site specific liveness information.
5051 const auto &LivenessAA = A.getAAFor<AAIsDead>(
5052 *this, IRPosition::function(*IRP.getAssociatedFunction()));
5053
5054 // Visit and expand uses until all are analyzed or a fixpoint is reached.
5055 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
5056 const Use *U = Uses[i];
5057 Instruction *UserI = cast<Instruction>(U->getUser());
5058 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
5059 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
5060 << "]\n");
5061 if (LivenessAA.isAssumedDead(UserI))
5062 continue;
5063
5064 // Check if the users of UserI should also be visited.
5065 if (followUsersOfUseIn(A, U, UserI))
5066 for (const Use &UserIUse : UserI->uses())
5067 Uses.insert(&UserIUse);
5068
5069 // If UserI might touch memory we analyze the use in detail.
5070 if (UserI->mayReadOrWriteMemory())
5071 analyzeUseIn(A, U, UserI);
5072 }
5073
5074 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5075 : ChangeStatus::UNCHANGED;
5076}
5077
5078bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
5079 const Instruction *UserI) {
5080 // The loaded value is unrelated to the pointer argument, no need to
5081 // follow the users of the load.
5082 if (isa<LoadInst>(UserI))
5083 return false;
5084
5085 // By default we follow all uses assuming UserI might leak information on U,
5086 // we have special handling for call sites operands though.
5087 ImmutableCallSite ICS(UserI);
5088 if (!ICS || !ICS.isArgOperand(U))
5089 return true;
5090
5091 // If the use is a call argument known not to be captured, the users of
5092 // the call do not need to be visited because they have to be unrelated to
5093 // the input. Note that this check is not trivial even though we disallow
5094 // general capturing of the underlying argument. The reason is that the
5095 // call might the argument "through return", which we allow and for which we
5096 // need to check call users.
5097 unsigned ArgNo = ICS.getArgumentNo(U);
5098 const auto &ArgNoCaptureAA =
5099 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
5100 return !ArgNoCaptureAA.isAssumedNoCapture();
5101}
5102
5103void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
5104 const Instruction *UserI) {
5105 assert(UserI->mayReadOrWriteMemory());
5106
5107 switch (UserI->getOpcode()) {
5108 default:
5109 // TODO: Handle all atomics and other side-effect operations we know of.
5110 break;
5111 case Instruction::Load:
5112 // Loads cause the NO_READS property to disappear.
5113 removeAssumedBits(NO_READS);
5114 return;
5115
5116 case Instruction::Store:
5117 // Stores cause the NO_WRITES property to disappear if the use is the
5118 // pointer operand. Note that we do assume that capturing was taken care of
5119 // somewhere else.
5120 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
5121 removeAssumedBits(NO_WRITES);
5122 return;
5123
5124 case Instruction::Call:
5125 case Instruction::CallBr:
5126 case Instruction::Invoke: {
5127 // For call sites we look at the argument memory behavior attribute (this
5128 // could be recursive!) in order to restrict our own state.
5129 ImmutableCallSite ICS(UserI);
5130
5131 // Give up on operand bundles.
5132 if (ICS.isBundleOperand(U)) {
5133 indicatePessimisticFixpoint();
5134 return;
5135 }
5136
5137 // Calling a function does read the function pointer, maybe write it if the
5138 // function is self-modifying.
5139 if (ICS.isCallee(U)) {
5140 removeAssumedBits(NO_READS);
5141 break;
5142 }
5143
5144 // Adjust the possible access behavior based on the information on the
5145 // argument.
5146 unsigned ArgNo = ICS.getArgumentNo(U);
5147 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
5148 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
5149 // "assumed" has at most the same bits as the MemBehaviorAA assumed
5150 // and at least "known".
5151 intersectAssumedBits(MemBehaviorAA.getAssumed());
5152 return;
5153 }
5154 };
5155
5156 // Generally, look at the "may-properties" and adjust the assumed state if we
5157 // did not trigger special handling before.
5158 if (UserI->mayReadFromMemory())
5159 removeAssumedBits(NO_READS);
5160 if (UserI->mayWriteToMemory())
5161 removeAssumedBits(NO_WRITES);
5162}
Hideto Uenoe9963032020-01-01 15:25:19 +09005163
Johannes Doerfertaade7822019-06-05 03:02:24 +00005164/// ----------------------------------------------------------------------------
5165/// Attributor
5166/// ----------------------------------------------------------------------------
5167
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005168bool Attributor::isAssumedDead(const AbstractAttribute &AA,
5169 const AAIsDead *LivenessAA) {
5170 const Instruction *CtxI = AA.getIRPosition().getCtxI();
5171 if (!CtxI)
5172 return false;
5173
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005174 // TODO: Find a good way to utilize fine and coarse grained liveness
5175 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005176 if (!LivenessAA)
5177 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00005178 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
5179 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00005180
5181 // Don't check liveness for AAIsDead.
5182 if (&AA == LivenessAA)
5183 return false;
5184
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005185 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005186 return false;
5187
Johannes Doerfert19b00432019-08-26 17:48:05 +00005188 // We actually used liveness information so we have to record a dependence.
Johannes Doerfert680f6382019-11-02 02:48:05 -05005189 recordDependence(*LivenessAA, AA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005190
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005191 return true;
5192}
5193
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005194bool Attributor::checkForAllUses(
5195 const function_ref<bool(const Use &, bool &)> &Pred,
5196 const AbstractAttribute &QueryingAA, const Value &V) {
5197 const IRPosition &IRP = QueryingAA.getIRPosition();
5198 SmallVector<const Use *, 16> Worklist;
5199 SmallPtrSet<const Use *, 16> Visited;
5200
5201 for (const Use &U : V.uses())
5202 Worklist.push_back(&U);
5203
5204 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
5205 << " initial uses to check\n");
5206
5207 if (Worklist.empty())
5208 return true;
5209
5210 bool AnyDead = false;
5211 const Function *ScopeFn = IRP.getAnchorScope();
5212 const auto *LivenessAA =
5213 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
5214 /* TrackDependence */ false)
5215 : nullptr;
5216
5217 while (!Worklist.empty()) {
5218 const Use *U = Worklist.pop_back_val();
5219 if (!Visited.insert(U).second)
5220 continue;
5221 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << "\n");
5222 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser()))
5223 if (LivenessAA && LivenessAA->isAssumedDead(UserI)) {
5224 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06005225 << *LivenessAA << "\n");
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005226 AnyDead = true;
5227 continue;
5228 }
5229
5230 bool Follow = false;
5231 if (!Pred(*U, Follow))
5232 return false;
5233 if (!Follow)
5234 continue;
5235 for (const Use &UU : U->getUser()->uses())
5236 Worklist.push_back(&UU);
5237 }
5238
5239 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005240 recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005241
5242 return true;
5243}
5244
Johannes Doerfert661db042019-10-07 23:14:58 +00005245bool Attributor::checkForAllCallSites(
5246 const function_ref<bool(AbstractCallSite)> &Pred,
5247 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005248 // We can try to determine information from
5249 // the call sites. However, this is only possible all call sites are known,
5250 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005251 const IRPosition &IRP = QueryingAA.getIRPosition();
5252 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00005253 if (!AssociatedFunction) {
5254 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
5255 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005256 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00005257 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005258
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005259 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
5260 &QueryingAA);
5261}
5262
5263bool Attributor::checkForAllCallSites(
5264 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
5265 bool RequireAllCallSites, const AbstractAttribute *QueryingAA) {
5266 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005267 LLVM_DEBUG(
5268 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005269 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00005270 << " has no internal linkage, hence not all call sites are known\n");
5271 return false;
5272 }
5273
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005274 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00005275 AbstractCallSite ACS(&U);
5276 if (!ACS) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005277 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00005278 << " has non call site use " << *U.get() << " in "
5279 << *U.getUser() << "\n");
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05005280 // BlockAddress users are allowed.
5281 if (isa<BlockAddress>(U.getUser()))
5282 continue;
Johannes Doerfertd98f9752019-08-21 21:48:56 +00005283 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00005284 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00005285
Johannes Doerfert661db042019-10-07 23:14:58 +00005286 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005287 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005288
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005289 const auto *LivenessAA =
5290 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005291 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005292
5293 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005294 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00005295 // We actually used liveness information so we have to record a
5296 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005297 if (QueryingAA)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005298 recordDependence(*LivenessAA, *QueryingAA, DepClassTy::OPTIONAL);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005299 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00005300 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00005301
Johannes Doerfert661db042019-10-07 23:14:58 +00005302 const Use *EffectiveUse =
5303 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
5304 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005305 if (!RequireAllCallSites)
5306 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00005307 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005308 << " is an invalid use of " << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00005309 return false;
5310 }
5311
Johannes Doerfert661db042019-10-07 23:14:58 +00005312 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00005313 continue;
5314
Johannes Doerfert5304b722019-08-14 22:04:28 +00005315 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00005316 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00005317 return false;
5318 }
5319
5320 return true;
5321}
5322
Johannes Doerfert14a04932019-08-07 22:27:24 +00005323bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00005324 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00005325 &Pred,
5326 const AbstractAttribute &QueryingAA) {
5327
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005328 const IRPosition &IRP = QueryingAA.getIRPosition();
5329 // Since we need to provide return instructions we have to have an exact
5330 // definition.
5331 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005332 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00005333 return false;
5334
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005335 // If this is a call site query we use the call site specific return values
5336 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005337 // TODO: use the function scope once we have call site AAReturnedValues.
5338 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005339 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005340 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005341 return false;
5342
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005343 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00005344}
5345
5346bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005347 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00005348 const AbstractAttribute &QueryingAA) {
5349
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005350 const IRPosition &IRP = QueryingAA.getIRPosition();
5351 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005352 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00005353 return false;
5354
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005355 // TODO: use the function scope once we have call site AAReturnedValues.
5356 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005357 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005358 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005359 return false;
5360
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005361 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00005362 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00005363 return Pred(RV);
5364 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00005365}
5366
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005367static bool
5368checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
5369 const function_ref<bool(Instruction &)> &Pred,
5370 const AAIsDead *LivenessAA, bool &AnyDead,
5371 const ArrayRef<unsigned> &Opcodes) {
5372 for (unsigned Opcode : Opcodes) {
5373 for (Instruction *I : OpcodeInstMap[Opcode]) {
5374 // Skip dead instructions.
5375 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
5376 AnyDead = true;
5377 continue;
5378 }
5379
5380 if (!Pred(*I))
5381 return false;
5382 }
5383 }
5384 return true;
5385}
5386
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005387bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005388 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00005389 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005390
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005391 const IRPosition &IRP = QueryingAA.getIRPosition();
5392 // Since we need to provide instructions we have to have an exact definition.
5393 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005394 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005395 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005396
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005397 // TODO: use the function scope once we have call site AAReturnedValues.
5398 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005399 const auto &LivenessAA =
5400 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
5401 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005402
5403 auto &OpcodeInstMap =
5404 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005405 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
5406 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005407 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005408
Johannes Doerfert19b00432019-08-26 17:48:05 +00005409 // If we actually used liveness information so we have to record a dependence.
5410 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005411 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005412
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005413 return true;
5414}
5415
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005416bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005417 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00005418 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005419
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005420 const Function *AssociatedFunction =
5421 QueryingAA.getIRPosition().getAssociatedFunction();
5422 if (!AssociatedFunction)
5423 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005424
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005425 // TODO: use the function scope once we have call site AAReturnedValues.
5426 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
5427 const auto &LivenessAA =
5428 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005429 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005430
5431 for (Instruction *I :
5432 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005433 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00005434 if (LivenessAA.isAssumedDead(I)) {
5435 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005436 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00005437 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005438
5439 if (!Pred(*I))
5440 return false;
5441 }
5442
Johannes Doerfert19b00432019-08-26 17:48:05 +00005443 // If we actually used liveness information so we have to record a dependence.
5444 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005445 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005446
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005447 return true;
5448}
5449
Johannes Doerfert2f622062019-09-04 16:35:20 +00005450ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005451 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
5452 << AllAbstractAttributes.size()
5453 << " abstract attributes.\n");
5454
Stefan Stipanovic53605892019-06-27 11:27:54 +00005455 // Now that all abstract attributes are collected and initialized we start
5456 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00005457
5458 unsigned IterationCounter = 1;
5459
5460 SmallVector<AbstractAttribute *, 64> ChangedAAs;
Johannes Doerfert680f6382019-11-02 02:48:05 -05005461 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005462 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
5463
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005464 bool RecomputeDependences = false;
5465
Johannes Doerfertaade7822019-06-05 03:02:24 +00005466 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005467 // Remember the size to determine new attributes.
5468 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005469 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
5470 << ", Worklist size: " << Worklist.size() << "\n");
5471
Johannes Doerfert680f6382019-11-02 02:48:05 -05005472 // For invalid AAs we can fix dependent AAs that have a required dependence,
5473 // thereby folding long dependence chains in a single step without the need
5474 // to run updates.
5475 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
5476 AbstractAttribute *InvalidAA = InvalidAAs[u];
5477 auto &QuerriedAAs = QueryMap[InvalidAA];
5478 LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
5479 << QuerriedAAs.RequiredAAs.size() << "/"
5480 << QuerriedAAs.OptionalAAs.size()
5481 << " required/optional dependences\n");
5482 for (AbstractAttribute *DepOnInvalidAA : QuerriedAAs.RequiredAAs) {
5483 AbstractState &DOIAAState = DepOnInvalidAA->getState();
5484 DOIAAState.indicatePessimisticFixpoint();
5485 ++NumAttributesFixedDueToRequiredDependences;
5486 assert(DOIAAState.isAtFixpoint() && "Expected fixpoint state!");
5487 if (!DOIAAState.isValidState())
5488 InvalidAAs.insert(DepOnInvalidAA);
5489 }
5490 if (!RecomputeDependences)
5491 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
5492 QuerriedAAs.OptionalAAs.end());
5493 }
5494
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005495 // If dependences (=QueryMap) are recomputed we have to look at all abstract
5496 // attributes again, regardless of what changed in the last iteration.
5497 if (RecomputeDependences) {
5498 LLVM_DEBUG(
5499 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
5500 QueryMap.clear();
5501 ChangedAAs.clear();
5502 Worklist.insert(AllAbstractAttributes.begin(),
5503 AllAbstractAttributes.end());
5504 }
5505
Johannes Doerfertaade7822019-06-05 03:02:24 +00005506 // Add all abstract attributes that are potentially dependent on one that
5507 // changed to the work list.
5508 for (AbstractAttribute *ChangedAA : ChangedAAs) {
5509 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05005510 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
5511 QuerriedAAs.OptionalAAs.end());
5512 Worklist.insert(QuerriedAAs.RequiredAAs.begin(),
5513 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00005514 }
5515
Johannes Doerfertb504eb82019-08-26 18:55:47 +00005516 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
5517 << ", Worklist+Dependent size: " << Worklist.size()
5518 << "\n");
5519
Johannes Doerfert680f6382019-11-02 02:48:05 -05005520 // Reset the changed and invalid set.
Johannes Doerfertaade7822019-06-05 03:02:24 +00005521 ChangedAAs.clear();
Johannes Doerfert680f6382019-11-02 02:48:05 -05005522 InvalidAAs.clear();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005523
5524 // Update all abstract attribute in the work list and record the ones that
5525 // changed.
5526 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005527 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
5528 QueriedNonFixAA = false;
5529 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005530 ChangedAAs.push_back(AA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05005531 if (!AA->getState().isValidState())
5532 InvalidAAs.insert(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005533 } else if (!QueriedNonFixAA) {
5534 // If the attribute did not query any non-fix information, the state
5535 // will not change and we can indicate that right away.
5536 AA->getState().indicateOptimisticFixpoint();
5537 }
5538 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00005539
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005540 // Check if we recompute the dependences in the next iteration.
5541 RecomputeDependences = (DepRecomputeInterval > 0 &&
5542 IterationCounter % DepRecomputeInterval == 0);
5543
Johannes Doerfert9543f142019-08-23 15:24:57 +00005544 // Add attributes to the changed set if they have been created in the last
5545 // iteration.
5546 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
5547 AllAbstractAttributes.end());
5548
Johannes Doerfertaade7822019-06-05 03:02:24 +00005549 // Reset the work list and repopulate with the changed abstract attributes.
5550 // Note that dependent ones are added above.
5551 Worklist.clear();
5552 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
5553
Johannes Doerfertbf112132019-08-29 01:29:44 +00005554 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
5555 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005556
Johannes Doerfertaade7822019-06-05 03:02:24 +00005557 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
5558 << IterationCounter << "/" << MaxFixpointIterations
5559 << " iterations\n");
5560
Johannes Doerfertbf112132019-08-29 01:29:44 +00005561 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00005562
Johannes Doerfertaade7822019-06-05 03:02:24 +00005563 // Reset abstract arguments not settled in a sound fixpoint by now. This
5564 // happens when we stopped the fixpoint iteration early. Note that only the
5565 // ones marked as "changed" *and* the ones transitively depending on them
5566 // need to be reverted to a pessimistic state. Others might not be in a
5567 // fixpoint state but we can use the optimistic results for them anyway.
5568 SmallPtrSet<AbstractAttribute *, 32> Visited;
5569 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
5570 AbstractAttribute *ChangedAA = ChangedAAs[u];
5571 if (!Visited.insert(ChangedAA).second)
5572 continue;
5573
5574 AbstractState &State = ChangedAA->getState();
5575 if (!State.isAtFixpoint()) {
5576 State.indicatePessimisticFixpoint();
5577
5578 NumAttributesTimedOut++;
5579 }
5580
5581 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05005582 ChangedAAs.append(QuerriedAAs.OptionalAAs.begin(),
5583 QuerriedAAs.OptionalAAs.end());
5584 ChangedAAs.append(QuerriedAAs.RequiredAAs.begin(),
5585 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00005586 }
5587
5588 LLVM_DEBUG({
5589 if (!Visited.empty())
5590 dbgs() << "\n[Attributor] Finalized " << Visited.size()
5591 << " abstract attributes.\n";
5592 });
5593
5594 unsigned NumManifested = 0;
5595 unsigned NumAtFixpoint = 0;
5596 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
5597 for (AbstractAttribute *AA : AllAbstractAttributes) {
5598 AbstractState &State = AA->getState();
5599
5600 // If there is not already a fixpoint reached, we can now take the
5601 // optimistic state. This is correct because we enforced a pessimistic one
5602 // on abstract attributes that were transitively dependent on a changed one
5603 // already above.
5604 if (!State.isAtFixpoint())
5605 State.indicateOptimisticFixpoint();
5606
5607 // If the state is invalid, we do not try to manifest it.
5608 if (!State.isValidState())
5609 continue;
5610
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005611 // Skip dead code.
5612 if (isAssumedDead(*AA, nullptr))
5613 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005614 // Manifest the state and record if we changed the IR.
5615 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00005616 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
5617 AA->trackStatistics();
5618
Johannes Doerfertaade7822019-06-05 03:02:24 +00005619 ManifestChange = ManifestChange | LocalChange;
5620
5621 NumAtFixpoint++;
5622 NumManifested += (LocalChange == ChangeStatus::CHANGED);
5623 }
5624
5625 (void)NumManifested;
5626 (void)NumAtFixpoint;
5627 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
5628 << " arguments while " << NumAtFixpoint
5629 << " were in a valid fixpoint state\n");
5630
Johannes Doerfertaade7822019-06-05 03:02:24 +00005631 NumAttributesManifested += NumManifested;
5632 NumAttributesValidFixpoint += NumAtFixpoint;
5633
Fangrui Songf1826172019-08-20 07:21:43 +00005634 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005635 assert(
5636 NumFinalAAs == AllAbstractAttributes.size() &&
5637 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00005638
5639 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00005640 {
5641 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
5642 << ToBeDeletedFunctions.size() << " functions and "
5643 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005644 << ToBeDeletedInsts.size() << " instructions and "
5645 << ToBeChangedUses.size() << " uses\n");
5646
5647 SmallVector<Instruction *, 32> DeadInsts;
5648 SmallVector<Instruction *, 32> TerminatorsToFold;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005649
5650 for (auto &It : ToBeChangedUses) {
5651 Use *U = It.first;
5652 Value *NewV = It.second;
5653 Value *OldV = U->get();
5654 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
5655 << " instead of " << *OldV << "\n");
5656 U->set(NewV);
5657 if (Instruction *I = dyn_cast<Instruction>(OldV))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005658 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
5659 isInstructionTriviallyDead(I)) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005660 DeadInsts.push_back(I);
5661 }
5662 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
5663 Instruction *UserI = cast<Instruction>(U->getUser());
5664 if (isa<UndefValue>(NewV)) {
Hideto Uenocb5eb132019-12-27 02:39:37 +09005665 ToBeChangedToUnreachableInsts.insert(UserI);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005666 } else {
5667 TerminatorsToFold.push_back(UserI);
5668 }
5669 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00005670 }
Hideto Uenocb5eb132019-12-27 02:39:37 +09005671 for (Instruction *I : ToBeChangedToUnreachableInsts)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005672 changeToUnreachable(I, /* UseLLVMTrap */ false);
5673 for (Instruction *I : TerminatorsToFold)
5674 ConstantFoldTerminator(I->getParent());
5675
5676 for (Instruction *I : ToBeDeletedInsts) {
5677 I->replaceAllUsesWith(UndefValue::get(I->getType()));
5678 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
5679 DeadInsts.push_back(I);
5680 else
5681 I->eraseFromParent();
5682 }
5683
5684 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005685
Johannes Doerfert2f622062019-09-04 16:35:20 +00005686 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
5687 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
5688 ToBeDeletedBBs.reserve(NumDeadBlocks);
5689 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
Johannes Doerfert5e442a52019-10-30 17:34:59 -05005690 // Actually we do not delete the blocks but squash them into a single
5691 // unreachable but untangling branches that jump here is something we need
5692 // to do in a more generic way.
5693 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
5694 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
5695 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00005696 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005697
Johannes Doerfert2f622062019-09-04 16:35:20 +00005698 // Identify dead internal functions and delete them. This happens outside
5699 // the other fixpoint analysis as we might treat potentially dead functions
5700 // as live to lower the number of iterations. If they happen to be dead, the
5701 // below fixpoint loop will identify and eliminate them.
5702 SmallVector<Function *, 8> InternalFns;
5703 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005704 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00005705 InternalFns.push_back(&F);
5706
5707 bool FoundDeadFn = true;
5708 while (FoundDeadFn) {
5709 FoundDeadFn = false;
5710 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
5711 Function *F = InternalFns[u];
5712 if (!F)
5713 continue;
5714
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06005715 if (!checkForAllCallSites(
5716 [this](AbstractCallSite ACS) {
5717 return ToBeDeletedFunctions.count(
5718 ACS.getInstruction()->getFunction());
5719 },
5720 *F, true, nullptr))
Johannes Doerfert2f622062019-09-04 16:35:20 +00005721 continue;
5722
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005723 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00005724 InternalFns[u] = nullptr;
5725 FoundDeadFn = true;
5726 }
5727 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00005728 }
5729
Johannes Doerfert75133632019-10-10 01:39:16 -05005730 // Rewrite the functions as requested during manifest.
5731 ManifestChange = ManifestChange | rewriteFunctionSignatures();
5732
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06005733 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
5734 BUILD_STAT_NAME(AAIsDead, Function) += ToBeDeletedFunctions.size();
5735 for (Function *Fn : ToBeDeletedFunctions) {
5736 Fn->deleteBody();
5737 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
5738 Fn->eraseFromParent();
5739 }
5740
Johannes Doerfertbf112132019-08-29 01:29:44 +00005741 if (VerifyMaxFixpointIterations &&
5742 IterationCounter != MaxFixpointIterations) {
5743 errs() << "\n[Attributor] Fixpoint iteration done after: "
5744 << IterationCounter << "/" << MaxFixpointIterations
5745 << " iterations\n";
5746 llvm_unreachable("The fixpoint was not reached with exactly the number of "
5747 "specified iterations!");
5748 }
5749
Johannes Doerfertaade7822019-06-05 03:02:24 +00005750 return ManifestChange;
5751}
5752
Johannes Doerfert75133632019-10-10 01:39:16 -05005753bool Attributor::registerFunctionSignatureRewrite(
5754 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
5755 ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,
5756 ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {
5757
5758 auto CallSiteCanBeChanged = [](AbstractCallSite ACS) {
5759 // Forbid must-tail calls for now.
5760 return !ACS.isCallbackCall() && !ACS.getCallSite().isMustTailCall();
5761 };
5762
5763 Function *Fn = Arg.getParent();
5764 // Avoid var-arg functions for now.
5765 if (Fn->isVarArg()) {
5766 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
5767 return false;
5768 }
5769
5770 // Avoid functions with complicated argument passing semantics.
5771 AttributeList FnAttributeList = Fn->getAttributes();
5772 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
5773 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
5774 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca)) {
5775 LLVM_DEBUG(
5776 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
5777 return false;
5778 }
5779
5780 // Avoid callbacks for now.
5781 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr)) {
5782 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
5783 return false;
5784 }
5785
5786 auto InstPred = [](Instruction &I) {
5787 if (auto *CI = dyn_cast<CallInst>(&I))
5788 return !CI->isMustTailCall();
5789 return true;
5790 };
5791
5792 // Forbid must-tail calls for now.
5793 // TODO:
5794 bool AnyDead;
5795 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
5796 if (!checkForAllInstructionsImpl(OpcodeInstMap, InstPred, nullptr, AnyDead,
5797 {Instruction::Call})) {
5798 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
5799 return false;
5800 }
5801
5802 SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = ArgumentReplacementMap[Fn];
5803 if (ARIs.size() == 0)
5804 ARIs.resize(Fn->arg_size());
5805
5806 // If we have a replacement already with less than or equal new arguments,
5807 // ignore this request.
5808 ArgumentReplacementInfo *&ARI = ARIs[Arg.getArgNo()];
5809 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
5810 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
5811 return false;
5812 }
5813
5814 // If we have a replacement already but we like the new one better, delete
5815 // the old.
5816 if (ARI)
5817 delete ARI;
5818
5819 // Remember the replacement.
5820 ARI = new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
5821 std::move(CalleeRepairCB),
5822 std::move(ACSRepairCB));
5823
5824 return true;
5825}
5826
5827ChangeStatus Attributor::rewriteFunctionSignatures() {
5828 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5829
5830 for (auto &It : ArgumentReplacementMap) {
5831 Function *OldFn = It.getFirst();
5832
5833 // Deleted functions do not require rewrites.
5834 if (ToBeDeletedFunctions.count(OldFn))
5835 continue;
5836
5837 const SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = It.getSecond();
5838 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
5839
5840 SmallVector<Type *, 16> NewArgumentTypes;
5841 SmallVector<AttributeSet, 16> NewArgumentAttributes;
5842
5843 // Collect replacement argument types and copy over existing attributes.
5844 AttributeList OldFnAttributeList = OldFn->getAttributes();
5845 for (Argument &Arg : OldFn->args()) {
5846 if (ArgumentReplacementInfo *ARI = ARIs[Arg.getArgNo()]) {
5847 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
5848 ARI->ReplacementTypes.end());
5849 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
5850 AttributeSet());
5851 } else {
5852 NewArgumentTypes.push_back(Arg.getType());
5853 NewArgumentAttributes.push_back(
5854 OldFnAttributeList.getParamAttributes(Arg.getArgNo()));
5855 }
5856 }
5857
5858 FunctionType *OldFnTy = OldFn->getFunctionType();
5859 Type *RetTy = OldFnTy->getReturnType();
5860
5861 // Construct the new function type using the new arguments types.
5862 FunctionType *NewFnTy =
5863 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
5864
5865 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
5866 << "' from " << *OldFn->getFunctionType() << " to "
5867 << *NewFnTy << "\n");
5868
5869 // Create the new function body and insert it into the module.
5870 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
5871 OldFn->getAddressSpace(), "");
5872 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
5873 NewFn->takeName(OldFn);
5874 NewFn->copyAttributesFrom(OldFn);
5875
5876 // Patch the pointer to LLVM function in debug info descriptor.
5877 NewFn->setSubprogram(OldFn->getSubprogram());
5878 OldFn->setSubprogram(nullptr);
5879
5880 // Recompute the parameter attributes list based on the new arguments for
5881 // the function.
5882 LLVMContext &Ctx = OldFn->getContext();
5883 NewFn->setAttributes(AttributeList::get(
5884 Ctx, OldFnAttributeList.getFnAttributes(),
5885 OldFnAttributeList.getRetAttributes(), NewArgumentAttributes));
5886
5887 // Since we have now created the new function, splice the body of the old
5888 // function right into the new function, leaving the old rotting hulk of the
5889 // function empty.
5890 NewFn->getBasicBlockList().splice(NewFn->begin(),
5891 OldFn->getBasicBlockList());
5892
5893 // Set of all "call-like" instructions that invoke the old function.
5894 SmallPtrSet<Instruction *, 8> OldCallSites;
5895
5896 // Callback to create a new "call-like" instruction for a given one.
5897 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
5898 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
5899 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
5900
5901 // Collect the new argument operands for the replacement call site.
5902 SmallVector<Value *, 16> NewArgOperands;
5903 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
5904 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
5905 unsigned NewFirstArgNum = NewArgOperands.size();
Ilya Biryukov4f82af82019-12-31 10:21:52 +01005906 (void)NewFirstArgNum; // only used inside assert.
Johannes Doerfert75133632019-10-10 01:39:16 -05005907 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
5908 if (ARI->ACSRepairCB)
5909 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
5910 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
5911 NewArgOperands.size() &&
5912 "ACS repair callback did not provide as many operand as new "
5913 "types were registered!");
5914 // TODO: Exose the attribute set to the ACS repair callback
5915 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
5916 AttributeSet());
5917 } else {
5918 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
5919 NewArgOperandAttributes.push_back(
5920 OldCallAttributeList.getParamAttributes(OldArgNum));
5921 }
5922 }
5923
5924 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
5925 "Mismatch # argument operands vs. # argument operand attributes!");
5926 assert(NewArgOperands.size() == NewFn->arg_size() &&
5927 "Mismatch # argument operands vs. # function arguments!");
5928
5929 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
5930 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
5931
5932 // Create a new call or invoke instruction to replace the old one.
5933 CallBase *NewCB;
5934 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
5935 NewCB =
5936 InvokeInst::Create(NewFn, II->getNormalDest(), II->getUnwindDest(),
5937 NewArgOperands, OperandBundleDefs, "", OldCB);
5938 } else {
5939 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
5940 "", OldCB);
5941 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
5942 NewCB = NewCI;
5943 }
5944
5945 // Copy over various properties and the new attributes.
5946 OldCB->replaceAllUsesWith(NewCB);
5947 uint64_t W;
5948 if (OldCB->extractProfTotalWeight(W))
5949 NewCB->setProfWeight(W);
5950 NewCB->setCallingConv(OldCB->getCallingConv());
5951 NewCB->setDebugLoc(OldCB->getDebugLoc());
5952 NewCB->takeName(OldCB);
5953 NewCB->setAttributes(AttributeList::get(
5954 Ctx, OldCallAttributeList.getFnAttributes(),
5955 OldCallAttributeList.getRetAttributes(), NewArgOperandAttributes));
5956
5957 bool Inserted = OldCallSites.insert(OldCB).second;
5958 assert(Inserted && "Call site was old twice!");
5959 (void)Inserted;
5960
5961 return true;
5962 };
5963
5964 // Use the CallSiteReplacementCreator to create replacement call sites.
5965 bool Success =
5966 checkForAllCallSites(CallSiteReplacementCreator, *OldFn, true, nullptr);
Ilya Biryukov4f82af82019-12-31 10:21:52 +01005967 (void)Success;
Johannes Doerfert75133632019-10-10 01:39:16 -05005968 assert(Success && "Assumed call site replacement to succeed!");
5969
5970 // Rewire the arguments.
5971 auto OldFnArgIt = OldFn->arg_begin();
5972 auto NewFnArgIt = NewFn->arg_begin();
5973 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
5974 ++OldArgNum, ++OldFnArgIt) {
5975 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
5976 if (ARI->CalleeRepairCB)
5977 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
5978 NewFnArgIt += ARI->ReplacementTypes.size();
5979 } else {
5980 NewFnArgIt->takeName(&*OldFnArgIt);
5981 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
5982 ++NewFnArgIt;
5983 }
5984 }
5985
5986 // Eliminate the instructions *after* we visited all of them.
5987 for (Instruction *OldCallSite : OldCallSites)
5988 OldCallSite->eraseFromParent();
5989
5990 assert(OldFn->getNumUses() == 0 && "Unexpected leftover uses!");
5991 OldFn->eraseFromParent();
5992 Changed = ChangeStatus::CHANGED;
5993 }
5994
5995 return Changed;
5996}
5997
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005998void Attributor::initializeInformationCache(Function &F) {
5999
6000 // Walk all instructions to find interesting instructions that might be
6001 // queried by abstract attributes during their initialization or update.
6002 // This has to happen before we create attributes.
6003 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
6004 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
6005
6006 for (Instruction &I : instructions(&F)) {
6007 bool IsInterestingOpcode = false;
6008
6009 // To allow easy access to all instructions in a function with a given
6010 // opcode we store them in the InfoCache. As not all opcodes are interesting
6011 // to concrete attributes we only cache the ones that are as identified in
6012 // the following switch.
6013 // Note: There are no concrete attributes now so this is initially empty.
6014 switch (I.getOpcode()) {
6015 default:
6016 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
6017 "New call site/base instruction type needs to be known int the "
6018 "Attributor.");
6019 break;
6020 case Instruction::Load:
6021 // The alignment of a pointer is interesting for loads.
6022 case Instruction::Store:
6023 // The alignment of a pointer is interesting for stores.
6024 case Instruction::Call:
6025 case Instruction::CallBr:
6026 case Instruction::Invoke:
6027 case Instruction::CleanupRet:
6028 case Instruction::CatchSwitch:
Johannes Doerfert5732f562019-12-24 19:25:08 -06006029 case Instruction::AtomicRMW:
6030 case Instruction::AtomicCmpXchg:
Hideto Uenoef4febd2019-12-29 17:34:08 +09006031 case Instruction::Br:
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006032 case Instruction::Resume:
6033 case Instruction::Ret:
6034 IsInterestingOpcode = true;
6035 }
6036 if (IsInterestingOpcode)
6037 InstOpcodeMap[I.getOpcode()].push_back(&I);
6038 if (I.mayReadOrWriteMemory())
6039 ReadOrWriteInsts.push_back(&I);
6040 }
6041}
6042
Johannes Doerfert12173e62019-10-13 20:25:25 -05006043void Attributor::recordDependence(const AbstractAttribute &FromAA,
Johannes Doerfert680f6382019-11-02 02:48:05 -05006044 const AbstractAttribute &ToAA,
6045 DepClassTy DepClass) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006046 if (FromAA.getState().isAtFixpoint())
6047 return;
6048
Johannes Doerfert680f6382019-11-02 02:48:05 -05006049 if (DepClass == DepClassTy::REQUIRED)
6050 QueryMap[&FromAA].RequiredAAs.insert(
6051 const_cast<AbstractAttribute *>(&ToAA));
6052 else
6053 QueryMap[&FromAA].OptionalAAs.insert(
6054 const_cast<AbstractAttribute *>(&ToAA));
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006055 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05006056}
6057
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006058void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00006059 if (!VisitedFunctions.insert(&F).second)
6060 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006061 if (F.isDeclaration())
6062 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006063
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006064 IRPosition FPos = IRPosition::function(F);
6065
Johannes Doerfert305b9612019-08-04 18:40:01 +00006066 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00006067 // We need dead instruction detection because we do not want to deal with
6068 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006069 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00006070
6071 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006072 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00006073
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006074 // Every function might contain instructions that cause "undefined behavior".
6075 getOrCreateAAFor<AAUndefinedBehavior>(FPos);
6076
Stefan Stipanovic53605892019-06-27 11:27:54 +00006077 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006078 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00006079
Stefan Stipanovic06263672019-07-11 21:37:40 +00006080 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006081 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00006082
Hideto Ueno65bbaf92019-07-12 17:38:51 +00006083 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006084 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00006085
Johannes Doerferte83f3032019-08-05 23:22:05 +00006086 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006087 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00006088
Hideto Ueno63f60662019-09-21 15:13:19 +00006089 // Every function might be "no-recurse".
6090 getOrCreateAAFor<AANoRecurse>(FPos);
6091
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006092 // Every function might be "readnone/readonly/writeonly/...".
6093 getOrCreateAAFor<AAMemoryBehavior>(FPos);
6094
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006095 // Every function might be applicable for Heap-To-Stack conversion.
6096 if (EnableHeapToStack)
6097 getOrCreateAAFor<AAHeapToStack>(FPos);
6098
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00006099 // Return attributes are only appropriate if the return type is non void.
6100 Type *ReturnType = F.getReturnType();
6101 if (!ReturnType->isVoidTy()) {
6102 // Argument attribute "returned" --- Create only one per function even
6103 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006104 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00006105
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006106 IRPosition RetPos = IRPosition::returned(F);
6107
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006108 // Every returned value might be dead.
6109 getOrCreateAAFor<AAIsDead>(RetPos);
6110
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006111 // Every function might be simplified.
6112 getOrCreateAAFor<AAValueSimplify>(RetPos);
6113
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006114 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006115
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006116 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006117 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006118
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006119 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006120 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006121
6122 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006123 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006124
6125 // Every function with pointer return type might be marked
6126 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006127 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006128 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00006129 }
6130
Hideto Ueno54869ec2019-07-15 06:49:04 +00006131 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006132 IRPosition ArgPos = IRPosition::argument(Arg);
6133
6134 // Every argument might be simplified.
6135 getOrCreateAAFor<AAValueSimplify>(ArgPos);
6136
Hideto Ueno19c07af2019-07-23 08:16:17 +00006137 if (Arg.getType()->isPointerTy()) {
6138 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006139 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006140
Hideto Uenocbab3342019-08-29 05:52:00 +00006141 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006142 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00006143
Hideto Ueno19c07af2019-07-23 08:16:17 +00006144 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006145 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006146
6147 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006148 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006149
6150 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006151 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006152
6153 // Every argument with pointer type might be marked
6154 // "readnone/readonly/writeonly/..."
6155 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006156
6157 // Every argument with pointer type might be marked nofree.
6158 getOrCreateAAFor<AANoFree>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006159 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00006160 }
6161
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006162 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006163 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006164 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006165 // Skip declerations except if annotations on their call sites were
6166 // explicitly requested.
Johannes Doerfert139c9ef2019-12-13 23:41:02 -06006167 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
6168 !Callee->hasMetadata(LLVMContext::MD_callback))
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006169 return true;
6170
6171 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006172 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
6173
6174 // Call site return values might be dead.
6175 getOrCreateAAFor<AAIsDead>(CSRetPos);
6176 }
6177
Johannes Doerfert28880192019-12-31 00:57:00 -06006178 for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006179
6180 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
6181
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006182 // Every call site argument might be dead.
6183 getOrCreateAAFor<AAIsDead>(CSArgPos);
6184
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006185 // Call site argument might be simplified.
6186 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
6187
Hideto Ueno54869ec2019-07-15 06:49:04 +00006188 if (!CS.getArgument(i)->getType()->isPointerTy())
6189 continue;
6190
6191 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006192 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006193
Hideto Uenocbab3342019-08-29 05:52:00 +00006194 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006195 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00006196
Hideto Ueno19c07af2019-07-23 08:16:17 +00006197 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006198 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006199
6200 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006201 getOrCreateAAFor<AAAlign>(CSArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006202
Johannes Doerfert28880192019-12-31 00:57:00 -06006203 // Call site argument attribute
6204 // "readnone/readonly/writeonly/..."
6205 getOrCreateAAFor<AAMemoryBehavior>(CSArgPos);
6206
Hideto Ueno4ecf2552019-12-12 13:42:40 +00006207 // Call site argument attribute "nofree".
6208 getOrCreateAAFor<AANoFree>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00006209 }
6210 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006211 return true;
6212 };
6213
6214 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
6215 bool Success, AnyDead = false;
6216 Success = checkForAllInstructionsImpl(
6217 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
6218 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
6219 (unsigned)Instruction::Call});
6220 (void)Success;
6221 assert(Success && !AnyDead && "Expected the check call to be successful!");
6222
6223 auto LoadStorePred = [&](Instruction &I) -> bool {
6224 if (isa<LoadInst>(I))
6225 getOrCreateAAFor<AAAlign>(
6226 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
6227 else
6228 getOrCreateAAFor<AAAlign>(
6229 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
6230 return true;
6231 };
6232 Success = checkForAllInstructionsImpl(
6233 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
6234 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
6235 (void)Success;
6236 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00006237}
6238
6239/// Helpers to ease debugging through output streams and print calls.
6240///
6241///{
6242raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
6243 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
6244}
6245
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006246raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006247 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006248 case IRPosition::IRP_INVALID:
6249 return OS << "inv";
6250 case IRPosition::IRP_FLOAT:
6251 return OS << "flt";
6252 case IRPosition::IRP_RETURNED:
6253 return OS << "fn_ret";
6254 case IRPosition::IRP_CALL_SITE_RETURNED:
6255 return OS << "cs_ret";
6256 case IRPosition::IRP_FUNCTION:
6257 return OS << "fn";
6258 case IRPosition::IRP_CALL_SITE:
6259 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006260 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00006261 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006262 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00006263 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00006264 }
6265 llvm_unreachable("Unknown attribute position!");
6266}
6267
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006268raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006269 const Value &AV = Pos.getAssociatedValue();
6270 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006271 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
6272}
6273
Johannes Doerfert1a746452019-10-20 22:28:49 -05006274template <typename base_ty, base_ty BestState, base_ty WorstState>
Hideto Ueno5fc02dc2020-01-03 11:03:56 +09006275raw_ostream &llvm::
6276operator<<(raw_ostream &OS,
6277 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00006278 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
6279 << static_cast<const AbstractState &>(S);
6280}
6281
Johannes Doerfertaade7822019-06-05 03:02:24 +00006282raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
6283 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
6284}
6285
6286raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
6287 AA.print(OS);
6288 return OS;
6289}
6290
6291void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006292 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
6293 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00006294}
6295///}
6296
6297/// ----------------------------------------------------------------------------
6298/// Pass (Manager) Boilerplate
6299/// ----------------------------------------------------------------------------
6300
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006301static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006302 if (DisableAttributor)
6303 return false;
6304
6305 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
6306 << " functions.\n");
6307
6308 // Create an Attributor and initially empty information cache that is filled
6309 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00006310 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006311 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006312
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006313 for (Function &F : M)
6314 A.initializeInformationCache(F);
6315
Johannes Doerfertaade7822019-06-05 03:02:24 +00006316 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006317 if (F.hasExactDefinition())
6318 NumFnWithExactDefinition++;
6319 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00006320 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006321
Johannes Doerfert2f622062019-09-04 16:35:20 +00006322 // We look at internal functions only on-demand but if any use is not a
6323 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00006324 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00006325 if (llvm::all_of(F.uses(), [](const Use &U) {
6326 return ImmutableCallSite(U.getUser()) &&
6327 ImmutableCallSite(U.getUser()).isCallee(&U);
6328 }))
6329 continue;
6330 }
6331
Johannes Doerfertaade7822019-06-05 03:02:24 +00006332 // Populate the Attributor with abstract attribute opportunities in the
6333 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006334 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006335 }
6336
Johannes Doerfert2f622062019-09-04 16:35:20 +00006337 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006338}
6339
6340PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00006341 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006342 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006343 // FIXME: Think about passes we will preserve and add them here.
6344 return PreservedAnalyses::none();
6345 }
6346 return PreservedAnalyses::all();
6347}
6348
6349namespace {
6350
6351struct AttributorLegacyPass : public ModulePass {
6352 static char ID;
6353
6354 AttributorLegacyPass() : ModulePass(ID) {
6355 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
6356 }
6357
6358 bool runOnModule(Module &M) override {
6359 if (skipModule(M))
6360 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006361
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006362 AnalysisGetter AG;
6363 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006364 }
6365
6366 void getAnalysisUsage(AnalysisUsage &AU) const override {
6367 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006368 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00006369 }
6370};
6371
6372} // end anonymous namespace
6373
6374Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
6375
6376char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006377
6378const char AAReturnedValues::ID = 0;
6379const char AANoUnwind::ID = 0;
6380const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00006381const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006382const char AANonNull::ID = 0;
6383const char AANoRecurse::ID = 0;
6384const char AAWillReturn::ID = 0;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006385const char AAUndefinedBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006386const char AANoAlias::ID = 0;
Pankaj Gode04945c92019-11-22 18:40:47 +05306387const char AAReachability::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006388const char AANoReturn::ID = 0;
6389const char AAIsDead::ID = 0;
6390const char AADereferenceable::ID = 0;
6391const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006392const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006393const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006394const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006395const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006396
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006397// Macro magic to create the static generator function for attributes that
6398// follow the naming scheme.
6399
6400#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
6401 case IRPosition::PK: \
6402 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
6403
6404#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
6405 case IRPosition::PK: \
6406 AA = new CLASS##SUFFIX(IRP); \
6407 break;
6408
6409#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6410 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6411 CLASS *AA = nullptr; \
6412 switch (IRP.getPositionKind()) { \
6413 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6414 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
6415 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
6416 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6417 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
6418 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
6419 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6420 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6421 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006422 return *AA; \
6423 }
6424
6425#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6426 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6427 CLASS *AA = nullptr; \
6428 switch (IRP.getPositionKind()) { \
6429 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6430 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
6431 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
6432 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6433 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6434 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
6435 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6436 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6437 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006438 return *AA; \
6439 }
6440
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006441#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6442 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6443 CLASS *AA = nullptr; \
6444 switch (IRP.getPositionKind()) { \
6445 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6446 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6447 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6448 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6449 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6450 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
6451 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6452 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6453 } \
6454 return *AA; \
6455 }
6456
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006457#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6458 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6459 CLASS *AA = nullptr; \
6460 switch (IRP.getPositionKind()) { \
6461 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6462 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
6463 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
6464 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6465 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
6466 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
6467 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
6468 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6469 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006470 return *AA; \
6471 }
6472
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006473#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6474 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6475 CLASS *AA = nullptr; \
6476 switch (IRP.getPositionKind()) { \
6477 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6478 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6479 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6480 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6481 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6482 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6483 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6484 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6485 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006486 return *AA; \
6487 }
6488
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006489CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
6490CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006491CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
6492CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
6493CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006494CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
6495
6496CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
6497CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
6498CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
6499CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006500CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006501
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006502CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006503CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006504CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006505
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006506CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
Pankaj Gode04945c92019-11-22 18:40:47 +05306507CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006508CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006509
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006510CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
6511
Johannes Doerfertd4bea882019-10-07 23:28:54 +00006512#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006513#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00006514#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006515#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006516#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006517#undef SWITCH_PK_CREATE
6518#undef SWITCH_PK_INV
6519
Johannes Doerfertaade7822019-06-05 03:02:24 +00006520INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
6521 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006522INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00006523INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
6524 "Deduce and propagate attributes", false, false)