blob: a09a46e642f822e0a1264f7370628abbe06aef47 [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 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001795 if (const Value *Base =
1796 GetPointerBaseWithConstantOffset(UseV, Offset, DL,
1797 /*AllowNonInbounds*/ false)) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001798 if (Base == &AssociatedValue) {
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001799 // As long as we only use known information there is no need to track
1800 // dependences here.
1801 auto &DerefAA = A.getAAFor<AADereferenceable>(
1802 QueryingAA, IRPosition::value(*Base), /* TrackDependence */ false);
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001803 IsNonNull |= (!NullPointerIsDefined && DerefAA.isKnownNonNull());
1804 IsNonNull |= (!NullPointerIsDefined && (Offset != 0));
1805 int64_t DerefBytes = DerefAA.getKnownDereferenceableBytes();
1806 return std::max(int64_t(0), DerefBytes - std::max(int64_t(0), Offset));
1807 }
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001808 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001809
1810 return 0;
1811}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001812
Johannes Doerfert344d0382019-08-07 22:34:26 +00001813struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001814 AANonNullImpl(const IRPosition &IRP)
1815 : AANonNull(IRP),
1816 NullIsDefined(NullPointerIsDefined(
1817 getAnchorScope(),
1818 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001819
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001820 /// See AbstractAttribute::initialize(...).
1821 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001822 if (!NullIsDefined &&
1823 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001824 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001825 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1826 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001827 else
1828 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001829 }
1830
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001831 /// See AAFromMustBeExecutedContext
1832 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1833 bool IsNonNull = false;
1834 bool TrackUse = false;
1835 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1836 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001837 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001838 return TrackUse;
1839 }
1840
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001841 /// See AbstractAttribute::getAsStr().
1842 const std::string getAsStr() const override {
1843 return getAssumed() ? "nonnull" : "may-null";
1844 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001845
1846 /// Flag to determine if the underlying value can be null and still allow
1847 /// valid accesses.
1848 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001849};
1850
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001851/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001852struct AANonNullFloating
1853 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1854 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1855 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001856
Hideto Ueno54869ec2019-07-15 06:49:04 +00001857 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001858 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001859 ChangeStatus Change = Base::updateImpl(A);
1860 if (isKnownNonNull())
1861 return Change;
1862
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001863 if (!NullIsDefined) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001864 const auto &DerefAA =
1865 A.getAAFor<AADereferenceable>(*this, getIRPosition());
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001866 if (DerefAA.getAssumedDereferenceableBytes())
1867 return Change;
1868 }
1869
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001870 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001871
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001872 DominatorTree *DT = nullptr;
1873 InformationCache &InfoCache = A.getInfoCache();
1874 if (const Function *Fn = getAnchorScope())
1875 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
1876
Johannes Doerfert1a746452019-10-20 22:28:49 -05001877 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001878 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001879 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1880 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001881 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001882 T.indicatePessimisticFixpoint();
1883 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001884 // Use abstract attribute information.
1885 const AANonNull::StateType &NS =
1886 static_cast<const AANonNull::StateType &>(AA.getState());
1887 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001888 }
1889 return T.isValidState();
1890 };
1891
1892 StateType T;
1893 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
1894 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001895 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001896
1897 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001898 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001899
1900 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001901 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001902};
1903
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001904/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001905struct AANonNullReturned final
1906 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001907 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001908 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001909
1910 /// See AbstractAttribute::trackStatistics()
1911 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
1912};
1913
Hideto Ueno54869ec2019-07-15 06:49:04 +00001914/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001915struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001916 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1917 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001918 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001919 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
1920 AANonNullImpl>(
1921 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001922
1923 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001924 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001925};
1926
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001927struct AANonNullCallSiteArgument final : AANonNullFloating {
1928 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001929
1930 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00001931 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00001932};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001933
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001934/// NonNull attribute for a call site return position.
1935struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001936 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1937 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001938 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001939 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
1940 AANonNullImpl>(
1941 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001942
1943 /// See AbstractAttribute::trackStatistics()
1944 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
1945};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001946
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001947/// ------------------------ No-Recurse Attributes ----------------------------
1948
1949struct AANoRecurseImpl : public AANoRecurse {
1950 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
1951
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001952 /// See AbstractAttribute::getAsStr()
1953 const std::string getAsStr() const override {
1954 return getAssumed() ? "norecurse" : "may-recurse";
1955 }
1956};
1957
1958struct AANoRecurseFunction final : AANoRecurseImpl {
1959 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
1960
Hideto Ueno63f60662019-09-21 15:13:19 +00001961 /// See AbstractAttribute::initialize(...).
1962 void initialize(Attributor &A) override {
1963 AANoRecurseImpl::initialize(A);
1964 if (const Function *F = getAnchorScope())
1965 if (A.getInfoCache().getSccSize(*F) == 1)
1966 return;
1967 indicatePessimisticFixpoint();
1968 }
1969
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001970 /// See AbstractAttribute::updateImpl(...).
1971 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00001972
1973 auto CheckForNoRecurse = [&](Instruction &I) {
1974 ImmutableCallSite ICS(&I);
1975 if (ICS.hasFnAttr(Attribute::NoRecurse))
1976 return true;
1977
1978 const auto &NoRecurseAA =
1979 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
1980 if (!NoRecurseAA.isAssumedNoRecurse())
1981 return false;
1982
1983 // Recursion to the same function
1984 if (ICS.getCalledFunction() == getAnchorScope())
1985 return false;
1986
1987 return true;
1988 };
1989
1990 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
1991 return indicatePessimisticFixpoint();
1992 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00001993 }
1994
1995 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
1996};
1997
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001998/// NoRecurse attribute deduction for a call sites.
1999struct AANoRecurseCallSite final : AANoRecurseImpl {
2000 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2001
2002 /// See AbstractAttribute::initialize(...).
2003 void initialize(Attributor &A) override {
2004 AANoRecurseImpl::initialize(A);
2005 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002006 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002007 indicatePessimisticFixpoint();
2008 }
2009
2010 /// See AbstractAttribute::updateImpl(...).
2011 ChangeStatus updateImpl(Attributor &A) override {
2012 // TODO: Once we have call site specific value information we can provide
2013 // call site specific liveness information and then it makes
2014 // sense to specialize attributes for call sites arguments instead of
2015 // redirecting requests to the callee argument.
2016 Function *F = getAssociatedFunction();
2017 const IRPosition &FnPos = IRPosition::function(*F);
2018 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
2019 return clampStateAndIndicateChange(
2020 getState(),
2021 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
2022 }
2023
2024 /// See AbstractAttribute::trackStatistics()
2025 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2026};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002027
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002028/// -------------------- Undefined-Behavior Attributes ------------------------
2029
2030struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2031 AAUndefinedBehaviorImpl(const IRPosition &IRP) : AAUndefinedBehavior(IRP) {}
2032
2033 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert5732f562019-12-24 19:25:08 -06002034 // through a pointer (i.e. also branches etc.)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002035 ChangeStatus updateImpl(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002036 const size_t UBPrevSize = KnownUBInsts.size();
2037 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002038
Johannes Doerfert5732f562019-12-24 19:25:08 -06002039 auto InspectMemAccessInstForUB = [&](Instruction &I) {
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002040 // Skip instructions that are already saved.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002041 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002042 return true;
2043
Hideto Uenoef4febd2019-12-29 17:34:08 +09002044 // If we reach here, we know we have an instruction
2045 // that accesses memory through a pointer operand,
2046 // for which getPointerOperand() should give it to us.
2047 const Value *PtrOp =
2048 Attributor::getPointerOperand(&I, /* AllowVolatile */ true);
2049 assert(PtrOp &&
2050 "Expected pointer operand of memory accessing instruction");
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002051
Johannes Doerfert5732f562019-12-24 19:25:08 -06002052 // A memory access through a pointer is considered UB
2053 // only if the pointer has constant null value.
2054 // TODO: Expand it to not only check constant values.
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002055 if (!isa<ConstantPointerNull>(PtrOp)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002056 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002057 return true;
2058 }
Johannes Doerfert5732f562019-12-24 19:25:08 -06002059 const Type *PtrTy = PtrOp->getType();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002060
Johannes Doerfert5732f562019-12-24 19:25:08 -06002061 // Because we only consider instructions inside functions,
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002062 // assume that a parent function exists.
2063 const Function *F = I.getFunction();
2064
Johannes Doerfert5732f562019-12-24 19:25:08 -06002065 // A memory access using constant null pointer is only considered UB
2066 // if null pointer is _not_ defined for the target platform.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002067 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()))
2068 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002069 else
Hideto Uenoef4febd2019-12-29 17:34:08 +09002070 KnownUBInsts.insert(&I);
2071 return true;
2072 };
2073
2074 auto InspectBrInstForUB = [&](Instruction &I) {
2075 // A conditional branch instruction is considered UB if it has `undef`
2076 // condition.
2077
2078 // Skip instructions that are already saved.
2079 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2080 return true;
2081
2082 // We know we have a branch instruction.
2083 auto BrInst = cast<BranchInst>(&I);
2084
2085 // Unconditional branches are never considered UB.
2086 if (BrInst->isUnconditional())
2087 return true;
2088
2089 // Either we stopped and the appropriate action was taken,
2090 // or we got back a simplified value to continue.
2091 Optional<Value *> SimplifiedCond =
2092 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2093 if (!SimplifiedCond.hasValue())
2094 return true;
2095 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002096 return true;
2097 };
2098
Johannes Doerfert5732f562019-12-24 19:25:08 -06002099 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
2100 {Instruction::Load, Instruction::Store,
2101 Instruction::AtomicCmpXchg,
2102 Instruction::AtomicRMW});
Hideto Uenoef4febd2019-12-29 17:34:08 +09002103 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br});
2104 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
2105 UBPrevSize != KnownUBInsts.size())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002106 return ChangeStatus::CHANGED;
2107 return ChangeStatus::UNCHANGED;
2108 }
2109
Hideto Uenoef4febd2019-12-29 17:34:08 +09002110 bool isKnownToCauseUB(Instruction *I) const override {
2111 return KnownUBInsts.count(I);
2112 }
2113
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002114 bool isAssumedToCauseUB(Instruction *I) const override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002115 // In simple words, if an instruction is not in the assumed to _not_
2116 // cause UB, then it is assumed UB (that includes those
2117 // in the KnownUBInsts set). The rest is boilerplate
2118 // is to ensure that it is one of the instructions we test
2119 // for UB.
2120
2121 switch (I->getOpcode()) {
2122 case Instruction::Load:
2123 case Instruction::Store:
2124 case Instruction::AtomicCmpXchg:
2125 case Instruction::AtomicRMW:
2126 return !AssumedNoUBInsts.count(I);
2127 case Instruction::Br: {
2128 auto BrInst = cast<BranchInst>(I);
2129 if (BrInst->isUnconditional())
2130 return false;
2131 return !AssumedNoUBInsts.count(I);
2132 } break;
2133 default:
2134 return false;
2135 }
2136 return false;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002137 }
2138
2139 ChangeStatus manifest(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002140 if (KnownUBInsts.empty())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002141 return ChangeStatus::UNCHANGED;
Hideto Uenoef4febd2019-12-29 17:34:08 +09002142 for (Instruction *I : KnownUBInsts)
Hideto Uenocb5eb132019-12-27 02:39:37 +09002143 A.changeToUnreachableAfterManifest(I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002144 return ChangeStatus::CHANGED;
2145 }
2146
2147 /// See AbstractAttribute::getAsStr()
2148 const std::string getAsStr() const override {
2149 return getAssumed() ? "undefined-behavior" : "no-ub";
2150 }
2151
Hideto Uenoef4febd2019-12-29 17:34:08 +09002152 /// Note: The correctness of this analysis depends on the fact that the
2153 /// following 2 sets will stop changing after some point.
2154 /// "Change" here means that their size changes.
2155 /// The size of each set is monotonically increasing
2156 /// (we only add items to them) and it is upper bounded by the number of
2157 /// instructions in the processed function (we can never save more
2158 /// elements in either set than this number). Hence, at some point,
2159 /// they will stop increasing.
2160 /// Consequently, at some point, both sets will have stopped
2161 /// changing, effectively making the analysis reach a fixpoint.
2162
2163 /// Note: These 2 sets are disjoint and an instruction can be considered
2164 /// one of 3 things:
2165 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
2166 /// the KnownUBInsts set.
2167 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
2168 /// has a reason to assume it).
2169 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
2170 /// could not find a reason to assume or prove that it can cause UB,
2171 /// hence it assumes it doesn't. We have a set for these instructions
2172 /// so that we don't reprocess them in every update.
2173 /// Note however that instructions in this set may cause UB.
2174
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002175protected:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002176 /// A set of all live instructions _known_ to cause UB.
2177 SmallPtrSet<Instruction *, 8> KnownUBInsts;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002178
2179private:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002180 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
2181 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
2182
2183 // Should be called on updates in which if we're processing an instruction
2184 // \p I that depends on a value \p V, one of the following has to happen:
2185 // - If the value is assumed, then stop.
2186 // - If the value is known but undef, then consider it UB.
2187 // - Otherwise, do specific processing with the simplified value.
2188 // We return None in the first 2 cases to signify that an appropriate
2189 // action was taken and the caller should stop.
2190 // Otherwise, we return the simplified value that the caller should
2191 // use for specific processing.
2192 Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
2193 Instruction *I) {
2194 const auto &ValueSimplifyAA =
2195 A.getAAFor<AAValueSimplify>(*this, IRPosition::value(*V));
2196 Optional<Value *> SimplifiedV =
2197 ValueSimplifyAA.getAssumedSimplifiedValue(A);
2198 if (!ValueSimplifyAA.isKnown()) {
2199 // Don't depend on assumed values.
2200 return llvm::None;
2201 }
2202 if (!SimplifiedV.hasValue()) {
2203 // If it is known (which we tested above) but it doesn't have a value,
2204 // then we can assume `undef` and hence the instruction is UB.
2205 KnownUBInsts.insert(I);
2206 return llvm::None;
2207 }
2208 Value *Val = SimplifiedV.getValue();
2209 if (isa<UndefValue>(Val)) {
2210 KnownUBInsts.insert(I);
2211 return llvm::None;
2212 }
2213 return Val;
2214 }
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002215};
2216
2217struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
2218 AAUndefinedBehaviorFunction(const IRPosition &IRP)
2219 : AAUndefinedBehaviorImpl(IRP) {}
2220
2221 /// See AbstractAttribute::trackStatistics()
2222 void trackStatistics() const override {
2223 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
2224 "Number of instructions known to have UB");
2225 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
Hideto Uenoef4febd2019-12-29 17:34:08 +09002226 KnownUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002227 }
2228};
2229
Hideto Ueno11d37102019-07-17 15:15:43 +00002230/// ------------------------ Will-Return Attributes ----------------------------
2231
Hideto Ueno11d37102019-07-17 15:15:43 +00002232// Helper function that checks whether a function has any cycle.
2233// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002234static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00002235 SmallPtrSet<BasicBlock *, 32> Visited;
2236
2237 // Traverse BB by dfs and check whether successor is already visited.
2238 for (BasicBlock *BB : depth_first(&F)) {
2239 Visited.insert(BB);
2240 for (auto *SuccBB : successors(BB)) {
2241 if (Visited.count(SuccBB))
2242 return true;
2243 }
2244 }
2245 return false;
2246}
2247
2248// Helper function that checks the function have a loop which might become an
2249// endless loop
2250// FIXME: Any cycle is regarded as endless loop for now.
2251// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002252static bool containsPossiblyEndlessLoop(Function *F) {
2253 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00002254}
2255
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002256struct AAWillReturnImpl : public AAWillReturn {
2257 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00002258
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002259 /// See AbstractAttribute::initialize(...).
2260 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002261 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00002262
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002263 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002264 if (containsPossiblyEndlessLoop(F))
2265 indicatePessimisticFixpoint();
2266 }
Hideto Ueno11d37102019-07-17 15:15:43 +00002267
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002268 /// See AbstractAttribute::updateImpl(...).
2269 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002270 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002271 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
2272 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
2273 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002274 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002275 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002276 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002277 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
2278 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002279 };
2280
2281 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
2282 return indicatePessimisticFixpoint();
2283
2284 return ChangeStatus::UNCHANGED;
2285 }
2286
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002287 /// See AbstractAttribute::getAsStr()
2288 const std::string getAsStr() const override {
2289 return getAssumed() ? "willreturn" : "may-noreturn";
2290 }
2291};
2292
2293struct AAWillReturnFunction final : AAWillReturnImpl {
2294 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2295
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002296 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002297 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002298};
Hideto Ueno11d37102019-07-17 15:15:43 +00002299
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002300/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002301struct AAWillReturnCallSite final : AAWillReturnImpl {
2302 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2303
2304 /// See AbstractAttribute::initialize(...).
2305 void initialize(Attributor &A) override {
2306 AAWillReturnImpl::initialize(A);
2307 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002308 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002309 indicatePessimisticFixpoint();
2310 }
2311
2312 /// See AbstractAttribute::updateImpl(...).
2313 ChangeStatus updateImpl(Attributor &A) override {
2314 // TODO: Once we have call site specific value information we can provide
2315 // call site specific liveness information and then it makes
2316 // sense to specialize attributes for call sites arguments instead of
2317 // redirecting requests to the callee argument.
2318 Function *F = getAssociatedFunction();
2319 const IRPosition &FnPos = IRPosition::function(*F);
2320 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
2321 return clampStateAndIndicateChange(
2322 getState(),
2323 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
2324 }
2325
2326 /// See AbstractAttribute::trackStatistics()
2327 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
2328};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002329
Pankaj Gode04945c92019-11-22 18:40:47 +05302330/// -------------------AAReachability Attribute--------------------------
2331
2332struct AAReachabilityImpl : AAReachability {
2333 AAReachabilityImpl(const IRPosition &IRP) : AAReachability(IRP) {}
2334
2335 const std::string getAsStr() const override {
2336 // TODO: Return the number of reachable queries.
2337 return "reachable";
2338 }
2339
2340 /// See AbstractAttribute::initialize(...).
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002341 void initialize(Attributor &A) override { indicatePessimisticFixpoint(); }
Pankaj Gode04945c92019-11-22 18:40:47 +05302342
2343 /// See AbstractAttribute::updateImpl(...).
2344 ChangeStatus updateImpl(Attributor &A) override {
2345 return indicatePessimisticFixpoint();
2346 }
2347};
2348
2349struct AAReachabilityFunction final : public AAReachabilityImpl {
2350 AAReachabilityFunction(const IRPosition &IRP) : AAReachabilityImpl(IRP) {}
2351
2352 /// See AbstractAttribute::trackStatistics()
2353 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); }
2354};
2355
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002356/// ------------------------ NoAlias Argument Attribute ------------------------
2357
Johannes Doerfert344d0382019-08-07 22:34:26 +00002358struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002359 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002360
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002361 const std::string getAsStr() const override {
2362 return getAssumed() ? "noalias" : "may-alias";
2363 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002364};
2365
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002366/// NoAlias attribute for a floating value.
2367struct AANoAliasFloating final : AANoAliasImpl {
2368 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2369
Hideto Uenocbab3342019-08-29 05:52:00 +00002370 /// See AbstractAttribute::initialize(...).
2371 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002372 AANoAliasImpl::initialize(A);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002373 Value &Val = getAssociatedValue();
2374 if (isa<AllocaInst>(Val))
2375 indicateOptimisticFixpoint();
2376 if (isa<ConstantPointerNull>(Val) &&
2377 Val.getType()->getPointerAddressSpace() == 0)
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002378 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002379 }
2380
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002381 /// See AbstractAttribute::updateImpl(...).
2382 ChangeStatus updateImpl(Attributor &A) override {
2383 // TODO: Implement this.
2384 return indicatePessimisticFixpoint();
2385 }
2386
2387 /// See AbstractAttribute::trackStatistics()
2388 void trackStatistics() const override {
2389 STATS_DECLTRACK_FLOATING_ATTR(noalias)
2390 }
2391};
2392
2393/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00002394struct AANoAliasArgument final
2395 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002396 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
2397 AANoAliasArgument(const IRPosition &IRP) : Base(IRP) {}
2398
2399 /// See AbstractAttribute::update(...).
2400 ChangeStatus updateImpl(Attributor &A) override {
2401 // We have to make sure no-alias on the argument does not break
2402 // synchronization when this is a callback argument, see also [1] below.
2403 // If synchronization cannot be affected, we delegate to the base updateImpl
2404 // function, otherwise we give up for now.
2405
2406 // If the function is no-sync, no-alias cannot break synchronization.
2407 const auto &NoSyncAA = A.getAAFor<AANoSync>(
2408 *this, IRPosition::function_scope(getIRPosition()));
2409 if (NoSyncAA.isAssumedNoSync())
2410 return Base::updateImpl(A);
2411
2412 // If the argument is read-only, no-alias cannot break synchronization.
2413 const auto &MemBehaviorAA =
2414 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
2415 if (MemBehaviorAA.isAssumedReadOnly())
2416 return Base::updateImpl(A);
2417
2418 // If the argument is never passed through callbacks, no-alias cannot break
2419 // synchronization.
2420 if (A.checkForAllCallSites(
2421 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
2422 true))
2423 return Base::updateImpl(A);
2424
2425 // TODO: add no-alias but make sure it doesn't break synchronization by
2426 // introducing fake uses. See:
2427 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
2428 // International Workshop on OpenMP 2018,
2429 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
2430
2431 return indicatePessimisticFixpoint();
2432 }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002433
2434 /// See AbstractAttribute::trackStatistics()
2435 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
2436};
2437
2438struct AANoAliasCallSiteArgument final : AANoAliasImpl {
2439 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2440
Hideto Uenocbab3342019-08-29 05:52:00 +00002441 /// See AbstractAttribute::initialize(...).
2442 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00002443 // See callsite argument attribute and callee argument attribute.
2444 ImmutableCallSite ICS(&getAnchorValue());
2445 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
2446 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002447 }
2448
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002449 /// See AbstractAttribute::updateImpl(...).
2450 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002451 // We can deduce "noalias" if the following conditions hold.
2452 // (i) Associated value is assumed to be noalias in the definition.
2453 // (ii) Associated value is assumed to be no-capture in all the uses
2454 // possibly executed before this callsite.
2455 // (iii) There is no other pointer argument which could alias with the
2456 // value.
2457
2458 const Value &V = getAssociatedValue();
2459 const IRPosition IRP = IRPosition::value(V);
2460
2461 // (i) Check whether noalias holds in the definition.
2462
2463 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002464 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] check definition: " << V
2465 << " :: " << NoAliasAA << "\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002466
2467 if (!NoAliasAA.isAssumedNoAlias())
2468 return indicatePessimisticFixpoint();
2469
2470 LLVM_DEBUG(dbgs() << "[Attributor][AANoAliasCSArg] " << V
2471 << " is assumed NoAlias in the definition\n");
2472
2473 // (ii) Check whether the value is captured in the scope using AANoCapture.
2474 // FIXME: This is conservative though, it is better to look at CFG and
2475 // check only uses possibly executed before this callsite.
2476
2477 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
Johannes Doerfert72adda12019-10-10 05:33:21 +00002478 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2479 LLVM_DEBUG(
2480 dbgs() << "[Attributor][AANoAliasCSArg] " << V
2481 << " cannot be noalias as it is potentially captured\n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002482 return indicatePessimisticFixpoint();
Johannes Doerfert72adda12019-10-10 05:33:21 +00002483 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002484
2485 // (iii) Check there is no other pointer argument which could alias with the
2486 // value.
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002487 // TODO: AbstractCallSite
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002488 ImmutableCallSite ICS(&getAnchorValue());
2489 for (unsigned i = 0; i < ICS.getNumArgOperands(); i++) {
2490 if (getArgNo() == (int)i)
2491 continue;
2492 const Value *ArgOp = ICS.getArgOperand(i);
2493 if (!ArgOp->getType()->isPointerTy())
2494 continue;
2495
Hideto Ueno30d86f12019-09-17 06:53:27 +00002496 if (const Function *F = getAnchorScope()) {
2497 if (AAResults *AAR = A.getInfoCache().getAAResultsForFunction(*F)) {
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002498 bool IsAliasing = !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
Hideto Ueno30d86f12019-09-17 06:53:27 +00002499 LLVM_DEBUG(dbgs()
2500 << "[Attributor][NoAliasCSArg] Check alias between "
2501 "callsite arguments "
2502 << AAR->isNoAlias(&getAssociatedValue(), ArgOp) << " "
Johannes Doerfert72adda12019-10-10 05:33:21 +00002503 << getAssociatedValue() << " " << *ArgOp << " => "
2504 << (IsAliasing ? "" : "no-") << "alias \n");
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002505
Johannes Doerfert3d347e22019-12-13 23:35:45 -06002506 if (!IsAliasing)
Hideto Ueno30d86f12019-09-17 06:53:27 +00002507 continue;
2508 }
2509 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002510 return indicatePessimisticFixpoint();
2511 }
2512
2513 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002514 }
2515
2516 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002517 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002518};
2519
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002520/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002521struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002522 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002523
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002524 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002525 virtual ChangeStatus updateImpl(Attributor &A) override {
2526
2527 auto CheckReturnValue = [&](Value &RV) -> bool {
2528 if (Constant *C = dyn_cast<Constant>(&RV))
2529 if (C->isNullValue() || isa<UndefValue>(C))
2530 return true;
2531
2532 /// For now, we can only deduce noalias if we have call sites.
2533 /// FIXME: add more support.
2534 ImmutableCallSite ICS(&RV);
2535 if (!ICS)
2536 return false;
2537
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002538 const IRPosition &RVPos = IRPosition::value(RV);
2539 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002540 if (!NoAliasAA.isAssumedNoAlias())
2541 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002542
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002543 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2544 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002545 };
2546
2547 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2548 return indicatePessimisticFixpoint();
2549
2550 return ChangeStatus::UNCHANGED;
2551 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002552
2553 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002554 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002555};
2556
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002557/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002558struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2559 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2560
2561 /// See AbstractAttribute::initialize(...).
2562 void initialize(Attributor &A) override {
2563 AANoAliasImpl::initialize(A);
2564 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002565 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002566 indicatePessimisticFixpoint();
2567 }
2568
2569 /// See AbstractAttribute::updateImpl(...).
2570 ChangeStatus updateImpl(Attributor &A) override {
2571 // TODO: Once we have call site specific value information we can provide
2572 // call site specific liveness information and then it makes
2573 // sense to specialize attributes for call sites arguments instead of
2574 // redirecting requests to the callee argument.
2575 Function *F = getAssociatedFunction();
2576 const IRPosition &FnPos = IRPosition::returned(*F);
2577 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2578 return clampStateAndIndicateChange(
2579 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2580 }
2581
2582 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002583 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002584};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002585
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002586/// -------------------AAIsDead Function Attribute-----------------------
2587
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002588struct AAIsDeadValueImpl : public AAIsDead {
2589 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002590
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002591 /// See AAIsDead::isAssumedDead().
2592 bool isAssumedDead() const override { return getAssumed(); }
2593
2594 /// See AAIsDead::isAssumedDead(BasicBlock *).
2595 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2596
2597 /// See AAIsDead::isKnownDead(BasicBlock *).
2598 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2599
2600 /// See AAIsDead::isAssumedDead(Instruction *I).
2601 bool isAssumedDead(const Instruction *I) const override {
2602 return I == getCtxI() && isAssumedDead();
2603 }
2604
2605 /// See AAIsDead::isKnownDead(Instruction *I).
2606 bool isKnownDead(const Instruction *I) const override {
2607 return I == getCtxI() && getKnown();
2608 }
2609
2610 /// See AbstractAttribute::getAsStr().
2611 const std::string getAsStr() const override {
2612 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2613 }
2614};
2615
2616struct AAIsDeadFloating : public AAIsDeadValueImpl {
2617 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2618
2619 /// See AbstractAttribute::initialize(...).
2620 void initialize(Attributor &A) override {
2621 if (Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()))
2622 if (!wouldInstructionBeTriviallyDead(I))
2623 indicatePessimisticFixpoint();
2624 if (isa<UndefValue>(getAssociatedValue()))
2625 indicatePessimisticFixpoint();
2626 }
2627
2628 /// See AbstractAttribute::updateImpl(...).
2629 ChangeStatus updateImpl(Attributor &A) override {
2630 auto UsePred = [&](const Use &U, bool &Follow) {
2631 Instruction *UserI = cast<Instruction>(U.getUser());
2632 if (CallSite CS = CallSite(UserI)) {
2633 if (!CS.isArgOperand(&U))
2634 return false;
2635 const IRPosition &CSArgPos =
2636 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
2637 const auto &CSArgIsDead = A.getAAFor<AAIsDead>(*this, CSArgPos);
2638 return CSArgIsDead.isAssumedDead();
2639 }
2640 if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
2641 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
2642 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, RetPos);
2643 return RetIsDeadAA.isAssumedDead();
2644 }
2645 Follow = true;
2646 return wouldInstructionBeTriviallyDead(UserI);
2647 };
2648
2649 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
2650 return indicatePessimisticFixpoint();
2651 return ChangeStatus::UNCHANGED;
2652 }
2653
2654 /// See AbstractAttribute::manifest(...).
2655 ChangeStatus manifest(Attributor &A) override {
2656 Value &V = getAssociatedValue();
2657 if (auto *I = dyn_cast<Instruction>(&V))
2658 if (wouldInstructionBeTriviallyDead(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002659 A.deleteAfterManifest(*I);
2660 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002661 }
2662
2663 if (V.use_empty())
2664 return ChangeStatus::UNCHANGED;
2665
2666 UndefValue &UV = *UndefValue::get(V.getType());
Hideto Ueno34fe8d02019-12-30 17:08:48 +09002667 bool AnyChange = A.changeValueAfterManifest(V, UV);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002668 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2669 }
2670
2671 /// See AbstractAttribute::trackStatistics()
2672 void trackStatistics() const override {
2673 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2674 }
2675};
2676
2677struct AAIsDeadArgument : public AAIsDeadFloating {
2678 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2679
2680 /// See AbstractAttribute::initialize(...).
2681 void initialize(Attributor &A) override {
2682 if (!getAssociatedFunction()->hasExactDefinition())
2683 indicatePessimisticFixpoint();
2684 }
2685
Johannes Doerfert75133632019-10-10 01:39:16 -05002686 /// See AbstractAttribute::manifest(...).
2687 ChangeStatus manifest(Attributor &A) override {
2688 ChangeStatus Changed = AAIsDeadFloating::manifest(A);
2689 Argument &Arg = *getAssociatedArgument();
2690 if (Arg.getParent()->hasLocalLinkage())
2691 if (A.registerFunctionSignatureRewrite(
2692 Arg, /* ReplacementTypes */ {},
2693 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{},
2694 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{}))
2695 return ChangeStatus::CHANGED;
2696 return Changed;
2697 }
2698
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002699 /// See AbstractAttribute::trackStatistics()
2700 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2701};
2702
2703struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2704 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2705
2706 /// See AbstractAttribute::initialize(...).
2707 void initialize(Attributor &A) override {
2708 if (isa<UndefValue>(getAssociatedValue()))
2709 indicatePessimisticFixpoint();
2710 }
2711
2712 /// See AbstractAttribute::updateImpl(...).
2713 ChangeStatus updateImpl(Attributor &A) override {
2714 // TODO: Once we have call site specific value information we can provide
2715 // call site specific liveness information and then it makes
2716 // sense to specialize attributes for call sites arguments instead of
2717 // redirecting requests to the callee argument.
2718 Argument *Arg = getAssociatedArgument();
2719 if (!Arg)
2720 return indicatePessimisticFixpoint();
2721 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2722 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
2723 return clampStateAndIndicateChange(
2724 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
2725 }
2726
2727 /// See AbstractAttribute::manifest(...).
2728 ChangeStatus manifest(Attributor &A) override {
2729 CallBase &CB = cast<CallBase>(getAnchorValue());
2730 Use &U = CB.getArgOperandUse(getArgNo());
2731 assert(!isa<UndefValue>(U.get()) &&
2732 "Expected undef values to be filtered out!");
2733 UndefValue &UV = *UndefValue::get(U->getType());
2734 if (A.changeUseAfterManifest(U, UV))
2735 return ChangeStatus::CHANGED;
2736 return ChangeStatus::UNCHANGED;
2737 }
2738
2739 /// See AbstractAttribute::trackStatistics()
2740 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
2741};
2742
2743struct AAIsDeadReturned : public AAIsDeadValueImpl {
2744 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2745
2746 /// See AbstractAttribute::updateImpl(...).
2747 ChangeStatus updateImpl(Attributor &A) override {
2748
2749 auto PredForCallSite = [&](AbstractCallSite ACS) {
2750 if (ACS.isCallbackCall())
2751 return false;
2752 const IRPosition &CSRetPos =
2753 IRPosition::callsite_returned(ACS.getCallSite());
2754 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, CSRetPos);
2755 return RetIsDeadAA.isAssumedDead();
2756 };
2757
2758 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
2759 return indicatePessimisticFixpoint();
2760
2761 return ChangeStatus::UNCHANGED;
2762 }
2763
2764 /// See AbstractAttribute::manifest(...).
2765 ChangeStatus manifest(Attributor &A) override {
2766 // TODO: Rewrite the signature to return void?
2767 bool AnyChange = false;
2768 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
2769 auto RetInstPred = [&](Instruction &I) {
2770 ReturnInst &RI = cast<ReturnInst>(I);
2771 if (!isa<UndefValue>(RI.getReturnValue()))
2772 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
2773 return true;
2774 };
2775 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
2776 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2777 }
2778
2779 /// See AbstractAttribute::trackStatistics()
2780 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
2781};
2782
2783struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
2784 AAIsDeadCallSiteReturned(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2785
2786 /// See AbstractAttribute::initialize(...).
2787 void initialize(Attributor &A) override {}
2788
2789 /// See AbstractAttribute::trackStatistics()
2790 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(IsDead) }
2791};
2792
2793struct AAIsDeadFunction : public AAIsDead {
2794 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
2795
2796 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002797 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002798 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002799 if (F && !F->isDeclaration()) {
2800 ToBeExploredFrom.insert(&F->getEntryBlock().front());
2801 assumeLive(A, F->getEntryBlock());
2802 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002803 }
2804
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002805 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002806 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002807 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002808 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002809 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
2810 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002811 }
2812
2813 /// See AbstractAttribute::manifest(...).
2814 ChangeStatus manifest(Attributor &A) override {
2815 assert(getState().isValidState() &&
2816 "Attempted to manifest an invalid state!");
2817
2818 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002819 Function &F = *getAssociatedFunction();
2820
2821 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002822 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00002823 return ChangeStatus::CHANGED;
2824 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00002825
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002826 // Flag to determine if we can change an invoke to a call assuming the
2827 // callee is nounwind. This is not possible if the personality of the
2828 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002829 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002830
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002831 KnownDeadEnds.set_union(ToBeExploredFrom);
2832 for (const Instruction *DeadEndI : KnownDeadEnds) {
2833 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002834 if (!CB)
2835 continue;
2836 const auto &NoReturnAA =
2837 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002838 bool MayReturn = !NoReturnAA.isAssumedNoReturn();
2839 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002840 continue;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002841 Instruction *I = const_cast<Instruction *>(DeadEndI);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002842 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002843 Instruction *SplitPos = I->getNextNode();
Johannes Doerfertd4108052019-08-21 20:56:41 +00002844 // TODO: mark stuff before unreachable instructions as dead.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002845
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002846 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002847 // If we keep the invoke the split position is at the beginning of the
2848 // normal desitination block (it invokes a noreturn function after all).
2849 BasicBlock *NormalDestBB = II->getNormalDest();
2850 SplitPos = &NormalDestBB->front();
2851
Johannes Doerfert4361da22019-08-04 18:38:53 +00002852 /// Invoke is replaced with a call and unreachable is placed after it if
2853 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
2854 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00002855 if (Invoke2CallAllowed) {
Michael Liaoa99086d2019-08-20 21:02:31 +00002856 if (II->getCalledFunction()) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002857 const IRPosition &IPos = IRPosition::callsite_function(*II);
2858 const auto &AANoUnw = A.getAAFor<AANoUnwind>(*this, IPos);
2859 if (AANoUnw.isAssumedNoUnwind()) {
Johannes Doerfert924d2132019-08-05 21:34:45 +00002860 LLVM_DEBUG(dbgs()
2861 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002862 CallInst *CI = createCallMatchingInvoke(II);
2863 CI->insertBefore(II);
2864 CI->takeName(II);
Johannes Doerfert5d346022019-12-13 22:11:42 -06002865 replaceAllInstructionUsesWith(*II, *CI);
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002866
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002867 // If this is a nounwind + mayreturn invoke we only remove the
2868 // unwind edge. This is done by moving the invoke into a new and
2869 // dead block and connecting the normal destination of the invoke
2870 // with a branch that follows the call replacement we created
2871 // above.
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002872 if (MayReturn) {
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002873 BasicBlock *NewDeadBB =
2874 SplitBlock(BB, II, nullptr, nullptr, nullptr, ".i2c");
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05002875 assert(isa<BranchInst>(BB->getTerminator()) &&
2876 BB->getTerminator()->getNumSuccessors() == 1 &&
2877 BB->getTerminator()->getSuccessor(0) == NewDeadBB);
2878 new UnreachableInst(I->getContext(), NewDeadBB);
2879 BB->getTerminator()->setOperand(0, NormalDestBB);
2880 A.deleteAfterManifest(*II);
2881 continue;
2882 }
2883
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002884 // We do not need an invoke (II) but instead want a call followed
2885 // by an unreachable. However, we do not remove II as other
2886 // abstract attributes might have it cached as part of their
2887 // results. Given that we modify the CFG anyway, we simply keep II
2888 // around but in a new dead block. To avoid II being live through
2889 // a different edge we have to ensure the block we place it in is
2890 // only reached from the current block of II and then not reached
2891 // at all when we insert the unreachable.
2892 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002893 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00002894 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00002895 }
2896 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002897
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002898 if (SplitPos == &NormalDestBB->front()) {
2899 // If this is an invoke of a noreturn function the edge to the normal
2900 // destination block is dead but not necessarily the block itself.
2901 // TODO: We need to move to an edge based system during deduction and
2902 // also manifest.
2903 assert(!NormalDestBB->isLandingPad() &&
2904 "Expected the normal destination not to be a landingpad!");
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002905 if (NormalDestBB->getUniquePredecessor() == BB) {
2906 assumeLive(A, *NormalDestBB);
2907 } else {
2908 BasicBlock *SplitBB =
2909 SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
2910 // The split block is live even if it contains only an unreachable
2911 // instruction at the end.
2912 assumeLive(A, *SplitBB);
2913 SplitPos = SplitBB->getTerminator();
2914 HasChanged = ChangeStatus::CHANGED;
2915 }
Johannes Doerfert7ab52532019-09-04 20:34:52 +00002916 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002917 }
2918
Johannes Doerfert4056e7f2019-10-13 05:27:09 +00002919 if (isa_and_nonnull<UnreachableInst>(SplitPos))
2920 continue;
2921
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00002922 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00002923 SplitBlock(BB, SplitPos);
Hideto Uenocb5eb132019-12-27 02:39:37 +09002924 A.changeToUnreachableAfterManifest(BB->getTerminator());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002925 HasChanged = ChangeStatus::CHANGED;
2926 }
2927
Johannes Doerfertb19cd272019-09-03 20:42:16 +00002928 for (BasicBlock &BB : F)
2929 if (!AssumedLiveBlocks.count(&BB))
2930 A.deleteAfterManifest(BB);
2931
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002932 return HasChanged;
2933 }
2934
2935 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00002936 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002937
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002938 /// See AbstractAttribute::trackStatistics()
2939 void trackStatistics() const override {}
2940
2941 /// Returns true if the function is assumed dead.
2942 bool isAssumedDead() const override { return false; }
2943
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002944 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002945 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002946 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002947 "BB must be in the same anchor scope function.");
2948
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002949 if (!getAssumed())
2950 return false;
2951 return !AssumedLiveBlocks.count(BB);
2952 }
2953
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002954 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002955 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002956 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002957 }
2958
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002959 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002960 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002961 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002962 "Instruction must be in the same anchor scope function.");
2963
Stefan Stipanovic7849e412019-08-03 15:27:41 +00002964 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002965 return false;
2966
2967 // If it is not in AssumedLiveBlocks then it for sure dead.
2968 // Otherwise, it can still be after noreturn call in a live block.
2969 if (!AssumedLiveBlocks.count(I->getParent()))
2970 return true;
2971
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002972 // If it is not after a liveness barrier it is live.
2973 const Instruction *PrevI = I->getPrevNode();
2974 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05002975 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002976 return true;
2977 PrevI = PrevI->getPrevNode();
2978 }
2979 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002980 }
2981
2982 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00002983 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002984 return getKnown() && isAssumedDead(I);
2985 }
2986
Johannes Doerfert924d2132019-08-05 21:34:45 +00002987 /// Determine if \p F might catch asynchronous exceptions.
2988 static bool mayCatchAsynchronousExceptions(const Function &F) {
2989 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
2990 }
2991
Johannes Doerfert2f622062019-09-04 16:35:20 +00002992 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
2993 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002994 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00002995 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002996 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00002997
2998 // We assume that all of BB is (probably) live now and if there are calls to
2999 // internal functions we will assume that those are now live as well. This
3000 // is a performance optimization for blocks with calls to a lot of internal
3001 // functions. It can however cause dead functions to be treated as live.
3002 for (const Instruction &I : BB)
3003 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
3004 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00003005 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00003006 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003007 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003008 }
3009
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003010 /// Collection of instructions that need to be explored again, e.g., we
3011 /// did assume they do not transfer control to (one of their) successors.
3012 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003013
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003014 /// Collection of instructions that are known to not transfer control.
3015 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
3016
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003017 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00003018 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003019};
3020
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003021static bool
3022identifyAliveSuccessors(Attributor &A, const CallBase &CB,
3023 AbstractAttribute &AA,
3024 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3025 const IRPosition &IPos = IRPosition::callsite_function(CB);
3026
3027 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
3028 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003029 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003030 if (CB.isTerminator())
3031 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
3032 else
3033 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003034 return false;
3035}
3036
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003037static bool
3038identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
3039 AbstractAttribute &AA,
3040 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3041 bool UsedAssumedInformation =
3042 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00003043
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003044 // First, determine if we can change an invoke to a call assuming the
3045 // callee is nounwind. This is not possible if the personality of the
3046 // function allows to catch asynchronous exceptions.
3047 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
3048 AliveSuccessors.push_back(&II.getUnwindDest()->front());
3049 } else {
3050 const IRPosition &IPos = IRPosition::callsite_function(II);
3051 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003052 if (AANoUnw.isAssumedNoUnwind()) {
3053 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
3054 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003055 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003056 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003057 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003058 return UsedAssumedInformation;
3059}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003060
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003061static Optional<ConstantInt *>
3062getAssumedConstant(Attributor &A, const Value &V, AbstractAttribute &AA,
3063 bool &UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003064 const auto &ValueSimplifyAA =
3065 A.getAAFor<AAValueSimplify>(AA, IRPosition::value(V));
3066 Optional<Value *> SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(A);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003067 UsedAssumedInformation |= !ValueSimplifyAA.isKnown();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003068 if (!SimplifiedV.hasValue())
3069 return llvm::None;
3070 if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue()))
3071 return llvm::None;
3072 return dyn_cast_or_null<ConstantInt>(SimplifiedV.getValue());
3073}
3074
3075static bool
3076identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
3077 AbstractAttribute &AA,
3078 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3079 bool UsedAssumedInformation = false;
3080 if (BI.getNumSuccessors() == 1) {
3081 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3082 } else {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003083 Optional<ConstantInt *> CI =
3084 getAssumedConstant(A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003085 if (!CI.hasValue()) {
3086 // No value yet, assume both edges are dead.
3087 } else if (CI.getValue()) {
3088 const BasicBlock *SuccBB =
3089 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
3090 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003091 } else {
3092 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3093 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003094 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003095 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003096 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003097 return UsedAssumedInformation;
3098}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003099
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003100static bool
3101identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
3102 AbstractAttribute &AA,
3103 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003104 bool UsedAssumedInformation = false;
3105 Optional<ConstantInt *> CI =
3106 getAssumedConstant(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003107 if (!CI.hasValue()) {
3108 // No value yet, assume all edges are dead.
3109 } else if (CI.getValue()) {
3110 for (auto &CaseIt : SI.cases()) {
3111 if (CaseIt.getCaseValue() == CI.getValue()) {
3112 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003113 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003114 }
3115 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05003116 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003117 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003118 } else {
3119 for (const BasicBlock *SuccBB : successors(SI.getParent()))
3120 AliveSuccessors.push_back(&SuccBB->front());
3121 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003122 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003123}
3124
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003125ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003126 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003127
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003128 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
3129 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003130 << ToBeExploredFrom.size() << " exploration points and "
3131 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003132
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003133 // Copy and clear the list of instructions we need to explore from. It is
3134 // refilled with instructions the next update has to look at.
3135 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
3136 ToBeExploredFrom.end());
3137 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003138
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003139 SmallVector<const Instruction *, 8> AliveSuccessors;
3140 while (!Worklist.empty()) {
3141 const Instruction *I = Worklist.pop_back_val();
3142 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003143
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003144 AliveSuccessors.clear();
3145
3146 bool UsedAssumedInformation = false;
3147 switch (I->getOpcode()) {
3148 // TODO: look for (assumed) UB to backwards propagate "deadness".
3149 default:
3150 if (I->isTerminator()) {
3151 for (const BasicBlock *SuccBB : successors(I->getParent()))
3152 AliveSuccessors.push_back(&SuccBB->front());
3153 } else {
3154 AliveSuccessors.push_back(I->getNextNode());
3155 }
3156 break;
3157 case Instruction::Call:
3158 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
3159 *this, AliveSuccessors);
3160 break;
3161 case Instruction::Invoke:
3162 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
3163 *this, AliveSuccessors);
3164 break;
3165 case Instruction::Br:
3166 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
3167 *this, AliveSuccessors);
3168 break;
3169 case Instruction::Switch:
3170 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
3171 *this, AliveSuccessors);
3172 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00003173 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003174
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003175 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003176 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003177 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003178 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003179 if (AliveSuccessors.empty() ||
3180 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
3181 KnownDeadEnds.insert(I);
3182 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003183
3184 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
3185 << AliveSuccessors.size() << " UsedAssumedInformation: "
3186 << UsedAssumedInformation << "\n");
3187
3188 for (const Instruction *AliveSuccessor : AliveSuccessors) {
3189 if (!I->isTerminator()) {
3190 assert(AliveSuccessors.size() == 1 &&
3191 "Non-terminator expected to have a single successor!");
3192 Worklist.push_back(AliveSuccessor);
3193 } else {
3194 if (assumeLive(A, *AliveSuccessor->getParent()))
3195 Worklist.push_back(AliveSuccessor);
3196 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00003197 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003198 }
3199
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003200 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003201
Johannes Doerfertd6207812019-08-07 22:32:38 +00003202 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003203 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003204 // "invalid" and all queries to be answered conservatively without lookups.
3205 // To be in this state we have to (1) finished the exploration and (3) not
3206 // discovered any non-trivial dead end and (2) not ruled unreachable code
3207 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003208 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003209 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
3210 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
3211 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
3212 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003213 return indicatePessimisticFixpoint();
3214 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003215}
3216
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003217/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003218struct AAIsDeadCallSite final : AAIsDeadFunction {
3219 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003220
3221 /// See AbstractAttribute::initialize(...).
3222 void initialize(Attributor &A) override {
3223 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003224 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003225 // sense to specialize attributes for call sites instead of
3226 // redirecting requests to the callee.
3227 llvm_unreachable("Abstract attributes for liveness are not "
3228 "supported for call sites yet!");
3229 }
3230
3231 /// See AbstractAttribute::updateImpl(...).
3232 ChangeStatus updateImpl(Attributor &A) override {
3233 return indicatePessimisticFixpoint();
3234 }
3235
3236 /// See AbstractAttribute::trackStatistics()
3237 void trackStatistics() const override {}
3238};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003239
Hideto Ueno19c07af2019-07-23 08:16:17 +00003240/// -------------------- Dereferenceable Argument Attribute --------------------
3241
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003242template <>
3243ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
3244 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05003245 ChangeStatus CS0 =
3246 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
3247 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003248 return CS0 | CS1;
3249}
3250
Hideto Ueno70576ca2019-08-22 14:18:29 +00003251struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003252 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003253 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00003254
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003255 void initialize(Attributor &A) override {
3256 SmallVector<Attribute, 4> Attrs;
3257 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
3258 Attrs);
3259 for (const Attribute &Attr : Attrs)
3260 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
3261
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003262 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition());
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003263
3264 const IRPosition &IRP = this->getIRPosition();
3265 bool IsFnInterface = IRP.isFnInterfaceKind();
3266 const Function *FnScope = IRP.getAnchorScope();
3267 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
3268 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003269 }
3270
Hideto Ueno19c07af2019-07-23 08:16:17 +00003271 /// See AbstractAttribute::getState()
3272 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00003273 StateType &getState() override { return *this; }
3274 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003275 /// }
3276
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003277 /// Helper function for collecting accessed bytes in must-be-executed-context
3278 void addAccessedBytesForUse(Attributor &A, const Use *U,
3279 const Instruction *I) {
3280 const Value *UseV = U->get();
3281 if (!UseV->getType()->isPointerTy())
3282 return;
3283
3284 Type *PtrTy = UseV->getType();
3285 const DataLayout &DL = A.getDataLayout();
3286 int64_t Offset;
3287 if (const Value *Base = getBasePointerOfAccessPointerOperand(
3288 I, Offset, DL, /*AllowNonInbounds*/ true)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09003289 if (Base == &getAssociatedValue() &&
3290 Attributor::getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003291 uint64_t Size = DL.getTypeStoreSize(PtrTy->getPointerElementType());
3292 addAccessedBytes(Offset, Size);
3293 }
3294 }
3295 return;
3296 }
3297
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003298 /// See AAFromMustBeExecutedContext
3299 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3300 bool IsNonNull = false;
3301 bool TrackUse = false;
3302 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
3303 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003304
3305 addAccessedBytesForUse(A, U, I);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003306 takeKnownDerefBytesMaximum(DerefBytes);
3307 return TrackUse;
3308 }
3309
Hideto Uenodfedae52019-11-29 06:45:07 +00003310 /// See AbstractAttribute::manifest(...).
3311 ChangeStatus manifest(Attributor &A) override {
3312 ChangeStatus Change = AADereferenceable::manifest(A);
3313 if (isAssumedNonNull() && hasAttr(Attribute::DereferenceableOrNull)) {
3314 removeAttrs({Attribute::DereferenceableOrNull});
3315 return ChangeStatus::CHANGED;
3316 }
3317 return Change;
3318 }
3319
Johannes Doerferteccdf082019-08-05 23:35:12 +00003320 void getDeducedAttributes(LLVMContext &Ctx,
3321 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00003322 // TODO: Add *_globally support
3323 if (isAssumedNonNull())
3324 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
3325 Ctx, getAssumedDereferenceableBytes()));
3326 else
3327 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
3328 Ctx, getAssumedDereferenceableBytes()));
3329 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003330
3331 /// See AbstractAttribute::getAsStr().
3332 const std::string getAsStr() const override {
3333 if (!getAssumedDereferenceableBytes())
3334 return "unknown-dereferenceable";
3335 return std::string("dereferenceable") +
3336 (isAssumedNonNull() ? "" : "_or_null") +
3337 (isAssumedGlobal() ? "_globally" : "") + "<" +
3338 std::to_string(getKnownDereferenceableBytes()) + "-" +
3339 std::to_string(getAssumedDereferenceableBytes()) + ">";
3340 }
3341};
3342
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003343/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003344struct AADereferenceableFloating
3345 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
3346 using Base =
3347 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
3348 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00003349
3350 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003351 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003352 ChangeStatus Change = Base::updateImpl(A);
3353
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003354 const DataLayout &DL = A.getDataLayout();
3355
3356 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
3357 unsigned IdxWidth =
3358 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
3359 APInt Offset(IdxWidth, 0);
3360 const Value *Base =
3361 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
3362
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003363 const auto &AA =
3364 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003365 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003366 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003367 // Use IR information if we did not strip anything.
3368 // TODO: track globally.
3369 bool CanBeNull;
3370 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
3371 T.GlobalState.indicatePessimisticFixpoint();
3372 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003373 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003374 DerefBytes = DS.DerefBytesState.getAssumed();
3375 T.GlobalState &= DS.GlobalState;
3376 }
3377
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003378 // For now we do not try to "increase" dereferenceability due to negative
3379 // indices as we first have to come up with code to deal with loops and
3380 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00003381 int64_t OffsetSExt = Offset.getSExtValue();
3382 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00003383 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003384
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003385 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00003386 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003387
Johannes Doerfert785fad32019-08-23 17:29:23 +00003388 if (this == &AA) {
3389 if (!Stripped) {
3390 // If nothing was stripped IR information is all we got.
3391 T.takeKnownDerefBytesMaximum(
3392 std::max(int64_t(0), DerefBytes - OffsetSExt));
3393 T.indicatePessimisticFixpoint();
3394 } else if (OffsetSExt > 0) {
3395 // If something was stripped but there is circular reasoning we look
3396 // for the offset. If it is positive we basically decrease the
3397 // dereferenceable bytes in a circluar loop now, which will simply
3398 // drive them down to the known value in a very slow way which we
3399 // can accelerate.
3400 T.indicatePessimisticFixpoint();
3401 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003402 }
3403
3404 return T.isValidState();
3405 };
3406
3407 DerefState T;
3408 if (!genericValueTraversal<AADereferenceable, DerefState>(
3409 A, getIRPosition(), *this, T, VisitValueCB))
3410 return indicatePessimisticFixpoint();
3411
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003412 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003413 }
3414
3415 /// See AbstractAttribute::trackStatistics()
3416 void trackStatistics() const override {
3417 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
3418 }
3419};
3420
3421/// Dereferenceable attribute for a return value.
3422struct AADereferenceableReturned final
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003423 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
3424 DerefState> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003425 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003426 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl,
3427 DerefState>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003428
3429 /// See AbstractAttribute::trackStatistics()
3430 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003431 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003432 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003433};
3434
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003435/// Dereferenceable attribute for an argument
3436struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003437 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
3438 AADereferenceable, AADereferenceableImpl, DerefState> {
3439 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
3440 AADereferenceable, AADereferenceableImpl, DerefState>;
3441 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003442
3443 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003444 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00003445 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
3446 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003447};
3448
Hideto Ueno19c07af2019-07-23 08:16:17 +00003449/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003450struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003451 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003452 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003453
3454 /// See AbstractAttribute::trackStatistics()
3455 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003456 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003457 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003458};
3459
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003460/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003461struct AADereferenceableCallSiteReturned final
3462 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3463 AADereferenceable, AADereferenceableImpl> {
3464 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3465 AADereferenceable, AADereferenceableImpl>;
3466 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003467
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003468 /// See AbstractAttribute::trackStatistics()
3469 void trackStatistics() const override {
3470 STATS_DECLTRACK_CS_ATTR(dereferenceable);
3471 }
3472};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003473
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003474// ------------------------ Align Argument Attribute ------------------------
3475
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003476static unsigned int getKnownAlignForUse(Attributor &A,
3477 AbstractAttribute &QueryingAA,
3478 Value &AssociatedValue, const Use *U,
3479 const Instruction *I, bool &TrackUse) {
Hideto Ueno78a75022019-11-26 07:51:59 +00003480 // We need to follow common pointer manipulation uses to the accesses they
3481 // feed into.
3482 if (isa<CastInst>(I)) {
3483 TrackUse = true;
3484 return 0;
3485 }
3486 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
3487 if (GEP->hasAllConstantIndices()) {
3488 TrackUse = true;
3489 return 0;
3490 }
3491 }
3492
3493 unsigned Alignment = 0;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003494 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
3495 if (ICS.isBundleOperand(U) || ICS.isCallee(U))
3496 return 0;
3497
3498 unsigned ArgNo = ICS.getArgumentNo(U);
3499 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
3500 // As long as we only use known information there is no need to track
3501 // dependences here.
3502 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP,
3503 /* TrackDependence */ false);
Hideto Ueno78a75022019-11-26 07:51:59 +00003504 Alignment = AlignAA.getKnownAlign();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003505 }
3506
Hideto Ueno78a75022019-11-26 07:51:59 +00003507 const Value *UseV = U->get();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003508 if (auto *SI = dyn_cast<StoreInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003509 Alignment = SI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003510 else if (auto *LI = dyn_cast<LoadInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003511 Alignment = LI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003512
Hideto Ueno78a75022019-11-26 07:51:59 +00003513 if (Alignment <= 1)
3514 return 0;
3515
3516 auto &DL = A.getDataLayout();
3517 int64_t Offset;
3518
3519 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
3520 if (Base == &AssociatedValue) {
3521 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
3522 // So we can say that the maximum power of two which is a divisor of
3523 // gcd(Offset, Alignment) is an alignment.
3524
3525 uint32_t gcd =
3526 greatestCommonDivisor(uint32_t(abs((int32_t)Offset)), Alignment);
3527 Alignment = llvm::PowerOf2Floor(gcd);
3528 }
3529 }
3530
3531 return Alignment;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003532}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003533struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003534 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003535
Johannes Doerfert234eda52019-08-16 19:51:23 +00003536 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003537 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003538 SmallVector<Attribute, 4> Attrs;
3539 getAttrs({Attribute::Alignment}, Attrs);
3540 for (const Attribute &Attr : Attrs)
3541 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003542
3543 if (getIRPosition().isFnInterfaceKind() &&
3544 (!getAssociatedFunction() ||
3545 !getAssociatedFunction()->hasExactDefinition()))
3546 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003547 }
3548
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003549 /// See AbstractAttribute::manifest(...).
3550 ChangeStatus manifest(Attributor &A) override {
3551 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3552
3553 // Check for users that allow alignment annotations.
3554 Value &AnchorVal = getIRPosition().getAnchorValue();
3555 for (const Use &U : AnchorVal.uses()) {
3556 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
3557 if (SI->getPointerOperand() == &AnchorVal)
3558 if (SI->getAlignment() < getAssumedAlign()) {
3559 STATS_DECLTRACK(AAAlign, Store,
3560 "Number of times alignemnt added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00003561 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003562 Changed = ChangeStatus::CHANGED;
3563 }
3564 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
3565 if (LI->getPointerOperand() == &AnchorVal)
3566 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00003567 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003568 STATS_DECLTRACK(AAAlign, Load,
3569 "Number of times alignemnt added to a load");
3570 Changed = ChangeStatus::CHANGED;
3571 }
3572 }
3573 }
3574
Johannes Doerfert81df4522019-08-30 15:22:28 +00003575 return AAAlign::manifest(A) | Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003576 }
3577
Johannes Doerfert81df4522019-08-30 15:22:28 +00003578 // TODO: Provide a helper to determine the implied ABI alignment and check in
3579 // the existing manifest method and a new one for AAAlignImpl that value
3580 // to avoid making the alignment explicit if it did not improve.
3581
3582 /// See AbstractAttribute::getDeducedAttributes
3583 virtual void
3584 getDeducedAttributes(LLVMContext &Ctx,
3585 SmallVectorImpl<Attribute> &Attrs) const override {
3586 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00003587 Attrs.emplace_back(
3588 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00003589 }
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003590 /// See AAFromMustBeExecutedContext
3591 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3592 bool TrackUse = false;
3593
Hideto Ueno4ecf2552019-12-12 13:42:40 +00003594 unsigned int KnownAlign =
3595 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003596 takeKnownMaximum(KnownAlign);
3597
3598 return TrackUse;
3599 }
Johannes Doerfert81df4522019-08-30 15:22:28 +00003600
3601 /// See AbstractAttribute::getAsStr().
3602 const std::string getAsStr() const override {
3603 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
3604 "-" + std::to_string(getAssumedAlign()) + ">")
3605 : "unknown-align";
3606 }
3607};
3608
3609/// Align attribute for a floating value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003610struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
3611 using Base = AAFromMustBeExecutedContext<AAAlign, AAAlignImpl>;
3612 AAAlignFloating(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert81df4522019-08-30 15:22:28 +00003613
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003614 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00003615 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003616 Base::updateImpl(A);
3617
Johannes Doerfert234eda52019-08-16 19:51:23 +00003618 const DataLayout &DL = A.getDataLayout();
3619
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003620 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3621 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003622 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3623 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003624 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003625 const MaybeAlign PA = V.getPointerAlignment(DL);
3626 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003627 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003628 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003629 // Use abstract attribute information.
3630 const AAAlign::StateType &DS =
3631 static_cast<const AAAlign::StateType &>(AA.getState());
3632 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003633 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003634 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003635 };
3636
3637 StateType T;
3638 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3639 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003640 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003641
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003642 // TODO: If we know we visited all incoming values, thus no are assumed
3643 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003644 return clampStateAndIndicateChange(getState(), T);
3645 }
3646
3647 /// See AbstractAttribute::trackStatistics()
3648 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3649};
3650
3651/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003652struct AAAlignReturned final
3653 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003654 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003655 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003656
3657 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003658 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003659};
3660
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003661/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003662struct AAAlignArgument final
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003663 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3664 AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003665 AAAlignArgument(const IRPosition &IRP)
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003666 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3667 AAAlignImpl>(
3668 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003669
3670 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003671 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003672};
3673
Johannes Doerfert234eda52019-08-16 19:51:23 +00003674struct AAAlignCallSiteArgument final : AAAlignFloating {
3675 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003676
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003677 /// See AbstractAttribute::manifest(...).
3678 ChangeStatus manifest(Attributor &A) override {
3679 return AAAlignImpl::manifest(A);
3680 }
3681
Johannes Doerfertdada8132019-12-31 01:27:50 -06003682 /// See AbstractAttribute::updateImpl(Attributor &A).
3683 ChangeStatus updateImpl(Attributor &A) override {
3684 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
3685 if (Argument *Arg = getAssociatedArgument()) {
3686 const auto &ArgAlignAA = A.getAAFor<AAAlign>(
3687 *this, IRPosition::argument(*Arg), /* TrackDependence */ false,
3688 DepClassTy::OPTIONAL);
3689 takeKnownMaximum(ArgAlignAA.getKnownAlign());
3690 }
3691 return Changed;
3692 }
3693
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003694 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003695 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003696};
3697
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003698/// Align attribute deduction for a call site return value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003699struct AAAlignCallSiteReturned final
3700 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3701 AAAlignImpl> {
3702 using Base =
3703 AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3704 AAAlignImpl>;
3705 AAAlignCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003706
3707 /// See AbstractAttribute::initialize(...).
3708 void initialize(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003709 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003710 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003711 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003712 indicatePessimisticFixpoint();
3713 }
3714
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003715 /// See AbstractAttribute::trackStatistics()
3716 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3717};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003718
Johannes Doerferte83f3032019-08-05 23:22:05 +00003719/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003720struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003721 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003722
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003723 /// See AbstractAttribute::initialize(...).
3724 void initialize(Attributor &A) override {
3725 AANoReturn::initialize(A);
3726 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003727 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003728 indicatePessimisticFixpoint();
3729 }
3730
Johannes Doerferte83f3032019-08-05 23:22:05 +00003731 /// See AbstractAttribute::getAsStr().
3732 const std::string getAsStr() const override {
3733 return getAssumed() ? "noreturn" : "may-return";
3734 }
3735
Johannes Doerferte83f3032019-08-05 23:22:05 +00003736 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00003737 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003738 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003739 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003740 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003741 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003742 return ChangeStatus::UNCHANGED;
3743 }
3744};
3745
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003746struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003747 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003748
3749 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003750 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003751};
3752
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003753/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003754struct AANoReturnCallSite final : AANoReturnImpl {
3755 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3756
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003757 /// See AbstractAttribute::updateImpl(...).
3758 ChangeStatus updateImpl(Attributor &A) override {
3759 // TODO: Once we have call site specific value information we can provide
3760 // call site specific liveness information and then it makes
3761 // sense to specialize attributes for call sites arguments instead of
3762 // redirecting requests to the callee argument.
3763 Function *F = getAssociatedFunction();
3764 const IRPosition &FnPos = IRPosition::function(*F);
3765 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3766 return clampStateAndIndicateChange(
3767 getState(),
3768 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3769 }
3770
3771 /// See AbstractAttribute::trackStatistics()
3772 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3773};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003774
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003775/// ----------------------- Variable Capturing ---------------------------------
3776
3777/// A class to hold the state of for no-capture attributes.
3778struct AANoCaptureImpl : public AANoCapture {
3779 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3780
3781 /// See AbstractAttribute::initialize(...).
3782 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003783 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3784 indicateOptimisticFixpoint();
3785 return;
3786 }
3787 Function *AnchorScope = getAnchorScope();
3788 if (isFnInterfaceKind() &&
3789 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3790 indicatePessimisticFixpoint();
3791 return;
3792 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003793
Johannes Doerfert72adda12019-10-10 05:33:21 +00003794 // You cannot "capture" null in the default address space.
3795 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3796 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3797 indicateOptimisticFixpoint();
3798 return;
3799 }
3800
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003801 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003802
3803 // Check what state the associated function can actually capture.
3804 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003805 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003806 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003807 indicatePessimisticFixpoint();
3808 }
3809
3810 /// See AbstractAttribute::updateImpl(...).
3811 ChangeStatus updateImpl(Attributor &A) override;
3812
3813 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3814 virtual void
3815 getDeducedAttributes(LLVMContext &Ctx,
3816 SmallVectorImpl<Attribute> &Attrs) const override {
3817 if (!isAssumedNoCaptureMaybeReturned())
3818 return;
3819
Hideto Ueno37367642019-09-11 06:52:11 +00003820 if (getArgNo() >= 0) {
3821 if (isAssumedNoCapture())
3822 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3823 else if (ManifestInternal)
3824 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3825 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003826 }
3827
3828 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3829 /// depending on the ability of the function associated with \p IRP to capture
3830 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003831 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3832 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003833 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003834 // TODO: Once we have memory behavior attributes we should use them here.
3835
3836 // If we know we cannot communicate or write to memory, we do not care about
3837 // ptr2int anymore.
3838 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3839 F.getReturnType()->isVoidTy()) {
3840 State.addKnownBits(NO_CAPTURE);
3841 return;
3842 }
3843
3844 // A function cannot capture state in memory if it only reads memory, it can
3845 // however return/throw state and the state might be influenced by the
3846 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3847 if (F.onlyReadsMemory())
3848 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3849
3850 // A function cannot communicate state back if it does not through
3851 // exceptions and doesn not return values.
3852 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
3853 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00003854
3855 // Check existing "returned" attributes.
3856 int ArgNo = IRP.getArgNo();
3857 if (F.doesNotThrow() && ArgNo >= 0) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01003858 for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
Johannes Doerfert3839b572019-10-21 00:48:42 +00003859 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00003860 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00003861 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
3862 else if (F.onlyReadsMemory())
3863 State.addKnownBits(NO_CAPTURE);
3864 else
3865 State.addKnownBits(NOT_CAPTURED_IN_RET);
3866 break;
3867 }
3868 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003869 }
3870
3871 /// See AbstractState::getAsStr().
3872 const std::string getAsStr() const override {
3873 if (isKnownNoCapture())
3874 return "known not-captured";
3875 if (isAssumedNoCapture())
3876 return "assumed not-captured";
3877 if (isKnownNoCaptureMaybeReturned())
3878 return "known not-captured-maybe-returned";
3879 if (isAssumedNoCaptureMaybeReturned())
3880 return "assumed not-captured-maybe-returned";
3881 return "assumed-captured";
3882 }
3883};
3884
3885/// Attributor-aware capture tracker.
3886struct AACaptureUseTracker final : public CaptureTracker {
3887
3888 /// Create a capture tracker that can lookup in-flight abstract attributes
3889 /// through the Attributor \p A.
3890 ///
3891 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
3892 /// search is stopped. If a use leads to a return instruction,
3893 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
3894 /// If a use leads to a ptr2int which may capture the value,
3895 /// \p CapturedInInteger is set. If a use is found that is currently assumed
3896 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
3897 /// set. All values in \p PotentialCopies are later tracked as well. For every
3898 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
3899 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
3900 /// conservatively set to true.
3901 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05003902 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003903 SmallVectorImpl<const Value *> &PotentialCopies,
3904 unsigned &RemainingUsesToExplore)
3905 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
3906 PotentialCopies(PotentialCopies),
3907 RemainingUsesToExplore(RemainingUsesToExplore) {}
3908
3909 /// Determine if \p V maybe captured. *Also updates the state!*
3910 bool valueMayBeCaptured(const Value *V) {
3911 if (V->getType()->isPointerTy()) {
3912 PointerMayBeCaptured(V, this);
3913 } else {
3914 State.indicatePessimisticFixpoint();
3915 }
3916 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
3917 }
3918
3919 /// See CaptureTracker::tooManyUses().
3920 void tooManyUses() override {
3921 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
3922 }
3923
3924 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
3925 if (CaptureTracker::isDereferenceableOrNull(O, DL))
3926 return true;
3927 const auto &DerefAA =
3928 A.getAAFor<AADereferenceable>(NoCaptureAA, IRPosition::value(*O));
3929 return DerefAA.getAssumedDereferenceableBytes();
3930 }
3931
3932 /// See CaptureTracker::captured(...).
3933 bool captured(const Use *U) override {
3934 Instruction *UInst = cast<Instruction>(U->getUser());
3935 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
3936 << "\n");
3937
3938 // Because we may reuse the tracker multiple times we keep track of the
3939 // number of explored uses ourselves as well.
3940 if (RemainingUsesToExplore-- == 0) {
3941 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
3942 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3943 /* Return */ true);
3944 }
3945
3946 // Deal with ptr2int by following uses.
3947 if (isa<PtrToIntInst>(UInst)) {
3948 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
3949 return valueMayBeCaptured(UInst);
3950 }
3951
3952 // Explicitly catch return instructions.
3953 if (isa<ReturnInst>(UInst))
3954 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3955 /* Return */ true);
3956
3957 // For now we only use special logic for call sites. However, the tracker
3958 // itself knows about a lot of other non-capturing cases already.
3959 CallSite CS(UInst);
3960 if (!CS || !CS.isArgOperand(U))
3961 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3962 /* Return */ true);
3963
3964 unsigned ArgNo = CS.getArgumentNo(U);
3965 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
3966 // If we have a abstract no-capture attribute for the argument we can use
3967 // it to justify a non-capture attribute here. This allows recursion!
3968 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
3969 if (ArgNoCaptureAA.isAssumedNoCapture())
3970 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3971 /* Return */ false);
3972 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
3973 addPotentialCopy(CS);
3974 return isCapturedIn(/* Memory */ false, /* Integer */ false,
3975 /* Return */ false);
3976 }
3977
3978 // Lastly, we could not find a reason no-capture can be assumed so we don't.
3979 return isCapturedIn(/* Memory */ true, /* Integer */ true,
3980 /* Return */ true);
3981 }
3982
3983 /// Register \p CS as potential copy of the value we are checking.
3984 void addPotentialCopy(CallSite CS) {
3985 PotentialCopies.push_back(CS.getInstruction());
3986 }
3987
3988 /// See CaptureTracker::shouldExplore(...).
3989 bool shouldExplore(const Use *U) override {
3990 // Check liveness.
3991 return !IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()));
3992 }
3993
3994 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
3995 /// \p CapturedInRet, then return the appropriate value for use in the
3996 /// CaptureTracker::captured() interface.
3997 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
3998 bool CapturedInRet) {
3999 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
4000 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
4001 if (CapturedInMem)
4002 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
4003 if (CapturedInInt)
4004 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
4005 if (CapturedInRet)
4006 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
4007 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4008 }
4009
4010private:
4011 /// The attributor providing in-flight abstract attributes.
4012 Attributor &A;
4013
4014 /// The abstract attribute currently updated.
4015 AANoCapture &NoCaptureAA;
4016
4017 /// The abstract liveness state.
4018 const AAIsDead &IsDeadAA;
4019
4020 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05004021 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004022
4023 /// Set of potential copies of the tracked value.
4024 SmallVectorImpl<const Value *> &PotentialCopies;
4025
4026 /// Global counter to limit the number of explored uses.
4027 unsigned &RemainingUsesToExplore;
4028};
4029
4030ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
4031 const IRPosition &IRP = getIRPosition();
4032 const Value *V =
4033 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
4034 if (!V)
4035 return indicatePessimisticFixpoint();
4036
4037 const Function *F =
4038 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
4039 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00004040 const IRPosition &FnPos = IRPosition::function(*F);
4041 const auto &IsDeadAA = A.getAAFor<AAIsDead>(*this, FnPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004042
4043 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004044
Johannes Doerfert3839b572019-10-21 00:48:42 +00004045 // Readonly means we cannot capture through memory.
4046 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4047 if (FnMemAA.isAssumedReadOnly()) {
4048 T.addKnownBits(NOT_CAPTURED_IN_MEM);
4049 if (FnMemAA.isKnownReadOnly())
4050 addKnownBits(NOT_CAPTURED_IN_MEM);
4051 }
4052
4053 // Make sure all returned values are different than the underlying value.
4054 // TODO: we could do this in a more sophisticated way inside
4055 // AAReturnedValues, e.g., track all values that escape through returns
4056 // directly somehow.
4057 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
4058 bool SeenConstant = false;
4059 for (auto &It : RVAA.returned_values()) {
4060 if (isa<Constant>(It.first)) {
4061 if (SeenConstant)
4062 return false;
4063 SeenConstant = true;
4064 } else if (!isa<Argument>(It.first) ||
4065 It.first == getAssociatedArgument())
4066 return false;
4067 }
4068 return true;
4069 };
4070
4071 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, FnPos);
4072 if (NoUnwindAA.isAssumedNoUnwind()) {
4073 bool IsVoidTy = F->getReturnType()->isVoidTy();
4074 const AAReturnedValues *RVAA =
4075 IsVoidTy ? nullptr : &A.getAAFor<AAReturnedValues>(*this, FnPos);
4076 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
4077 T.addKnownBits(NOT_CAPTURED_IN_RET);
4078 if (T.isKnown(NOT_CAPTURED_IN_MEM))
4079 return ChangeStatus::UNCHANGED;
4080 if (NoUnwindAA.isKnownNoUnwind() &&
4081 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
4082 addKnownBits(NOT_CAPTURED_IN_RET);
4083 if (isKnown(NOT_CAPTURED_IN_MEM))
4084 return indicateOptimisticFixpoint();
4085 }
4086 }
4087 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004088
4089 // Use the CaptureTracker interface and logic with the specialized tracker,
4090 // defined in AACaptureUseTracker, that can look at in-flight abstract
4091 // attributes and directly updates the assumed state.
4092 SmallVector<const Value *, 4> PotentialCopies;
4093 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
4094 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
4095 RemainingUsesToExplore);
4096
4097 // Check all potential copies of the associated value until we can assume
4098 // none will be captured or we have to assume at least one might be.
4099 unsigned Idx = 0;
4100 PotentialCopies.push_back(V);
4101 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
4102 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
4103
Johannes Doerfert1a746452019-10-20 22:28:49 -05004104 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004105 auto Assumed = S.getAssumed();
4106 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05004107 if (!isAssumedNoCaptureMaybeReturned())
4108 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004109 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
4110 : ChangeStatus::CHANGED;
4111}
4112
4113/// NoCapture attribute for function arguments.
4114struct AANoCaptureArgument final : AANoCaptureImpl {
4115 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4116
4117 /// See AbstractAttribute::trackStatistics()
4118 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
4119};
4120
4121/// NoCapture attribute for call site arguments.
4122struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
4123 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4124
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004125 /// See AbstractAttribute::initialize(...).
4126 void initialize(Attributor &A) override {
4127 if (Argument *Arg = getAssociatedArgument())
4128 if (Arg->hasByValAttr())
4129 indicateOptimisticFixpoint();
4130 AANoCaptureImpl::initialize(A);
4131 }
4132
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004133 /// See AbstractAttribute::updateImpl(...).
4134 ChangeStatus updateImpl(Attributor &A) override {
4135 // TODO: Once we have call site specific value information we can provide
4136 // call site specific liveness information and then it makes
4137 // sense to specialize attributes for call sites arguments instead of
4138 // redirecting requests to the callee argument.
4139 Argument *Arg = getAssociatedArgument();
4140 if (!Arg)
4141 return indicatePessimisticFixpoint();
4142 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4143 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
4144 return clampStateAndIndicateChange(
4145 getState(),
4146 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
4147 }
4148
4149 /// See AbstractAttribute::trackStatistics()
4150 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
4151};
4152
4153/// NoCapture attribute for floating values.
4154struct AANoCaptureFloating final : AANoCaptureImpl {
4155 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4156
4157 /// See AbstractAttribute::trackStatistics()
4158 void trackStatistics() const override {
4159 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
4160 }
4161};
4162
4163/// NoCapture attribute for function return value.
4164struct AANoCaptureReturned final : AANoCaptureImpl {
4165 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
4166 llvm_unreachable("NoCapture is not applicable to function returns!");
4167 }
4168
4169 /// See AbstractAttribute::initialize(...).
4170 void initialize(Attributor &A) override {
4171 llvm_unreachable("NoCapture is not applicable to function returns!");
4172 }
4173
4174 /// See AbstractAttribute::updateImpl(...).
4175 ChangeStatus updateImpl(Attributor &A) override {
4176 llvm_unreachable("NoCapture is not applicable to function returns!");
4177 }
4178
4179 /// See AbstractAttribute::trackStatistics()
4180 void trackStatistics() const override {}
4181};
4182
4183/// NoCapture attribute deduction for a call site return value.
4184struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
4185 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4186
4187 /// See AbstractAttribute::trackStatistics()
4188 void trackStatistics() const override {
4189 STATS_DECLTRACK_CSRET_ATTR(nocapture)
4190 }
4191};
4192
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004193/// ------------------ Value Simplify Attribute ----------------------------
4194struct AAValueSimplifyImpl : AAValueSimplify {
4195 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
4196
4197 /// See AbstractAttribute::getAsStr().
4198 const std::string getAsStr() const override {
4199 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
4200 : "not-simple";
4201 }
4202
4203 /// See AbstractAttribute::trackStatistics()
4204 void trackStatistics() const override {}
4205
4206 /// See AAValueSimplify::getAssumedSimplifiedValue()
4207 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
4208 if (!getAssumed())
4209 return const_cast<Value *>(&getAssociatedValue());
4210 return SimplifiedAssociatedValue;
4211 }
4212 void initialize(Attributor &A) override {}
4213
4214 /// Helper function for querying AAValueSimplify and updating candicate.
4215 /// \param QueryingValue Value trying to unify with SimplifiedValue
4216 /// \param AccumulatedSimplifiedValue Current simplification result.
4217 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
4218 Value &QueryingValue,
4219 Optional<Value *> &AccumulatedSimplifiedValue) {
4220 // FIXME: Add a typecast support.
4221
4222 auto &ValueSimpifyAA = A.getAAFor<AAValueSimplify>(
4223 QueryingAA, IRPosition::value(QueryingValue));
4224
4225 Optional<Value *> QueryingValueSimplified =
4226 ValueSimpifyAA.getAssumedSimplifiedValue(A);
4227
4228 if (!QueryingValueSimplified.hasValue())
4229 return true;
4230
4231 if (!QueryingValueSimplified.getValue())
4232 return false;
4233
4234 Value &QueryingValueSimplifiedUnwrapped =
4235 *QueryingValueSimplified.getValue();
4236
4237 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
4238 return true;
4239
4240 if (AccumulatedSimplifiedValue.hasValue())
4241 return AccumulatedSimplifiedValue == QueryingValueSimplified;
4242
4243 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << QueryingValue
4244 << " is assumed to be "
4245 << QueryingValueSimplifiedUnwrapped << "\n");
4246
4247 AccumulatedSimplifiedValue = QueryingValueSimplified;
4248 return true;
4249 }
4250
4251 /// See AbstractAttribute::manifest(...).
4252 ChangeStatus manifest(Attributor &A) override {
4253 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4254
4255 if (!SimplifiedAssociatedValue.hasValue() ||
4256 !SimplifiedAssociatedValue.getValue())
4257 return Changed;
4258
4259 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
4260 // We can replace the AssociatedValue with the constant.
4261 Value &V = getAssociatedValue();
4262 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
4263 LLVM_DEBUG(dbgs() << "[Attributor][ValueSimplify] " << V << " -> " << *C
4264 << "\n");
Hideto Ueno34fe8d02019-12-30 17:08:48 +09004265 A.changeValueAfterManifest(V, *C);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004266 Changed = ChangeStatus::CHANGED;
4267 }
4268 }
4269
4270 return Changed | AAValueSimplify::manifest(A);
4271 }
4272
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004273 /// See AbstractState::indicatePessimisticFixpoint(...).
4274 ChangeStatus indicatePessimisticFixpoint() override {
4275 // NOTE: Associated value will be returned in a pessimistic fixpoint and is
4276 // regarded as known. That's why`indicateOptimisticFixpoint` is called.
4277 SimplifiedAssociatedValue = &getAssociatedValue();
4278 return indicateOptimisticFixpoint();
4279 }
4280
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004281protected:
4282 // An assumed simplified value. Initially, it is set to Optional::None, which
4283 // means that the value is not clear under current assumption. If in the
4284 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4285 // returns orignal associated value.
4286 Optional<Value *> SimplifiedAssociatedValue;
4287};
4288
4289struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
4290 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4291
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004292 void initialize(Attributor &A) override {
4293 AAValueSimplifyImpl::initialize(A);
4294 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
4295 indicatePessimisticFixpoint();
4296 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
4297 /* IgnoreSubsumingPositions */ true))
4298 indicatePessimisticFixpoint();
4299 }
4300
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004301 /// See AbstractAttribute::updateImpl(...).
4302 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004303 // Byval is only replacable if it is readonly otherwise we would write into
4304 // the replaced value and not the copy that byval creates implicitly.
4305 Argument *Arg = getAssociatedArgument();
4306 if (Arg->hasByValAttr()) {
4307 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
4308 if (!MemAA.isAssumedReadOnly())
4309 return indicatePessimisticFixpoint();
4310 }
4311
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004312 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4313
Johannes Doerfert661db042019-10-07 23:14:58 +00004314 auto PredForCallSite = [&](AbstractCallSite ACS) {
4315 // Check if we have an associated argument or not (which can happen for
4316 // callback calls).
Johannes Doerferte360ee62019-11-01 18:45:25 -05004317 Value *ArgOp = ACS.getCallArgOperand(getArgNo());
4318 if (!ArgOp)
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004319 return false;
Johannes Doerferte360ee62019-11-01 18:45:25 -05004320 // We can only propagate thread independent values through callbacks.
4321 // This is different to direct/indirect call sites because for them we
4322 // know the thread executing the caller and callee is the same. For
4323 // callbacks this is not guaranteed, thus a thread dependent value could
4324 // be different for the caller and callee, making it invalid to propagate.
4325 if (ACS.isCallbackCall())
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004326 if (auto *C = dyn_cast<Constant>(ArgOp))
Johannes Doerferte360ee62019-11-01 18:45:25 -05004327 if (C->isThreadDependent())
4328 return false;
4329 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004330 };
4331
4332 if (!A.checkForAllCallSites(PredForCallSite, *this, true))
4333 return indicatePessimisticFixpoint();
4334
4335 // If a candicate was found in this update, return CHANGED.
4336 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4337 ? ChangeStatus::UNCHANGED
4338 : ChangeStatus ::CHANGED;
4339 }
4340
4341 /// See AbstractAttribute::trackStatistics()
4342 void trackStatistics() const override {
4343 STATS_DECLTRACK_ARG_ATTR(value_simplify)
4344 }
4345};
4346
4347struct AAValueSimplifyReturned : AAValueSimplifyImpl {
4348 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4349
4350 /// See AbstractAttribute::updateImpl(...).
4351 ChangeStatus updateImpl(Attributor &A) override {
4352 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4353
4354 auto PredForReturned = [&](Value &V) {
4355 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4356 };
4357
4358 if (!A.checkForAllReturnedValues(PredForReturned, *this))
4359 return indicatePessimisticFixpoint();
4360
4361 // If a candicate was found in this update, return CHANGED.
4362 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4363 ? ChangeStatus::UNCHANGED
4364 : ChangeStatus ::CHANGED;
4365 }
4366 /// See AbstractAttribute::trackStatistics()
4367 void trackStatistics() const override {
4368 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
4369 }
4370};
4371
4372struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4373 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4374
4375 /// See AbstractAttribute::initialize(...).
4376 void initialize(Attributor &A) override {
4377 Value &V = getAnchorValue();
4378
4379 // TODO: add other stuffs
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004380 if (isa<Constant>(V))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004381 indicatePessimisticFixpoint();
4382 }
4383
4384 /// See AbstractAttribute::updateImpl(...).
4385 ChangeStatus updateImpl(Attributor &A) override {
4386 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4387
4388 auto VisitValueCB = [&](Value &V, BooleanState, bool Stripped) -> bool {
4389 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
4390 if (!Stripped && this == &AA) {
4391 // TODO: Look the instruction and check recursively.
4392 LLVM_DEBUG(
4393 dbgs() << "[Attributor][ValueSimplify] Can't be stripped more : "
4394 << V << "\n");
4395 indicatePessimisticFixpoint();
4396 return false;
4397 }
4398 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4399 };
4400
4401 if (!genericValueTraversal<AAValueSimplify, BooleanState>(
4402 A, getIRPosition(), *this, static_cast<BooleanState &>(*this),
4403 VisitValueCB))
4404 return indicatePessimisticFixpoint();
4405
4406 // If a candicate was found in this update, return CHANGED.
4407
4408 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4409 ? ChangeStatus::UNCHANGED
4410 : ChangeStatus ::CHANGED;
4411 }
4412
4413 /// See AbstractAttribute::trackStatistics()
4414 void trackStatistics() const override {
4415 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
4416 }
4417};
4418
4419struct AAValueSimplifyFunction : AAValueSimplifyImpl {
4420 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4421
4422 /// See AbstractAttribute::initialize(...).
4423 void initialize(Attributor &A) override {
4424 SimplifiedAssociatedValue = &getAnchorValue();
4425 indicateOptimisticFixpoint();
4426 }
4427 /// See AbstractAttribute::initialize(...).
4428 ChangeStatus updateImpl(Attributor &A) override {
4429 llvm_unreachable(
4430 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
4431 }
4432 /// See AbstractAttribute::trackStatistics()
4433 void trackStatistics() const override {
4434 STATS_DECLTRACK_FN_ATTR(value_simplify)
4435 }
4436};
4437
4438struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
4439 AAValueSimplifyCallSite(const IRPosition &IRP)
4440 : AAValueSimplifyFunction(IRP) {}
4441 /// See AbstractAttribute::trackStatistics()
4442 void trackStatistics() const override {
4443 STATS_DECLTRACK_CS_ATTR(value_simplify)
4444 }
4445};
4446
4447struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
4448 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
4449 : AAValueSimplifyReturned(IRP) {}
4450
4451 void trackStatistics() const override {
4452 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
4453 }
4454};
4455struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
4456 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
4457 : AAValueSimplifyFloating(IRP) {}
4458
4459 void trackStatistics() const override {
4460 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
4461 }
4462};
4463
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004464/// ----------------------- Heap-To-Stack Conversion ---------------------------
4465struct AAHeapToStackImpl : public AAHeapToStack {
4466 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
4467
4468 const std::string getAsStr() const override {
4469 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
4470 }
4471
4472 ChangeStatus manifest(Attributor &A) override {
4473 assert(getState().isValidState() &&
4474 "Attempted to manifest an invalid state!");
4475
4476 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4477 Function *F = getAssociatedFunction();
4478 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4479
4480 for (Instruction *MallocCall : MallocCalls) {
4481 // This malloc cannot be replaced.
4482 if (BadMallocCalls.count(MallocCall))
4483 continue;
4484
4485 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
4486 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
4487 A.deleteAfterManifest(*FreeCall);
4488 HasChanged = ChangeStatus::CHANGED;
4489 }
4490
4491 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
4492 << "\n");
4493
4494 Constant *Size;
4495 if (isCallocLikeFn(MallocCall, TLI)) {
4496 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
4497 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
4498 APInt TotalSize = SizeT->getValue() * Num->getValue();
4499 Size =
4500 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
4501 } else {
4502 Size = cast<ConstantInt>(MallocCall->getOperand(0));
4503 }
4504
4505 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
4506 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
4507 Size, "", MallocCall->getNextNode());
4508
4509 if (AI->getType() != MallocCall->getType())
4510 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
4511 AI->getNextNode());
4512
Johannes Doerfert5d346022019-12-13 22:11:42 -06004513 replaceAllInstructionUsesWith(*MallocCall, *AI);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004514
4515 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
4516 auto *NBB = II->getNormalDest();
4517 BranchInst::Create(NBB, MallocCall->getParent());
4518 A.deleteAfterManifest(*MallocCall);
4519 } else {
4520 A.deleteAfterManifest(*MallocCall);
4521 }
4522
4523 if (isCallocLikeFn(MallocCall, TLI)) {
4524 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
4525 AI->getNextNode());
4526 Value *Ops[] = {
4527 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
4528 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
4529
4530 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
4531 Module *M = F->getParent();
4532 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
4533 CallInst::Create(Fn, Ops, "", BI->getNextNode());
4534 }
4535 HasChanged = ChangeStatus::CHANGED;
4536 }
4537
4538 return HasChanged;
4539 }
4540
4541 /// Collection of all malloc calls in a function.
4542 SmallSetVector<Instruction *, 4> MallocCalls;
4543
4544 /// Collection of malloc calls that cannot be converted.
4545 DenseSet<const Instruction *> BadMallocCalls;
4546
4547 /// A map for each malloc call to the set of associated free calls.
4548 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
4549
4550 ChangeStatus updateImpl(Attributor &A) override;
4551};
4552
4553ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4554 const Function *F = getAssociatedFunction();
4555 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4556
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004557 MustBeExecutedContextExplorer &Explorer =
4558 A.getInfoCache().getMustBeExecutedContextExplorer();
4559
4560 auto FreeCheck = [&](Instruction &I) {
4561 const auto &Frees = FreesForMalloc.lookup(&I);
4562 if (Frees.size() != 1)
4563 return false;
4564 Instruction *UniqueFree = *Frees.begin();
4565 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
4566 };
4567
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004568 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004569 bool ValidUsesOnly = true;
4570 bool MustUse = true;
Hideto Ueno827bade2019-12-12 12:26:30 +00004571 auto Pred = [&](const Use &U, bool &Follow) -> bool {
4572 Instruction *UserI = cast<Instruction>(U.getUser());
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004573 if (isa<LoadInst>(UserI))
Hideto Ueno827bade2019-12-12 12:26:30 +00004574 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004575 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004576 if (SI->getValueOperand() == U.get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004577 LLVM_DEBUG(dbgs()
4578 << "[H2S] escaping store to memory: " << *UserI << "\n");
4579 ValidUsesOnly = false;
4580 } else {
4581 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004582 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004583 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004584 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004585 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004586 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
4587 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004588 // Record malloc.
4589 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004590 if (MustUse) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004591 FreesForMalloc[&I].insert(UserI);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004592 } else {
4593 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
4594 << *UserI << "\n");
4595 ValidUsesOnly = false;
4596 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004597 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004598 }
4599
Hideto Ueno827bade2019-12-12 12:26:30 +00004600 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004601
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004602 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
4603 *this, IRPosition::callsite_argument(*CB, ArgNo));
4604
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004605 // If a callsite argument use is nofree, we are fine.
4606 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
4607 *this, IRPosition::callsite_argument(*CB, ArgNo));
4608
Hideto Ueno827bade2019-12-12 12:26:30 +00004609 if (!NoCaptureAA.isAssumedNoCapture() ||
4610 !ArgNoFreeAA.isAssumedNoFree()) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004611 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004612 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004613 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004614 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004615 }
4616
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004617 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
4618 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
4619 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Hideto Ueno827bade2019-12-12 12:26:30 +00004620 Follow = true;
4621 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004622 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004623 // Unknown user for which we can not track uses further (in a way that
4624 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004625 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004626 ValidUsesOnly = false;
Hideto Ueno827bade2019-12-12 12:26:30 +00004627 return true;
4628 };
4629 A.checkForAllUses(Pred, *this, I);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004630 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004631 };
4632
4633 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004634 if (BadMallocCalls.count(&I))
4635 return true;
4636
4637 bool IsMalloc = isMallocLikeFn(&I, TLI);
4638 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
4639 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004640 BadMallocCalls.insert(&I);
4641 return true;
4642 }
4643
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004644 if (IsMalloc) {
4645 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004646 if (Size->getValue().ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004647 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004648 MallocCalls.insert(&I);
4649 return true;
4650 }
4651 } else if (IsCalloc) {
4652 bool Overflow = false;
4653 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
4654 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
4655 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004656 .ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004657 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004658 MallocCalls.insert(&I);
4659 return true;
4660 }
4661 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004662
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004663 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004664 return true;
4665 };
4666
4667 size_t NumBadMallocs = BadMallocCalls.size();
4668
4669 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4670
4671 if (NumBadMallocs != BadMallocCalls.size())
4672 return ChangeStatus::CHANGED;
4673
4674 return ChangeStatus::UNCHANGED;
4675}
4676
4677struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4678 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4679
4680 /// See AbstractAttribute::trackStatistics()
4681 void trackStatistics() const override {
4682 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004683 "Number of malloc calls converted to allocas");
4684 for (auto *C : MallocCalls)
4685 if (!BadMallocCalls.count(C))
4686 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004687 }
4688};
4689
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004690/// -------------------- Memory Behavior Attributes ----------------------------
4691/// Includes read-none, read-only, and write-only.
4692/// ----------------------------------------------------------------------------
4693struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
4694 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
4695
4696 /// See AbstractAttribute::initialize(...).
4697 void initialize(Attributor &A) override {
4698 intersectAssumedBits(BEST_STATE);
4699 getKnownStateFromValue(getIRPosition(), getState());
4700 IRAttribute::initialize(A);
4701 }
4702
4703 /// Return the memory behavior information encoded in the IR for \p IRP.
4704 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004705 BitIntegerState &State,
4706 bool IgnoreSubsumingPositions = false) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004707 SmallVector<Attribute, 2> Attrs;
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004708 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004709 for (const Attribute &Attr : Attrs) {
4710 switch (Attr.getKindAsEnum()) {
4711 case Attribute::ReadNone:
4712 State.addKnownBits(NO_ACCESSES);
4713 break;
4714 case Attribute::ReadOnly:
4715 State.addKnownBits(NO_WRITES);
4716 break;
4717 case Attribute::WriteOnly:
4718 State.addKnownBits(NO_READS);
4719 break;
4720 default:
4721 llvm_unreachable("Unexpcted attribute!");
4722 }
4723 }
4724
4725 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
4726 if (!I->mayReadFromMemory())
4727 State.addKnownBits(NO_READS);
4728 if (!I->mayWriteToMemory())
4729 State.addKnownBits(NO_WRITES);
4730 }
4731 }
4732
4733 /// See AbstractAttribute::getDeducedAttributes(...).
4734 void getDeducedAttributes(LLVMContext &Ctx,
4735 SmallVectorImpl<Attribute> &Attrs) const override {
4736 assert(Attrs.size() == 0);
4737 if (isAssumedReadNone())
4738 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
4739 else if (isAssumedReadOnly())
4740 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
4741 else if (isAssumedWriteOnly())
4742 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
4743 assert(Attrs.size() <= 1);
4744 }
4745
4746 /// See AbstractAttribute::manifest(...).
4747 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05004748 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004749
4750 // Check if we would improve the existing attributes first.
4751 SmallVector<Attribute, 4> DeducedAttrs;
4752 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
4753 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
4754 return IRP.hasAttr(Attr.getKindAsEnum(),
4755 /* IgnoreSubsumingPositions */ true);
4756 }))
4757 return ChangeStatus::UNCHANGED;
4758
4759 // Clear existing attributes.
4760 IRP.removeAttrs(AttrKinds);
4761
4762 // Use the generic manifest method.
4763 return IRAttribute::manifest(A);
4764 }
4765
4766 /// See AbstractState::getAsStr().
4767 const std::string getAsStr() const override {
4768 if (isAssumedReadNone())
4769 return "readnone";
4770 if (isAssumedReadOnly())
4771 return "readonly";
4772 if (isAssumedWriteOnly())
4773 return "writeonly";
4774 return "may-read/write";
4775 }
4776
4777 /// The set of IR attributes AAMemoryBehavior deals with.
4778 static const Attribute::AttrKind AttrKinds[3];
4779};
4780
4781const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
4782 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
4783
4784/// Memory behavior attribute for a floating value.
4785struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
4786 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4787
4788 /// See AbstractAttribute::initialize(...).
4789 void initialize(Attributor &A) override {
4790 AAMemoryBehaviorImpl::initialize(A);
4791 // Initialize the use vector with all direct uses of the associated value.
4792 for (const Use &U : getAssociatedValue().uses())
4793 Uses.insert(&U);
4794 }
4795
4796 /// See AbstractAttribute::updateImpl(...).
4797 ChangeStatus updateImpl(Attributor &A) override;
4798
4799 /// See AbstractAttribute::trackStatistics()
4800 void trackStatistics() const override {
4801 if (isAssumedReadNone())
4802 STATS_DECLTRACK_FLOATING_ATTR(readnone)
4803 else if (isAssumedReadOnly())
4804 STATS_DECLTRACK_FLOATING_ATTR(readonly)
4805 else if (isAssumedWriteOnly())
4806 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
4807 }
4808
4809private:
4810 /// Return true if users of \p UserI might access the underlying
4811 /// variable/location described by \p U and should therefore be analyzed.
4812 bool followUsersOfUseIn(Attributor &A, const Use *U,
4813 const Instruction *UserI);
4814
4815 /// Update the state according to the effect of use \p U in \p UserI.
4816 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
4817
4818protected:
4819 /// Container for (transitive) uses of the associated argument.
4820 SetVector<const Use *> Uses;
4821};
4822
4823/// Memory behavior attribute for function argument.
4824struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
4825 AAMemoryBehaviorArgument(const IRPosition &IRP)
4826 : AAMemoryBehaviorFloating(IRP) {}
4827
4828 /// See AbstractAttribute::initialize(...).
4829 void initialize(Attributor &A) override {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004830 intersectAssumedBits(BEST_STATE);
4831 const IRPosition &IRP = getIRPosition();
4832 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
4833 // can query it when we use has/getAttr. That would allow us to reuse the
4834 // initialize of the base class here.
4835 bool HasByVal =
4836 IRP.hasAttr({Attribute::ByVal}, /* IgnoreSubsumingPositions */ true);
4837 getKnownStateFromValue(IRP, getState(),
4838 /* IgnoreSubsumingPositions */ HasByVal);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004839
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004840 // Initialize the use vector with all direct uses of the associated value.
4841 Argument *Arg = getAssociatedArgument();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004842 if (!Arg || !Arg->getParent()->hasExactDefinition()) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004843 indicatePessimisticFixpoint();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004844 } else {
4845 // Initialize the use vector with all direct uses of the associated value.
4846 for (const Use &U : Arg->uses())
4847 Uses.insert(&U);
4848 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004849 }
4850
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00004851 ChangeStatus manifest(Attributor &A) override {
4852 // TODO: From readattrs.ll: "inalloca parameters are always
4853 // considered written"
4854 if (hasAttr({Attribute::InAlloca})) {
4855 removeKnownBits(NO_WRITES);
4856 removeAssumedBits(NO_WRITES);
4857 }
4858 return AAMemoryBehaviorFloating::manifest(A);
4859 }
4860
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004861 /// See AbstractAttribute::trackStatistics()
4862 void trackStatistics() const override {
4863 if (isAssumedReadNone())
4864 STATS_DECLTRACK_ARG_ATTR(readnone)
4865 else if (isAssumedReadOnly())
4866 STATS_DECLTRACK_ARG_ATTR(readonly)
4867 else if (isAssumedWriteOnly())
4868 STATS_DECLTRACK_ARG_ATTR(writeonly)
4869 }
4870};
4871
4872struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
4873 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
4874 : AAMemoryBehaviorArgument(IRP) {}
4875
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004876 /// See AbstractAttribute::initialize(...).
4877 void initialize(Attributor &A) override {
4878 if (Argument *Arg = getAssociatedArgument()) {
4879 if (Arg->hasByValAttr()) {
4880 addKnownBits(NO_WRITES);
4881 removeKnownBits(NO_READS);
4882 removeAssumedBits(NO_READS);
4883 }
4884 } else {
4885 }
4886 AAMemoryBehaviorArgument::initialize(A);
4887 }
4888
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004889 /// See AbstractAttribute::updateImpl(...).
4890 ChangeStatus updateImpl(Attributor &A) override {
4891 // TODO: Once we have call site specific value information we can provide
4892 // call site specific liveness liveness information and then it makes
4893 // sense to specialize attributes for call sites arguments instead of
4894 // redirecting requests to the callee argument.
4895 Argument *Arg = getAssociatedArgument();
4896 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4897 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
4898 return clampStateAndIndicateChange(
4899 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05004900 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004901 }
4902
4903 /// See AbstractAttribute::trackStatistics()
4904 void trackStatistics() const override {
4905 if (isAssumedReadNone())
4906 STATS_DECLTRACK_CSARG_ATTR(readnone)
4907 else if (isAssumedReadOnly())
4908 STATS_DECLTRACK_CSARG_ATTR(readonly)
4909 else if (isAssumedWriteOnly())
4910 STATS_DECLTRACK_CSARG_ATTR(writeonly)
4911 }
4912};
4913
4914/// Memory behavior attribute for a call site return position.
4915struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
4916 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
4917 : AAMemoryBehaviorFloating(IRP) {}
4918
4919 /// See AbstractAttribute::manifest(...).
4920 ChangeStatus manifest(Attributor &A) override {
4921 // We do not annotate returned values.
4922 return ChangeStatus::UNCHANGED;
4923 }
4924
4925 /// See AbstractAttribute::trackStatistics()
4926 void trackStatistics() const override {}
4927};
4928
4929/// An AA to represent the memory behavior function attributes.
4930struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
4931 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4932
4933 /// See AbstractAttribute::updateImpl(Attributor &A).
4934 virtual ChangeStatus updateImpl(Attributor &A) override;
4935
4936 /// See AbstractAttribute::manifest(...).
4937 ChangeStatus manifest(Attributor &A) override {
4938 Function &F = cast<Function>(getAnchorValue());
4939 if (isAssumedReadNone()) {
4940 F.removeFnAttr(Attribute::ArgMemOnly);
4941 F.removeFnAttr(Attribute::InaccessibleMemOnly);
4942 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
4943 }
4944 return AAMemoryBehaviorImpl::manifest(A);
4945 }
4946
4947 /// See AbstractAttribute::trackStatistics()
4948 void trackStatistics() const override {
4949 if (isAssumedReadNone())
4950 STATS_DECLTRACK_FN_ATTR(readnone)
4951 else if (isAssumedReadOnly())
4952 STATS_DECLTRACK_FN_ATTR(readonly)
4953 else if (isAssumedWriteOnly())
4954 STATS_DECLTRACK_FN_ATTR(writeonly)
4955 }
4956};
4957
4958/// AAMemoryBehavior attribute for call sites.
4959struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
4960 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
4961
4962 /// See AbstractAttribute::initialize(...).
4963 void initialize(Attributor &A) override {
4964 AAMemoryBehaviorImpl::initialize(A);
4965 Function *F = getAssociatedFunction();
4966 if (!F || !F->hasExactDefinition())
4967 indicatePessimisticFixpoint();
4968 }
4969
4970 /// See AbstractAttribute::updateImpl(...).
4971 ChangeStatus updateImpl(Attributor &A) override {
4972 // TODO: Once we have call site specific value information we can provide
4973 // call site specific liveness liveness information and then it makes
4974 // sense to specialize attributes for call sites arguments instead of
4975 // redirecting requests to the callee argument.
4976 Function *F = getAssociatedFunction();
4977 const IRPosition &FnPos = IRPosition::function(*F);
4978 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
4979 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05004980 getState(),
4981 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004982 }
4983
4984 /// See AbstractAttribute::trackStatistics()
4985 void trackStatistics() const override {
4986 if (isAssumedReadNone())
4987 STATS_DECLTRACK_CS_ATTR(readnone)
4988 else if (isAssumedReadOnly())
4989 STATS_DECLTRACK_CS_ATTR(readonly)
4990 else if (isAssumedWriteOnly())
4991 STATS_DECLTRACK_CS_ATTR(writeonly)
4992 }
4993};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00004994} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00004995
4996ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
4997
4998 // The current assumed state used to determine a change.
4999 auto AssumedState = getAssumed();
5000
5001 auto CheckRWInst = [&](Instruction &I) {
5002 // If the instruction has an own memory behavior state, use it to restrict
5003 // the local state. No further analysis is required as the other memory
5004 // state is as optimistic as it gets.
5005 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
5006 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
5007 *this, IRPosition::callsite_function(ICS));
5008 intersectAssumedBits(MemBehaviorAA.getAssumed());
5009 return !isAtFixpoint();
5010 }
5011
5012 // Remove access kind modifiers if necessary.
5013 if (I.mayReadFromMemory())
5014 removeAssumedBits(NO_READS);
5015 if (I.mayWriteToMemory())
5016 removeAssumedBits(NO_WRITES);
5017 return !isAtFixpoint();
5018 };
5019
5020 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
5021 return indicatePessimisticFixpoint();
5022
5023 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5024 : ChangeStatus::UNCHANGED;
5025}
5026
5027ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
5028
5029 const IRPosition &IRP = getIRPosition();
5030 const IRPosition &FnPos = IRPosition::function_scope(IRP);
5031 AAMemoryBehavior::StateType &S = getState();
5032
5033 // First, check the function scope. We take the known information and we avoid
5034 // work if the assumed information implies the current assumed information for
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005035 // this attribute. This is a valid for all but byval arguments.
5036 Argument *Arg = IRP.getAssociatedArgument();
5037 AAMemoryBehavior::base_t FnMemAssumedState =
5038 AAMemoryBehavior::StateType::getWorstState();
5039 if (!Arg || !Arg->hasByValAttr()) {
5040 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
5041 FnMemAssumedState = FnMemAA.getAssumed();
5042 S.addKnownBits(FnMemAA.getKnown());
5043 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
5044 return ChangeStatus::UNCHANGED;
5045 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005046
5047 // Make sure the value is not captured (except through "return"), if
5048 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005049 // check the potential aliases introduced by the capture. However, no need
5050 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert28880192019-12-31 00:57:00 -06005051 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
5052 *this, IRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005053 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005054 S.intersectAssumedBits(FnMemAssumedState);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005055 return ChangeStatus::CHANGED;
5056 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005057
5058 // The current assumed state used to determine a change.
5059 auto AssumedState = S.getAssumed();
5060
5061 // Liveness information to exclude dead users.
5062 // TODO: Take the FnPos once we have call site specific liveness information.
5063 const auto &LivenessAA = A.getAAFor<AAIsDead>(
5064 *this, IRPosition::function(*IRP.getAssociatedFunction()));
5065
5066 // Visit and expand uses until all are analyzed or a fixpoint is reached.
5067 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
5068 const Use *U = Uses[i];
5069 Instruction *UserI = cast<Instruction>(U->getUser());
5070 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
5071 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
5072 << "]\n");
5073 if (LivenessAA.isAssumedDead(UserI))
5074 continue;
5075
5076 // Check if the users of UserI should also be visited.
5077 if (followUsersOfUseIn(A, U, UserI))
5078 for (const Use &UserIUse : UserI->uses())
5079 Uses.insert(&UserIUse);
5080
5081 // If UserI might touch memory we analyze the use in detail.
5082 if (UserI->mayReadOrWriteMemory())
5083 analyzeUseIn(A, U, UserI);
5084 }
5085
5086 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5087 : ChangeStatus::UNCHANGED;
5088}
5089
5090bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
5091 const Instruction *UserI) {
5092 // The loaded value is unrelated to the pointer argument, no need to
5093 // follow the users of the load.
5094 if (isa<LoadInst>(UserI))
5095 return false;
5096
5097 // By default we follow all uses assuming UserI might leak information on U,
5098 // we have special handling for call sites operands though.
5099 ImmutableCallSite ICS(UserI);
5100 if (!ICS || !ICS.isArgOperand(U))
5101 return true;
5102
5103 // If the use is a call argument known not to be captured, the users of
5104 // the call do not need to be visited because they have to be unrelated to
5105 // the input. Note that this check is not trivial even though we disallow
5106 // general capturing of the underlying argument. The reason is that the
5107 // call might the argument "through return", which we allow and for which we
5108 // need to check call users.
5109 unsigned ArgNo = ICS.getArgumentNo(U);
5110 const auto &ArgNoCaptureAA =
5111 A.getAAFor<AANoCapture>(*this, IRPosition::callsite_argument(ICS, ArgNo));
5112 return !ArgNoCaptureAA.isAssumedNoCapture();
5113}
5114
5115void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
5116 const Instruction *UserI) {
5117 assert(UserI->mayReadOrWriteMemory());
5118
5119 switch (UserI->getOpcode()) {
5120 default:
5121 // TODO: Handle all atomics and other side-effect operations we know of.
5122 break;
5123 case Instruction::Load:
5124 // Loads cause the NO_READS property to disappear.
5125 removeAssumedBits(NO_READS);
5126 return;
5127
5128 case Instruction::Store:
5129 // Stores cause the NO_WRITES property to disappear if the use is the
5130 // pointer operand. Note that we do assume that capturing was taken care of
5131 // somewhere else.
5132 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
5133 removeAssumedBits(NO_WRITES);
5134 return;
5135
5136 case Instruction::Call:
5137 case Instruction::CallBr:
5138 case Instruction::Invoke: {
5139 // For call sites we look at the argument memory behavior attribute (this
5140 // could be recursive!) in order to restrict our own state.
5141 ImmutableCallSite ICS(UserI);
5142
5143 // Give up on operand bundles.
5144 if (ICS.isBundleOperand(U)) {
5145 indicatePessimisticFixpoint();
5146 return;
5147 }
5148
5149 // Calling a function does read the function pointer, maybe write it if the
5150 // function is self-modifying.
5151 if (ICS.isCallee(U)) {
5152 removeAssumedBits(NO_READS);
5153 break;
5154 }
5155
5156 // Adjust the possible access behavior based on the information on the
5157 // argument.
5158 unsigned ArgNo = ICS.getArgumentNo(U);
5159 const IRPosition &ArgPos = IRPosition::callsite_argument(ICS, ArgNo);
5160 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
5161 // "assumed" has at most the same bits as the MemBehaviorAA assumed
5162 // and at least "known".
5163 intersectAssumedBits(MemBehaviorAA.getAssumed());
5164 return;
5165 }
5166 };
5167
5168 // Generally, look at the "may-properties" and adjust the assumed state if we
5169 // did not trigger special handling before.
5170 if (UserI->mayReadFromMemory())
5171 removeAssumedBits(NO_READS);
5172 if (UserI->mayWriteToMemory())
5173 removeAssumedBits(NO_WRITES);
5174}
5175
Johannes Doerfertaade7822019-06-05 03:02:24 +00005176/// ----------------------------------------------------------------------------
5177/// Attributor
5178/// ----------------------------------------------------------------------------
5179
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005180bool Attributor::isAssumedDead(const AbstractAttribute &AA,
5181 const AAIsDead *LivenessAA) {
5182 const Instruction *CtxI = AA.getIRPosition().getCtxI();
5183 if (!CtxI)
5184 return false;
5185
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005186 // TODO: Find a good way to utilize fine and coarse grained liveness
5187 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005188 if (!LivenessAA)
5189 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00005190 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
5191 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00005192
5193 // Don't check liveness for AAIsDead.
5194 if (&AA == LivenessAA)
5195 return false;
5196
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005197 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005198 return false;
5199
Johannes Doerfert19b00432019-08-26 17:48:05 +00005200 // We actually used liveness information so we have to record a dependence.
Johannes Doerfert680f6382019-11-02 02:48:05 -05005201 recordDependence(*LivenessAA, AA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005202
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005203 return true;
5204}
5205
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005206bool Attributor::checkForAllUses(
5207 const function_ref<bool(const Use &, bool &)> &Pred,
5208 const AbstractAttribute &QueryingAA, const Value &V) {
5209 const IRPosition &IRP = QueryingAA.getIRPosition();
5210 SmallVector<const Use *, 16> Worklist;
5211 SmallPtrSet<const Use *, 16> Visited;
5212
5213 for (const Use &U : V.uses())
5214 Worklist.push_back(&U);
5215
5216 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
5217 << " initial uses to check\n");
5218
5219 if (Worklist.empty())
5220 return true;
5221
5222 bool AnyDead = false;
5223 const Function *ScopeFn = IRP.getAnchorScope();
5224 const auto *LivenessAA =
5225 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
5226 /* TrackDependence */ false)
5227 : nullptr;
5228
5229 while (!Worklist.empty()) {
5230 const Use *U = Worklist.pop_back_val();
5231 if (!Visited.insert(U).second)
5232 continue;
5233 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << "\n");
5234 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser()))
5235 if (LivenessAA && LivenessAA->isAssumedDead(UserI)) {
5236 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06005237 << *LivenessAA << "\n");
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005238 AnyDead = true;
5239 continue;
5240 }
5241
5242 bool Follow = false;
5243 if (!Pred(*U, Follow))
5244 return false;
5245 if (!Follow)
5246 continue;
5247 for (const Use &UU : U->getUser()->uses())
5248 Worklist.push_back(&UU);
5249 }
5250
5251 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005252 recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005253
5254 return true;
5255}
5256
Johannes Doerfert661db042019-10-07 23:14:58 +00005257bool Attributor::checkForAllCallSites(
5258 const function_ref<bool(AbstractCallSite)> &Pred,
5259 const AbstractAttribute &QueryingAA, bool RequireAllCallSites) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005260 // We can try to determine information from
5261 // the call sites. However, this is only possible all call sites are known,
5262 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005263 const IRPosition &IRP = QueryingAA.getIRPosition();
5264 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00005265 if (!AssociatedFunction) {
5266 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
5267 << "\n");
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005268 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00005269 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005270
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005271 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
5272 &QueryingAA);
5273}
5274
5275bool Attributor::checkForAllCallSites(
5276 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
5277 bool RequireAllCallSites, const AbstractAttribute *QueryingAA) {
5278 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005279 LLVM_DEBUG(
5280 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005281 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00005282 << " has no internal linkage, hence not all call sites are known\n");
5283 return false;
5284 }
5285
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005286 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00005287 AbstractCallSite ACS(&U);
5288 if (!ACS) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005289 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00005290 << " has non call site use " << *U.get() << " in "
5291 << *U.getUser() << "\n");
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05005292 // BlockAddress users are allowed.
5293 if (isa<BlockAddress>(U.getUser()))
5294 continue;
Johannes Doerfertd98f9752019-08-21 21:48:56 +00005295 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00005296 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00005297
Johannes Doerfert661db042019-10-07 23:14:58 +00005298 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005299 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005300
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005301 const auto *LivenessAA =
5302 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005303 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005304
5305 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005306 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00005307 // We actually used liveness information so we have to record a
5308 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00005309 if (QueryingAA)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005310 recordDependence(*LivenessAA, *QueryingAA, DepClassTy::OPTIONAL);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00005311 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00005312 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00005313
Johannes Doerfert661db042019-10-07 23:14:58 +00005314 const Use *EffectiveUse =
5315 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
5316 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00005317 if (!RequireAllCallSites)
5318 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00005319 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005320 << " is an invalid use of " << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00005321 return false;
5322 }
5323
Johannes Doerfert661db042019-10-07 23:14:58 +00005324 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00005325 continue;
5326
Johannes Doerfert5304b722019-08-14 22:04:28 +00005327 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00005328 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00005329 return false;
5330 }
5331
5332 return true;
5333}
5334
Johannes Doerfert14a04932019-08-07 22:27:24 +00005335bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00005336 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00005337 &Pred,
5338 const AbstractAttribute &QueryingAA) {
5339
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005340 const IRPosition &IRP = QueryingAA.getIRPosition();
5341 // Since we need to provide return instructions we have to have an exact
5342 // definition.
5343 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005344 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00005345 return false;
5346
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005347 // If this is a call site query we use the call site specific return values
5348 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005349 // TODO: use the function scope once we have call site AAReturnedValues.
5350 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005351 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005352 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005353 return false;
5354
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005355 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00005356}
5357
5358bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005359 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00005360 const AbstractAttribute &QueryingAA) {
5361
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005362 const IRPosition &IRP = QueryingAA.getIRPosition();
5363 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005364 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00005365 return false;
5366
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005367 // TODO: use the function scope once we have call site AAReturnedValues.
5368 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005369 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005370 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005371 return false;
5372
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005373 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00005374 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00005375 return Pred(RV);
5376 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00005377}
5378
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005379static bool
5380checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
5381 const function_ref<bool(Instruction &)> &Pred,
5382 const AAIsDead *LivenessAA, bool &AnyDead,
5383 const ArrayRef<unsigned> &Opcodes) {
5384 for (unsigned Opcode : Opcodes) {
5385 for (Instruction *I : OpcodeInstMap[Opcode]) {
5386 // Skip dead instructions.
5387 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
5388 AnyDead = true;
5389 continue;
5390 }
5391
5392 if (!Pred(*I))
5393 return false;
5394 }
5395 }
5396 return true;
5397}
5398
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005399bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005400 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00005401 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005402
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005403 const IRPosition &IRP = QueryingAA.getIRPosition();
5404 // Since we need to provide instructions we have to have an exact definition.
5405 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00005406 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005407 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005408
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005409 // TODO: use the function scope once we have call site AAReturnedValues.
5410 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005411 const auto &LivenessAA =
5412 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
5413 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005414
5415 auto &OpcodeInstMap =
5416 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005417 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
5418 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00005419 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005420
Johannes Doerfert19b00432019-08-26 17:48:05 +00005421 // If we actually used liveness information so we have to record a dependence.
5422 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005423 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005424
Johannes Doerfertd0f64002019-08-06 00:32:43 +00005425 return true;
5426}
5427
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005428bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005429 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00005430 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005431
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005432 const Function *AssociatedFunction =
5433 QueryingAA.getIRPosition().getAssociatedFunction();
5434 if (!AssociatedFunction)
5435 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005436
Johannes Doerfert07a5c122019-08-28 14:09:14 +00005437 // TODO: use the function scope once we have call site AAReturnedValues.
5438 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
5439 const auto &LivenessAA =
5440 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005441 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00005442
5443 for (Instruction *I :
5444 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005445 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00005446 if (LivenessAA.isAssumedDead(I)) {
5447 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005448 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00005449 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005450
5451 if (!Pred(*I))
5452 return false;
5453 }
5454
Johannes Doerfert19b00432019-08-26 17:48:05 +00005455 // If we actually used liveness information so we have to record a dependence.
5456 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05005457 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00005458
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00005459 return true;
5460}
5461
Johannes Doerfert2f622062019-09-04 16:35:20 +00005462ChangeStatus Attributor::run(Module &M) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00005463 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
5464 << AllAbstractAttributes.size()
5465 << " abstract attributes.\n");
5466
Stefan Stipanovic53605892019-06-27 11:27:54 +00005467 // Now that all abstract attributes are collected and initialized we start
5468 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00005469
5470 unsigned IterationCounter = 1;
5471
5472 SmallVector<AbstractAttribute *, 64> ChangedAAs;
Johannes Doerfert680f6382019-11-02 02:48:05 -05005473 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005474 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
5475
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005476 bool RecomputeDependences = false;
5477
Johannes Doerfertaade7822019-06-05 03:02:24 +00005478 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005479 // Remember the size to determine new attributes.
5480 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005481 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
5482 << ", Worklist size: " << Worklist.size() << "\n");
5483
Johannes Doerfert680f6382019-11-02 02:48:05 -05005484 // For invalid AAs we can fix dependent AAs that have a required dependence,
5485 // thereby folding long dependence chains in a single step without the need
5486 // to run updates.
5487 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
5488 AbstractAttribute *InvalidAA = InvalidAAs[u];
5489 auto &QuerriedAAs = QueryMap[InvalidAA];
5490 LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
5491 << QuerriedAAs.RequiredAAs.size() << "/"
5492 << QuerriedAAs.OptionalAAs.size()
5493 << " required/optional dependences\n");
5494 for (AbstractAttribute *DepOnInvalidAA : QuerriedAAs.RequiredAAs) {
5495 AbstractState &DOIAAState = DepOnInvalidAA->getState();
5496 DOIAAState.indicatePessimisticFixpoint();
5497 ++NumAttributesFixedDueToRequiredDependences;
5498 assert(DOIAAState.isAtFixpoint() && "Expected fixpoint state!");
5499 if (!DOIAAState.isValidState())
5500 InvalidAAs.insert(DepOnInvalidAA);
5501 }
5502 if (!RecomputeDependences)
5503 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
5504 QuerriedAAs.OptionalAAs.end());
5505 }
5506
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005507 // If dependences (=QueryMap) are recomputed we have to look at all abstract
5508 // attributes again, regardless of what changed in the last iteration.
5509 if (RecomputeDependences) {
5510 LLVM_DEBUG(
5511 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
5512 QueryMap.clear();
5513 ChangedAAs.clear();
5514 Worklist.insert(AllAbstractAttributes.begin(),
5515 AllAbstractAttributes.end());
5516 }
5517
Johannes Doerfertaade7822019-06-05 03:02:24 +00005518 // Add all abstract attributes that are potentially dependent on one that
5519 // changed to the work list.
5520 for (AbstractAttribute *ChangedAA : ChangedAAs) {
5521 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05005522 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
5523 QuerriedAAs.OptionalAAs.end());
5524 Worklist.insert(QuerriedAAs.RequiredAAs.begin(),
5525 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00005526 }
5527
Johannes Doerfertb504eb82019-08-26 18:55:47 +00005528 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
5529 << ", Worklist+Dependent size: " << Worklist.size()
5530 << "\n");
5531
Johannes Doerfert680f6382019-11-02 02:48:05 -05005532 // Reset the changed and invalid set.
Johannes Doerfertaade7822019-06-05 03:02:24 +00005533 ChangedAAs.clear();
Johannes Doerfert680f6382019-11-02 02:48:05 -05005534 InvalidAAs.clear();
Johannes Doerfertaade7822019-06-05 03:02:24 +00005535
5536 // Update all abstract attribute in the work list and record the ones that
5537 // changed.
5538 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005539 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
5540 QueriedNonFixAA = false;
5541 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005542 ChangedAAs.push_back(AA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05005543 if (!AA->getState().isValidState())
5544 InvalidAAs.insert(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05005545 } else if (!QueriedNonFixAA) {
5546 // If the attribute did not query any non-fix information, the state
5547 // will not change and we can indicate that right away.
5548 AA->getState().indicateOptimisticFixpoint();
5549 }
5550 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00005551
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005552 // Check if we recompute the dependences in the next iteration.
5553 RecomputeDependences = (DepRecomputeInterval > 0 &&
5554 IterationCounter % DepRecomputeInterval == 0);
5555
Johannes Doerfert9543f142019-08-23 15:24:57 +00005556 // Add attributes to the changed set if they have been created in the last
5557 // iteration.
5558 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
5559 AllAbstractAttributes.end());
5560
Johannes Doerfertaade7822019-06-05 03:02:24 +00005561 // Reset the work list and repopulate with the changed abstract attributes.
5562 // Note that dependent ones are added above.
5563 Worklist.clear();
5564 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
5565
Johannes Doerfertbf112132019-08-29 01:29:44 +00005566 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
5567 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00005568
Johannes Doerfertaade7822019-06-05 03:02:24 +00005569 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
5570 << IterationCounter << "/" << MaxFixpointIterations
5571 << " iterations\n");
5572
Johannes Doerfertbf112132019-08-29 01:29:44 +00005573 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00005574
Johannes Doerfertaade7822019-06-05 03:02:24 +00005575 // Reset abstract arguments not settled in a sound fixpoint by now. This
5576 // happens when we stopped the fixpoint iteration early. Note that only the
5577 // ones marked as "changed" *and* the ones transitively depending on them
5578 // need to be reverted to a pessimistic state. Others might not be in a
5579 // fixpoint state but we can use the optimistic results for them anyway.
5580 SmallPtrSet<AbstractAttribute *, 32> Visited;
5581 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
5582 AbstractAttribute *ChangedAA = ChangedAAs[u];
5583 if (!Visited.insert(ChangedAA).second)
5584 continue;
5585
5586 AbstractState &State = ChangedAA->getState();
5587 if (!State.isAtFixpoint()) {
5588 State.indicatePessimisticFixpoint();
5589
5590 NumAttributesTimedOut++;
5591 }
5592
5593 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05005594 ChangedAAs.append(QuerriedAAs.OptionalAAs.begin(),
5595 QuerriedAAs.OptionalAAs.end());
5596 ChangedAAs.append(QuerriedAAs.RequiredAAs.begin(),
5597 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00005598 }
5599
5600 LLVM_DEBUG({
5601 if (!Visited.empty())
5602 dbgs() << "\n[Attributor] Finalized " << Visited.size()
5603 << " abstract attributes.\n";
5604 });
5605
5606 unsigned NumManifested = 0;
5607 unsigned NumAtFixpoint = 0;
5608 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
5609 for (AbstractAttribute *AA : AllAbstractAttributes) {
5610 AbstractState &State = AA->getState();
5611
5612 // If there is not already a fixpoint reached, we can now take the
5613 // optimistic state. This is correct because we enforced a pessimistic one
5614 // on abstract attributes that were transitively dependent on a changed one
5615 // already above.
5616 if (!State.isAtFixpoint())
5617 State.indicateOptimisticFixpoint();
5618
5619 // If the state is invalid, we do not try to manifest it.
5620 if (!State.isValidState())
5621 continue;
5622
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00005623 // Skip dead code.
5624 if (isAssumedDead(*AA, nullptr))
5625 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00005626 // Manifest the state and record if we changed the IR.
5627 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00005628 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
5629 AA->trackStatistics();
5630
Johannes Doerfertaade7822019-06-05 03:02:24 +00005631 ManifestChange = ManifestChange | LocalChange;
5632
5633 NumAtFixpoint++;
5634 NumManifested += (LocalChange == ChangeStatus::CHANGED);
5635 }
5636
5637 (void)NumManifested;
5638 (void)NumAtFixpoint;
5639 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
5640 << " arguments while " << NumAtFixpoint
5641 << " were in a valid fixpoint state\n");
5642
Johannes Doerfertaade7822019-06-05 03:02:24 +00005643 NumAttributesManifested += NumManifested;
5644 NumAttributesValidFixpoint += NumAtFixpoint;
5645
Fangrui Songf1826172019-08-20 07:21:43 +00005646 (void)NumFinalAAs;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00005647 assert(
5648 NumFinalAAs == AllAbstractAttributes.size() &&
5649 "Expected the final number of abstract attributes to remain unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00005650
5651 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00005652 {
5653 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
5654 << ToBeDeletedFunctions.size() << " functions and "
5655 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005656 << ToBeDeletedInsts.size() << " instructions and "
5657 << ToBeChangedUses.size() << " uses\n");
5658
5659 SmallVector<Instruction *, 32> DeadInsts;
5660 SmallVector<Instruction *, 32> TerminatorsToFold;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005661
5662 for (auto &It : ToBeChangedUses) {
5663 Use *U = It.first;
5664 Value *NewV = It.second;
5665 Value *OldV = U->get();
5666 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
5667 << " instead of " << *OldV << "\n");
5668 U->set(NewV);
5669 if (Instruction *I = dyn_cast<Instruction>(OldV))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01005670 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
5671 isInstructionTriviallyDead(I)) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005672 DeadInsts.push_back(I);
5673 }
5674 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
5675 Instruction *UserI = cast<Instruction>(U->getUser());
5676 if (isa<UndefValue>(NewV)) {
Hideto Uenocb5eb132019-12-27 02:39:37 +09005677 ToBeChangedToUnreachableInsts.insert(UserI);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005678 } else {
5679 TerminatorsToFold.push_back(UserI);
5680 }
5681 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00005682 }
Hideto Uenocb5eb132019-12-27 02:39:37 +09005683 for (Instruction *I : ToBeChangedToUnreachableInsts)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005684 changeToUnreachable(I, /* UseLLVMTrap */ false);
5685 for (Instruction *I : TerminatorsToFold)
5686 ConstantFoldTerminator(I->getParent());
5687
5688 for (Instruction *I : ToBeDeletedInsts) {
5689 I->replaceAllUsesWith(UndefValue::get(I->getType()));
5690 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
5691 DeadInsts.push_back(I);
5692 else
5693 I->eraseFromParent();
5694 }
5695
5696 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005697
Johannes Doerfert2f622062019-09-04 16:35:20 +00005698 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
5699 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
5700 ToBeDeletedBBs.reserve(NumDeadBlocks);
5701 ToBeDeletedBBs.append(ToBeDeletedBlocks.begin(), ToBeDeletedBlocks.end());
Johannes Doerfert5e442a52019-10-30 17:34:59 -05005702 // Actually we do not delete the blocks but squash them into a single
5703 // unreachable but untangling branches that jump here is something we need
5704 // to do in a more generic way.
5705 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
5706 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
5707 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00005708 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00005709
Johannes Doerfert2f622062019-09-04 16:35:20 +00005710 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
5711 for (Function *Fn : ToBeDeletedFunctions) {
5712 Fn->replaceAllUsesWith(UndefValue::get(Fn->getType()));
5713 Fn->eraseFromParent();
5714 STATS_TRACK(AAIsDead, Function);
5715 }
5716
5717 // Identify dead internal functions and delete them. This happens outside
5718 // the other fixpoint analysis as we might treat potentially dead functions
5719 // as live to lower the number of iterations. If they happen to be dead, the
5720 // below fixpoint loop will identify and eliminate them.
5721 SmallVector<Function *, 8> InternalFns;
5722 for (Function &F : M)
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00005723 if (F.hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00005724 InternalFns.push_back(&F);
5725
5726 bool FoundDeadFn = true;
5727 while (FoundDeadFn) {
5728 FoundDeadFn = false;
5729 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
5730 Function *F = InternalFns[u];
5731 if (!F)
5732 continue;
5733
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005734 if (!checkForAllCallSites([](AbstractCallSite ACS) { return false; },
5735 *F, true, nullptr))
Johannes Doerfert2f622062019-09-04 16:35:20 +00005736 continue;
5737
5738 STATS_TRACK(AAIsDead, Function);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05005739 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05005740 F->deleteBody();
Johannes Doerfert2f622062019-09-04 16:35:20 +00005741 F->replaceAllUsesWith(UndefValue::get(F->getType()));
5742 F->eraseFromParent();
5743 InternalFns[u] = nullptr;
5744 FoundDeadFn = true;
5745 }
5746 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00005747 }
5748
Johannes Doerfert75133632019-10-10 01:39:16 -05005749 // Rewrite the functions as requested during manifest.
5750 ManifestChange = ManifestChange | rewriteFunctionSignatures();
5751
Johannes Doerfertbf112132019-08-29 01:29:44 +00005752 if (VerifyMaxFixpointIterations &&
5753 IterationCounter != MaxFixpointIterations) {
5754 errs() << "\n[Attributor] Fixpoint iteration done after: "
5755 << IterationCounter << "/" << MaxFixpointIterations
5756 << " iterations\n";
5757 llvm_unreachable("The fixpoint was not reached with exactly the number of "
5758 "specified iterations!");
5759 }
5760
Johannes Doerfertaade7822019-06-05 03:02:24 +00005761 return ManifestChange;
5762}
5763
Johannes Doerfert75133632019-10-10 01:39:16 -05005764bool Attributor::registerFunctionSignatureRewrite(
5765 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
5766 ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,
5767 ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {
5768
5769 auto CallSiteCanBeChanged = [](AbstractCallSite ACS) {
5770 // Forbid must-tail calls for now.
5771 return !ACS.isCallbackCall() && !ACS.getCallSite().isMustTailCall();
5772 };
5773
5774 Function *Fn = Arg.getParent();
5775 // Avoid var-arg functions for now.
5776 if (Fn->isVarArg()) {
5777 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
5778 return false;
5779 }
5780
5781 // Avoid functions with complicated argument passing semantics.
5782 AttributeList FnAttributeList = Fn->getAttributes();
5783 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
5784 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
5785 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca)) {
5786 LLVM_DEBUG(
5787 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
5788 return false;
5789 }
5790
5791 // Avoid callbacks for now.
5792 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr)) {
5793 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
5794 return false;
5795 }
5796
5797 auto InstPred = [](Instruction &I) {
5798 if (auto *CI = dyn_cast<CallInst>(&I))
5799 return !CI->isMustTailCall();
5800 return true;
5801 };
5802
5803 // Forbid must-tail calls for now.
5804 // TODO:
5805 bool AnyDead;
5806 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
5807 if (!checkForAllInstructionsImpl(OpcodeInstMap, InstPred, nullptr, AnyDead,
5808 {Instruction::Call})) {
5809 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
5810 return false;
5811 }
5812
5813 SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = ArgumentReplacementMap[Fn];
5814 if (ARIs.size() == 0)
5815 ARIs.resize(Fn->arg_size());
5816
5817 // If we have a replacement already with less than or equal new arguments,
5818 // ignore this request.
5819 ArgumentReplacementInfo *&ARI = ARIs[Arg.getArgNo()];
5820 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
5821 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
5822 return false;
5823 }
5824
5825 // If we have a replacement already but we like the new one better, delete
5826 // the old.
5827 if (ARI)
5828 delete ARI;
5829
5830 // Remember the replacement.
5831 ARI = new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
5832 std::move(CalleeRepairCB),
5833 std::move(ACSRepairCB));
5834
5835 return true;
5836}
5837
5838ChangeStatus Attributor::rewriteFunctionSignatures() {
5839 ChangeStatus Changed = ChangeStatus::UNCHANGED;
5840
5841 for (auto &It : ArgumentReplacementMap) {
5842 Function *OldFn = It.getFirst();
5843
5844 // Deleted functions do not require rewrites.
5845 if (ToBeDeletedFunctions.count(OldFn))
5846 continue;
5847
5848 const SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = It.getSecond();
5849 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
5850
5851 SmallVector<Type *, 16> NewArgumentTypes;
5852 SmallVector<AttributeSet, 16> NewArgumentAttributes;
5853
5854 // Collect replacement argument types and copy over existing attributes.
5855 AttributeList OldFnAttributeList = OldFn->getAttributes();
5856 for (Argument &Arg : OldFn->args()) {
5857 if (ArgumentReplacementInfo *ARI = ARIs[Arg.getArgNo()]) {
5858 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
5859 ARI->ReplacementTypes.end());
5860 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
5861 AttributeSet());
5862 } else {
5863 NewArgumentTypes.push_back(Arg.getType());
5864 NewArgumentAttributes.push_back(
5865 OldFnAttributeList.getParamAttributes(Arg.getArgNo()));
5866 }
5867 }
5868
5869 FunctionType *OldFnTy = OldFn->getFunctionType();
5870 Type *RetTy = OldFnTy->getReturnType();
5871
5872 // Construct the new function type using the new arguments types.
5873 FunctionType *NewFnTy =
5874 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
5875
5876 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
5877 << "' from " << *OldFn->getFunctionType() << " to "
5878 << *NewFnTy << "\n");
5879
5880 // Create the new function body and insert it into the module.
5881 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
5882 OldFn->getAddressSpace(), "");
5883 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
5884 NewFn->takeName(OldFn);
5885 NewFn->copyAttributesFrom(OldFn);
5886
5887 // Patch the pointer to LLVM function in debug info descriptor.
5888 NewFn->setSubprogram(OldFn->getSubprogram());
5889 OldFn->setSubprogram(nullptr);
5890
5891 // Recompute the parameter attributes list based on the new arguments for
5892 // the function.
5893 LLVMContext &Ctx = OldFn->getContext();
5894 NewFn->setAttributes(AttributeList::get(
5895 Ctx, OldFnAttributeList.getFnAttributes(),
5896 OldFnAttributeList.getRetAttributes(), NewArgumentAttributes));
5897
5898 // Since we have now created the new function, splice the body of the old
5899 // function right into the new function, leaving the old rotting hulk of the
5900 // function empty.
5901 NewFn->getBasicBlockList().splice(NewFn->begin(),
5902 OldFn->getBasicBlockList());
5903
5904 // Set of all "call-like" instructions that invoke the old function.
5905 SmallPtrSet<Instruction *, 8> OldCallSites;
5906
5907 // Callback to create a new "call-like" instruction for a given one.
5908 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
5909 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
5910 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
5911
5912 // Collect the new argument operands for the replacement call site.
5913 SmallVector<Value *, 16> NewArgOperands;
5914 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
5915 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
5916 unsigned NewFirstArgNum = NewArgOperands.size();
Ilya Biryukov4f82af82019-12-31 10:21:52 +01005917 (void)NewFirstArgNum; // only used inside assert.
Johannes Doerfert75133632019-10-10 01:39:16 -05005918 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
5919 if (ARI->ACSRepairCB)
5920 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
5921 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
5922 NewArgOperands.size() &&
5923 "ACS repair callback did not provide as many operand as new "
5924 "types were registered!");
5925 // TODO: Exose the attribute set to the ACS repair callback
5926 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
5927 AttributeSet());
5928 } else {
5929 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
5930 NewArgOperandAttributes.push_back(
5931 OldCallAttributeList.getParamAttributes(OldArgNum));
5932 }
5933 }
5934
5935 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
5936 "Mismatch # argument operands vs. # argument operand attributes!");
5937 assert(NewArgOperands.size() == NewFn->arg_size() &&
5938 "Mismatch # argument operands vs. # function arguments!");
5939
5940 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
5941 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
5942
5943 // Create a new call or invoke instruction to replace the old one.
5944 CallBase *NewCB;
5945 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
5946 NewCB =
5947 InvokeInst::Create(NewFn, II->getNormalDest(), II->getUnwindDest(),
5948 NewArgOperands, OperandBundleDefs, "", OldCB);
5949 } else {
5950 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
5951 "", OldCB);
5952 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
5953 NewCB = NewCI;
5954 }
5955
5956 // Copy over various properties and the new attributes.
5957 OldCB->replaceAllUsesWith(NewCB);
5958 uint64_t W;
5959 if (OldCB->extractProfTotalWeight(W))
5960 NewCB->setProfWeight(W);
5961 NewCB->setCallingConv(OldCB->getCallingConv());
5962 NewCB->setDebugLoc(OldCB->getDebugLoc());
5963 NewCB->takeName(OldCB);
5964 NewCB->setAttributes(AttributeList::get(
5965 Ctx, OldCallAttributeList.getFnAttributes(),
5966 OldCallAttributeList.getRetAttributes(), NewArgOperandAttributes));
5967
5968 bool Inserted = OldCallSites.insert(OldCB).second;
5969 assert(Inserted && "Call site was old twice!");
5970 (void)Inserted;
5971
5972 return true;
5973 };
5974
5975 // Use the CallSiteReplacementCreator to create replacement call sites.
5976 bool Success =
5977 checkForAllCallSites(CallSiteReplacementCreator, *OldFn, true, nullptr);
Ilya Biryukov4f82af82019-12-31 10:21:52 +01005978 (void)Success;
Johannes Doerfert75133632019-10-10 01:39:16 -05005979 assert(Success && "Assumed call site replacement to succeed!");
5980
5981 // Rewire the arguments.
5982 auto OldFnArgIt = OldFn->arg_begin();
5983 auto NewFnArgIt = NewFn->arg_begin();
5984 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
5985 ++OldArgNum, ++OldFnArgIt) {
5986 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
5987 if (ARI->CalleeRepairCB)
5988 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
5989 NewFnArgIt += ARI->ReplacementTypes.size();
5990 } else {
5991 NewFnArgIt->takeName(&*OldFnArgIt);
5992 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
5993 ++NewFnArgIt;
5994 }
5995 }
5996
5997 // Eliminate the instructions *after* we visited all of them.
5998 for (Instruction *OldCallSite : OldCallSites)
5999 OldCallSite->eraseFromParent();
6000
6001 assert(OldFn->getNumUses() == 0 && "Unexpected leftover uses!");
6002 OldFn->eraseFromParent();
6003 Changed = ChangeStatus::CHANGED;
6004 }
6005
6006 return Changed;
6007}
6008
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006009void Attributor::initializeInformationCache(Function &F) {
6010
6011 // Walk all instructions to find interesting instructions that might be
6012 // queried by abstract attributes during their initialization or update.
6013 // This has to happen before we create attributes.
6014 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
6015 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
6016
6017 for (Instruction &I : instructions(&F)) {
6018 bool IsInterestingOpcode = false;
6019
6020 // To allow easy access to all instructions in a function with a given
6021 // opcode we store them in the InfoCache. As not all opcodes are interesting
6022 // to concrete attributes we only cache the ones that are as identified in
6023 // the following switch.
6024 // Note: There are no concrete attributes now so this is initially empty.
6025 switch (I.getOpcode()) {
6026 default:
6027 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
6028 "New call site/base instruction type needs to be known int the "
6029 "Attributor.");
6030 break;
6031 case Instruction::Load:
6032 // The alignment of a pointer is interesting for loads.
6033 case Instruction::Store:
6034 // The alignment of a pointer is interesting for stores.
6035 case Instruction::Call:
6036 case Instruction::CallBr:
6037 case Instruction::Invoke:
6038 case Instruction::CleanupRet:
6039 case Instruction::CatchSwitch:
Johannes Doerfert5732f562019-12-24 19:25:08 -06006040 case Instruction::AtomicRMW:
6041 case Instruction::AtomicCmpXchg:
Hideto Uenoef4febd2019-12-29 17:34:08 +09006042 case Instruction::Br:
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006043 case Instruction::Resume:
6044 case Instruction::Ret:
6045 IsInterestingOpcode = true;
6046 }
6047 if (IsInterestingOpcode)
6048 InstOpcodeMap[I.getOpcode()].push_back(&I);
6049 if (I.mayReadOrWriteMemory())
6050 ReadOrWriteInsts.push_back(&I);
6051 }
6052}
6053
Johannes Doerfert12173e62019-10-13 20:25:25 -05006054void Attributor::recordDependence(const AbstractAttribute &FromAA,
Johannes Doerfert680f6382019-11-02 02:48:05 -05006055 const AbstractAttribute &ToAA,
6056 DepClassTy DepClass) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006057 if (FromAA.getState().isAtFixpoint())
6058 return;
6059
Johannes Doerfert680f6382019-11-02 02:48:05 -05006060 if (DepClass == DepClassTy::REQUIRED)
6061 QueryMap[&FromAA].RequiredAAs.insert(
6062 const_cast<AbstractAttribute *>(&ToAA));
6063 else
6064 QueryMap[&FromAA].OptionalAAs.insert(
6065 const_cast<AbstractAttribute *>(&ToAA));
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006066 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05006067}
6068
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006069void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00006070 if (!VisitedFunctions.insert(&F).second)
6071 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006072 if (F.isDeclaration())
6073 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006074
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006075 IRPosition FPos = IRPosition::function(F);
6076
Johannes Doerfert305b9612019-08-04 18:40:01 +00006077 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00006078 // We need dead instruction detection because we do not want to deal with
6079 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006080 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00006081
6082 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006083 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00006084
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006085 // Every function might contain instructions that cause "undefined behavior".
6086 getOrCreateAAFor<AAUndefinedBehavior>(FPos);
6087
Stefan Stipanovic53605892019-06-27 11:27:54 +00006088 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006089 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00006090
Stefan Stipanovic06263672019-07-11 21:37:40 +00006091 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006092 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00006093
Hideto Ueno65bbaf92019-07-12 17:38:51 +00006094 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006095 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00006096
Johannes Doerferte83f3032019-08-05 23:22:05 +00006097 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006098 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00006099
Hideto Ueno63f60662019-09-21 15:13:19 +00006100 // Every function might be "no-recurse".
6101 getOrCreateAAFor<AANoRecurse>(FPos);
6102
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006103 // Every function might be "readnone/readonly/writeonly/...".
6104 getOrCreateAAFor<AAMemoryBehavior>(FPos);
6105
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006106 // Every function might be applicable for Heap-To-Stack conversion.
6107 if (EnableHeapToStack)
6108 getOrCreateAAFor<AAHeapToStack>(FPos);
6109
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00006110 // Return attributes are only appropriate if the return type is non void.
6111 Type *ReturnType = F.getReturnType();
6112 if (!ReturnType->isVoidTy()) {
6113 // Argument attribute "returned" --- Create only one per function even
6114 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006115 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00006116
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006117 IRPosition RetPos = IRPosition::returned(F);
6118
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006119 // Every returned value might be dead.
6120 getOrCreateAAFor<AAIsDead>(RetPos);
6121
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006122 // Every function might be simplified.
6123 getOrCreateAAFor<AAValueSimplify>(RetPos);
6124
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006125 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006126
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006127 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006128 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006129
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006130 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006131 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006132
6133 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006134 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006135
6136 // Every function with pointer return type might be marked
6137 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006138 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00006139 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00006140 }
6141
Hideto Ueno54869ec2019-07-15 06:49:04 +00006142 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006143 IRPosition ArgPos = IRPosition::argument(Arg);
6144
6145 // Every argument might be simplified.
6146 getOrCreateAAFor<AAValueSimplify>(ArgPos);
6147
Hideto Ueno19c07af2019-07-23 08:16:17 +00006148 if (Arg.getType()->isPointerTy()) {
6149 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006150 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006151
Hideto Uenocbab3342019-08-29 05:52:00 +00006152 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006153 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00006154
Hideto Ueno19c07af2019-07-23 08:16:17 +00006155 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006156 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006157
6158 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006159 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006160
6161 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006162 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006163
6164 // Every argument with pointer type might be marked
6165 // "readnone/readonly/writeonly/..."
6166 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006167
6168 // Every argument with pointer type might be marked nofree.
6169 getOrCreateAAFor<AANoFree>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006170 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00006171 }
6172
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006173 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006174 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006175 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006176 // Skip declerations except if annotations on their call sites were
6177 // explicitly requested.
Johannes Doerfert139c9ef2019-12-13 23:41:02 -06006178 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
6179 !Callee->hasMetadata(LLVMContext::MD_callback))
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05006180 return true;
6181
6182 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006183 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
6184
6185 // Call site return values might be dead.
6186 getOrCreateAAFor<AAIsDead>(CSRetPos);
6187 }
6188
Johannes Doerfert28880192019-12-31 00:57:00 -06006189 for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006190
6191 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
6192
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006193 // Every call site argument might be dead.
6194 getOrCreateAAFor<AAIsDead>(CSArgPos);
6195
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006196 // Call site argument might be simplified.
6197 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
6198
Hideto Ueno54869ec2019-07-15 06:49:04 +00006199 if (!CS.getArgument(i)->getType()->isPointerTy())
6200 continue;
6201
6202 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006203 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00006204
Hideto Uenocbab3342019-08-29 05:52:00 +00006205 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006206 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00006207
Hideto Ueno19c07af2019-07-23 08:16:17 +00006208 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006209 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00006210
6211 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00006212 getOrCreateAAFor<AAAlign>(CSArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006213
Johannes Doerfert28880192019-12-31 00:57:00 -06006214 // Call site argument attribute
6215 // "readnone/readonly/writeonly/..."
6216 getOrCreateAAFor<AAMemoryBehavior>(CSArgPos);
6217
Hideto Ueno4ecf2552019-12-12 13:42:40 +00006218 // Call site argument attribute "nofree".
6219 getOrCreateAAFor<AANoFree>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00006220 }
6221 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006222 return true;
6223 };
6224
6225 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
6226 bool Success, AnyDead = false;
6227 Success = checkForAllInstructionsImpl(
6228 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
6229 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
6230 (unsigned)Instruction::Call});
6231 (void)Success;
6232 assert(Success && !AnyDead && "Expected the check call to be successful!");
6233
6234 auto LoadStorePred = [&](Instruction &I) -> bool {
6235 if (isa<LoadInst>(I))
6236 getOrCreateAAFor<AAAlign>(
6237 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
6238 else
6239 getOrCreateAAFor<AAAlign>(
6240 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
6241 return true;
6242 };
6243 Success = checkForAllInstructionsImpl(
6244 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
6245 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
6246 (void)Success;
6247 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00006248}
6249
6250/// Helpers to ease debugging through output streams and print calls.
6251///
6252///{
6253raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
6254 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
6255}
6256
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006257raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006258 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006259 case IRPosition::IRP_INVALID:
6260 return OS << "inv";
6261 case IRPosition::IRP_FLOAT:
6262 return OS << "flt";
6263 case IRPosition::IRP_RETURNED:
6264 return OS << "fn_ret";
6265 case IRPosition::IRP_CALL_SITE_RETURNED:
6266 return OS << "cs_ret";
6267 case IRPosition::IRP_FUNCTION:
6268 return OS << "fn";
6269 case IRPosition::IRP_CALL_SITE:
6270 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006271 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00006272 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006273 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00006274 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00006275 }
6276 llvm_unreachable("Unknown attribute position!");
6277}
6278
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006279raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006280 const Value &AV = Pos.getAssociatedValue();
6281 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006282 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
6283}
6284
Johannes Doerfert1a746452019-10-20 22:28:49 -05006285template <typename base_ty, base_ty BestState, base_ty WorstState>
Johannes Doerfert5732f562019-12-24 19:25:08 -06006286raw_ostream &llvm::
6287operator<<(raw_ostream &OS,
6288 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00006289 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
6290 << static_cast<const AbstractState &>(S);
6291}
6292
Johannes Doerfertaade7822019-06-05 03:02:24 +00006293raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
6294 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
6295}
6296
6297raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
6298 AA.print(OS);
6299 return OS;
6300}
6301
6302void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00006303 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
6304 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00006305}
6306///}
6307
6308/// ----------------------------------------------------------------------------
6309/// Pass (Manager) Boilerplate
6310/// ----------------------------------------------------------------------------
6311
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006312static bool runAttributorOnModule(Module &M, AnalysisGetter &AG) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006313 if (DisableAttributor)
6314 return false;
6315
6316 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
6317 << " functions.\n");
6318
6319 // Create an Attributor and initially empty information cache that is filled
6320 // while we identify default attribute opportunities.
Hideto Ueno63f60662019-09-21 15:13:19 +00006321 InformationCache InfoCache(M, AG);
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006322 Attributor A(InfoCache, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006323
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006324 for (Function &F : M)
6325 A.initializeInformationCache(F);
6326
Johannes Doerfertaade7822019-06-05 03:02:24 +00006327 for (Function &F : M) {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006328 if (F.hasExactDefinition())
6329 NumFnWithExactDefinition++;
6330 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00006331 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006332
Johannes Doerfert2f622062019-09-04 16:35:20 +00006333 // We look at internal functions only on-demand but if any use is not a
6334 // direct call, we have to do it eagerly.
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00006335 if (F.hasLocalLinkage()) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00006336 if (llvm::all_of(F.uses(), [](const Use &U) {
6337 return ImmutableCallSite(U.getUser()) &&
6338 ImmutableCallSite(U.getUser()).isCallee(&U);
6339 }))
6340 continue;
6341 }
6342
Johannes Doerfertaade7822019-06-05 03:02:24 +00006343 // Populate the Attributor with abstract attribute opportunities in the
6344 // function and the information cache with IR information.
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006345 A.identifyDefaultAbstractAttributes(F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006346 }
6347
Johannes Doerfert2f622062019-09-04 16:35:20 +00006348 return A.run(M) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006349}
6350
6351PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Hideto Ueno63f60662019-09-21 15:13:19 +00006352 AnalysisGetter AG(AM);
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006353 if (runAttributorOnModule(M, AG)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006354 // FIXME: Think about passes we will preserve and add them here.
6355 return PreservedAnalyses::none();
6356 }
6357 return PreservedAnalyses::all();
6358}
6359
6360namespace {
6361
6362struct AttributorLegacyPass : public ModulePass {
6363 static char ID;
6364
6365 AttributorLegacyPass() : ModulePass(ID) {
6366 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
6367 }
6368
6369 bool runOnModule(Module &M) override {
6370 if (skipModule(M))
6371 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006372
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00006373 AnalysisGetter AG;
6374 return runAttributorOnModule(M, AG);
Johannes Doerfertaade7822019-06-05 03:02:24 +00006375 }
6376
6377 void getAnalysisUsage(AnalysisUsage &AU) const override {
6378 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006379 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00006380 }
6381};
6382
6383} // end anonymous namespace
6384
6385Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
6386
6387char AttributorLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006388
6389const char AAReturnedValues::ID = 0;
6390const char AANoUnwind::ID = 0;
6391const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00006392const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006393const char AANonNull::ID = 0;
6394const char AANoRecurse::ID = 0;
6395const char AAWillReturn::ID = 0;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006396const char AAUndefinedBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006397const char AANoAlias::ID = 0;
Pankaj Gode04945c92019-11-22 18:40:47 +05306398const char AAReachability::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006399const char AANoReturn::ID = 0;
6400const char AAIsDead::ID = 0;
6401const char AADereferenceable::ID = 0;
6402const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006403const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006404const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006405const char AAHeapToStack::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006406const char AAMemoryBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00006407
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006408// Macro magic to create the static generator function for attributes that
6409// follow the naming scheme.
6410
6411#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
6412 case IRPosition::PK: \
6413 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
6414
6415#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
6416 case IRPosition::PK: \
6417 AA = new CLASS##SUFFIX(IRP); \
6418 break;
6419
6420#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6421 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6422 CLASS *AA = nullptr; \
6423 switch (IRP.getPositionKind()) { \
6424 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6425 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
6426 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
6427 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6428 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
6429 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
6430 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6431 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6432 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006433 return *AA; \
6434 }
6435
6436#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6437 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6438 CLASS *AA = nullptr; \
6439 switch (IRP.getPositionKind()) { \
6440 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6441 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
6442 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
6443 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6444 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6445 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
6446 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6447 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6448 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006449 return *AA; \
6450 }
6451
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006452#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6453 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6454 CLASS *AA = nullptr; \
6455 switch (IRP.getPositionKind()) { \
6456 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6457 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6458 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6459 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6460 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6461 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
6462 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6463 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6464 } \
6465 return *AA; \
6466 }
6467
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006468#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6469 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6470 CLASS *AA = nullptr; \
6471 switch (IRP.getPositionKind()) { \
6472 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6473 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
6474 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
6475 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6476 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
6477 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
6478 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
6479 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6480 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006481 return *AA; \
6482 }
6483
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006484#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
6485 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
6486 CLASS *AA = nullptr; \
6487 switch (IRP.getPositionKind()) { \
6488 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
6489 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
6490 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
6491 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
6492 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
6493 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
6494 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
6495 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
6496 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006497 return *AA; \
6498 }
6499
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006500CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
6501CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006502CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
6503CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
6504CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006505CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
6506
6507CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
6508CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
6509CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
6510CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00006511CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006512
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006513CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006514CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006515CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006516
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006517CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
Pankaj Gode04945c92019-11-22 18:40:47 +05306518CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06006519CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006520
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006521CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
6522
Johannes Doerfertd4bea882019-10-07 23:28:54 +00006523#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006524#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00006525#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006526#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00006527#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006528#undef SWITCH_PK_CREATE
6529#undef SWITCH_PK_INV
6530
Johannes Doerfertaade7822019-06-05 03:02:24 +00006531INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
6532 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00006533INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00006534INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
6535 "Deduce and propagate attributes", false, false)