blob: 2d82ba35b147d74292c971d3c7f7934ec0a5e2ad [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
Johannes Doerfert368f7ee2019-12-30 16:12:36 -060016#include "llvm/Transforms/IPO/Attributor.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000017
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"
Johannes Doerfertb0c77c32019-11-27 00:30:12 -060023#include "llvm/Analysis/CallGraph.h"
24#include "llvm/Analysis/CallGraphSCCPass.h"
Stefan Stipanovic69ebb022019-07-22 19:36:27 +000025#include "llvm/Analysis/CaptureTracking.h"
Johannes Doerfert924d2132019-08-05 21:34:45 +000026#include "llvm/Analysis/EHPersonalities.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000027#include "llvm/Analysis/GlobalsModRef.h"
Hideto Ueno188f9a32020-01-15 15:25:52 +090028#include "llvm/Analysis/LazyValueInfo.h"
Hideto Ueno19c07af2019-07-23 08:16:17 +000029#include "llvm/Analysis/Loads.h"
Stefan Stipanovic431141c2019-09-15 21:47:41 +000030#include "llvm/Analysis/MemoryBuiltins.h"
Hideto Ueno188f9a32020-01-15 15:25:52 +090031#include "llvm/Analysis/ScalarEvolution.h"
Hideto Ueno54869ec2019-07-15 06:49:04 +000032#include "llvm/Analysis/ValueTracking.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000033#include "llvm/IR/Argument.h"
34#include "llvm/IR/Attributes.h"
Hideto Ueno11d37102019-07-17 15:15:43 +000035#include "llvm/IR/CFG.h"
Johannes Doerfert89c2e732019-10-30 17:20:20 -050036#include "llvm/IR/IRBuilder.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000037#include "llvm/IR/InstIterator.h"
Stefan Stipanovic06263672019-07-11 21:37:40 +000038#include "llvm/IR/IntrinsicInst.h"
Johannes Doerferta4088c72020-01-07 16:01:57 -060039#include "llvm/IR/Verifier.h"
Reid Kleckner05da2fe2019-11-13 13:15:01 -080040#include "llvm/InitializePasses.h"
Johannes Doerfert89c2e732019-10-30 17:20:20 -050041#include "llvm/IR/NoFolder.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000042#include "llvm/Support/CommandLine.h"
43#include "llvm/Support/Debug.h"
44#include "llvm/Support/raw_ostream.h"
Johannes Doerfert89c2e732019-10-30 17:20:20 -050045#include "llvm/Transforms/IPO/ArgumentPromotion.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000046#include "llvm/Transforms/Utils/BasicBlockUtils.h"
47#include "llvm/Transforms/Utils/Local.h"
48
Johannes Doerfertaade7822019-06-05 03:02:24 +000049#include <cassert>
50
51using namespace llvm;
52
53#define DEBUG_TYPE "attributor"
54
55STATISTIC(NumFnWithExactDefinition,
56 "Number of function with exact definitions");
57STATISTIC(NumFnWithoutExactDefinition,
58 "Number of function without exact definitions");
59STATISTIC(NumAttributesTimedOut,
60 "Number of abstract attributes timed out before fixpoint");
61STATISTIC(NumAttributesValidFixpoint,
62 "Number of abstract attributes in a valid fixpoint state");
63STATISTIC(NumAttributesManifested,
64 "Number of abstract attributes manifested in IR");
Johannes Doerfert680f6382019-11-02 02:48:05 -050065STATISTIC(NumAttributesFixedDueToRequiredDependences,
66 "Number of abstract attributes fixed due to required dependences");
Johannes Doerfertaade7822019-06-05 03:02:24 +000067
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000068// Some helper macros to deal with statistics tracking.
69//
70// Usage:
71// For simple IR attribute tracking overload trackStatistics in the abstract
Johannes Doerfert17b578b2019-08-14 21:46:25 +000072// attribute and choose the right STATS_DECLTRACK_********* macro,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000073// e.g.,:
74// void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +000075// STATS_DECLTRACK_ARG_ATTR(returned)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000076// }
77// If there is a single "increment" side one can use the macro
Johannes Doerfert17b578b2019-08-14 21:46:25 +000078// STATS_DECLTRACK with a custom message. If there are multiple increment
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000079// sides, STATS_DECL and STATS_TRACK can also be used separatly.
80//
81#define BUILD_STAT_MSG_IR_ATTR(TYPE, NAME) \
82 ("Number of " #TYPE " marked '" #NAME "'")
83#define BUILD_STAT_NAME(NAME, TYPE) NumIR##TYPE##_##NAME
Johannes Doerferta7a3b3a2019-09-04 19:01:08 +000084#define STATS_DECL_(NAME, MSG) STATISTIC(NAME, MSG);
85#define STATS_DECL(NAME, TYPE, MSG) \
86 STATS_DECL_(BUILD_STAT_NAME(NAME, TYPE), MSG);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +000087#define STATS_TRACK(NAME, TYPE) ++(BUILD_STAT_NAME(NAME, TYPE));
Johannes Doerfert17b578b2019-08-14 21:46:25 +000088#define STATS_DECLTRACK(NAME, TYPE, MSG) \
Johannes Doerfert169af992019-08-20 06:09:56 +000089 { \
90 STATS_DECL(NAME, TYPE, MSG) \
91 STATS_TRACK(NAME, TYPE) \
92 }
Johannes Doerfert17b578b2019-08-14 21:46:25 +000093#define STATS_DECLTRACK_ARG_ATTR(NAME) \
94 STATS_DECLTRACK(NAME, Arguments, BUILD_STAT_MSG_IR_ATTR(arguments, NAME))
95#define STATS_DECLTRACK_CSARG_ATTR(NAME) \
96 STATS_DECLTRACK(NAME, CSArguments, \
97 BUILD_STAT_MSG_IR_ATTR(call site arguments, NAME))
98#define STATS_DECLTRACK_FN_ATTR(NAME) \
99 STATS_DECLTRACK(NAME, Function, BUILD_STAT_MSG_IR_ATTR(functions, NAME))
100#define STATS_DECLTRACK_CS_ATTR(NAME) \
101 STATS_DECLTRACK(NAME, CS, BUILD_STAT_MSG_IR_ATTR(call site, NAME))
102#define STATS_DECLTRACK_FNRET_ATTR(NAME) \
103 STATS_DECLTRACK(NAME, FunctionReturn, \
Johannes Doerfert2db85282019-08-21 20:56:56 +0000104 BUILD_STAT_MSG_IR_ATTR(function returns, NAME))
Johannes Doerfert17b578b2019-08-14 21:46:25 +0000105#define STATS_DECLTRACK_CSRET_ATTR(NAME) \
106 STATS_DECLTRACK(NAME, CSReturn, \
107 BUILD_STAT_MSG_IR_ATTR(call site returns, NAME))
108#define STATS_DECLTRACK_FLOATING_ATTR(NAME) \
109 STATS_DECLTRACK(NAME, Floating, \
110 ("Number of floating values known to be '" #NAME "'"))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000111
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600112// Specialization of the operator<< for abstract attributes subclasses. This
113// disambiguates situations where multiple operators are applicable.
114namespace llvm {
115#define PIPE_OPERATOR(CLASS) \
116 raw_ostream &operator<<(raw_ostream &OS, const CLASS &AA) { \
117 return OS << static_cast<const AbstractAttribute &>(AA); \
118 }
119
120PIPE_OPERATOR(AAIsDead)
121PIPE_OPERATOR(AANoUnwind)
122PIPE_OPERATOR(AANoSync)
123PIPE_OPERATOR(AANoRecurse)
124PIPE_OPERATOR(AAWillReturn)
125PIPE_OPERATOR(AANoReturn)
126PIPE_OPERATOR(AAReturnedValues)
127PIPE_OPERATOR(AANonNull)
128PIPE_OPERATOR(AANoAlias)
129PIPE_OPERATOR(AADereferenceable)
130PIPE_OPERATOR(AAAlign)
131PIPE_OPERATOR(AANoCapture)
132PIPE_OPERATOR(AAValueSimplify)
133PIPE_OPERATOR(AANoFree)
134PIPE_OPERATOR(AAHeapToStack)
135PIPE_OPERATOR(AAReachability)
136PIPE_OPERATOR(AAMemoryBehavior)
Johannes Doerfert282f5d72020-01-26 02:51:57 -0600137PIPE_OPERATOR(AAMemoryLocation)
Hideto Ueno188f9a32020-01-15 15:25:52 +0900138PIPE_OPERATOR(AAValueConstantRange)
Johannes Doerfert89c2e732019-10-30 17:20:20 -0500139PIPE_OPERATOR(AAPrivatizablePtr)
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600140
141#undef PIPE_OPERATOR
142} // namespace llvm
143
Johannes Doerfertaade7822019-06-05 03:02:24 +0000144// TODO: Determine a good default value.
145//
146// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
147// (when run with the first 5 abstract attributes). The results also indicate
148// that we never reach 32 iterations but always find a fixpoint sooner.
149//
150// This will become more evolved once we perform two interleaved fixpoint
151// iterations: bottom-up and top-down.
152static cl::opt<unsigned>
153 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
154 cl::desc("Maximal number of fixpoint iterations."),
155 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000156static cl::opt<bool> VerifyMaxFixpointIterations(
157 "attributor-max-iterations-verify", cl::Hidden,
158 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
159 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000160
161static cl::opt<bool> DisableAttributor(
162 "attributor-disable", cl::Hidden,
163 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000164 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000165
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500166static cl::opt<bool> AnnotateDeclarationCallSites(
167 "attributor-annotate-decl-cs", cl::Hidden,
James Hendersond68904f2020-01-06 10:15:44 +0000168 cl::desc("Annotate call sites of function declarations."), cl::init(false));
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500169
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000170static cl::opt<bool> ManifestInternal(
171 "attributor-manifest-internal", cl::Hidden,
172 cl::desc("Manifest Attributor internal string attributes."),
173 cl::init(false));
174
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000175static cl::opt<unsigned> DepRecInterval(
176 "attributor-dependence-recompute-interval", cl::Hidden,
177 cl::desc("Number of iterations until dependences are recomputed."),
178 cl::init(4));
179
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000180static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
181 cl::init(true), cl::Hidden);
182
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000183static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
184 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000185
Johannes Doerfertaade7822019-06-05 03:02:24 +0000186/// Logic operators for the change status enum class.
187///
188///{
189ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
190 return l == ChangeStatus::CHANGED ? l : r;
191}
192ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
193 return l == ChangeStatus::UNCHANGED ? l : r;
194}
195///}
196
Johannes Doerfertb1b441d2019-10-10 01:19:57 -0500197Argument *IRPosition::getAssociatedArgument() const {
198 if (getPositionKind() == IRP_ARGUMENT)
199 return cast<Argument>(&getAnchorValue());
200
201 // Not an Argument and no argument number means this is not a call site
202 // argument, thus we cannot find a callback argument to return.
203 int ArgNo = getArgNo();
204 if (ArgNo < 0)
205 return nullptr;
206
207 // Use abstract call sites to make the connection between the call site
208 // values and the ones in callbacks. If a callback was found that makes use
209 // of the underlying call site operand, we want the corresponding callback
210 // callee argument and not the direct callee argument.
211 Optional<Argument *> CBCandidateArg;
212 SmallVector<const Use *, 4> CBUses;
213 ImmutableCallSite ICS(&getAnchorValue());
214 AbstractCallSite::getCallbackUses(ICS, CBUses);
215 for (const Use *U : CBUses) {
216 AbstractCallSite ACS(U);
217 assert(ACS && ACS.isCallbackCall());
218 if (!ACS.getCalledFunction())
219 continue;
220
221 for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {
222
223 // Test if the underlying call site operand is argument number u of the
224 // callback callee.
225 if (ACS.getCallArgOperandNo(u) != ArgNo)
226 continue;
227
228 assert(ACS.getCalledFunction()->arg_size() > u &&
229 "ACS mapped into var-args arguments!");
230 if (CBCandidateArg.hasValue()) {
231 CBCandidateArg = nullptr;
232 break;
233 }
234 CBCandidateArg = ACS.getCalledFunction()->getArg(u);
235 }
236 }
237
238 // If we found a unique callback candidate argument, return it.
239 if (CBCandidateArg.hasValue() && CBCandidateArg.getValue())
240 return CBCandidateArg.getValue();
241
242 // If no callbacks were found, or none used the underlying call site operand
243 // exclusively, use the direct callee argument if available.
244 const Function *Callee = ICS.getCalledFunction();
245 if (Callee && Callee->arg_size() > unsigned(ArgNo))
246 return Callee->getArg(ArgNo);
247
248 return nullptr;
249}
250
Johannes Doerferte1eed6c2020-02-16 16:45:28 -0600251static Optional<Constant *> getAssumedConstant(Attributor &A, const Value &V,
252 const AbstractAttribute &AA,
253 bool &UsedAssumedInformation) {
Johannes Doerfert214ed3f2020-01-11 23:35:45 -0600254 const auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
255 AA, IRPosition::value(V), /* TrackDependence */ false);
256 Optional<Value *> SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(A);
257 bool IsKnown = ValueSimplifyAA.isKnown();
258 UsedAssumedInformation |= !IsKnown;
259 if (!SimplifiedV.hasValue()) {
260 A.recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
261 return llvm::None;
262 }
263 if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue())) {
264 A.recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
265 return llvm::None;
266 }
Johannes Doerferte1eed6c2020-02-16 16:45:28 -0600267 Constant *CI = dyn_cast_or_null<Constant>(SimplifiedV.getValue());
268 if (CI && CI->getType() != V.getType()) {
269 // TODO: Check for a save conversion.
270 return nullptr;
271 }
Johannes Doerfert214ed3f2020-01-11 23:35:45 -0600272 if (CI)
273 A.recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
274 return CI;
275}
276
Johannes Doerferte1eed6c2020-02-16 16:45:28 -0600277static Optional<ConstantInt *>
278getAssumedConstantInt(Attributor &A, const Value &V,
279 const AbstractAttribute &AA,
280 bool &UsedAssumedInformation) {
281 Optional<Constant *> C = getAssumedConstant(A, V, AA, UsedAssumedInformation);
282 if (C.hasValue())
283 return dyn_cast_or_null<ConstantInt>(C.getValue());
284 return llvm::None;
285}
286
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -0600287/// Get pointer operand of memory accessing instruction. If \p I is
288/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
289/// is set to false and the instruction is volatile, return nullptr.
290static const Value *getPointerOperand(const Instruction *I,
291 bool AllowVolatile) {
292 if (auto *LI = dyn_cast<LoadInst>(I)) {
293 if (!AllowVolatile && LI->isVolatile())
294 return nullptr;
295 return LI->getPointerOperand();
296 }
297
298 if (auto *SI = dyn_cast<StoreInst>(I)) {
299 if (!AllowVolatile && SI->isVolatile())
300 return nullptr;
301 return SI->getPointerOperand();
302 }
303
304 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
305 if (!AllowVolatile && CXI->isVolatile())
306 return nullptr;
307 return CXI->getPointerOperand();
308 }
309
310 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
311 if (!AllowVolatile && RMWI->isVolatile())
312 return nullptr;
313 return RMWI->getPointerOperand();
314 }
315
316 return nullptr;
317}
318
Johannes Doerfert89c2e732019-10-30 17:20:20 -0500319/// Helper function to create a pointer of type \p ResTy, based on \p Ptr, and
320/// advanced by \p Offset bytes. To aid later analysis the method tries to build
321/// getelement pointer instructions that traverse the natural type of \p Ptr if
322/// possible. If that fails, the remaining offset is adjusted byte-wise, hence
323/// through a cast to i8*.
324///
325/// TODO: This could probably live somewhere more prominantly if it doesn't
326/// already exist.
327static Value *constructPointer(Type *ResTy, Value *Ptr, int64_t Offset,
328 IRBuilder<NoFolder> &IRB, const DataLayout &DL) {
329 assert(Offset >= 0 && "Negative offset not supported yet!");
330 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
331 << "-bytes as " << *ResTy << "\n");
332
333 // The initial type we are trying to traverse to get nice GEPs.
334 Type *Ty = Ptr->getType();
335
336 SmallVector<Value *, 4> Indices;
337 std::string GEPName = Ptr->getName().str();
338 while (Offset) {
339 uint64_t Idx, Rem;
340
341 if (auto *STy = dyn_cast<StructType>(Ty)) {
342 const StructLayout *SL = DL.getStructLayout(STy);
343 if (int64_t(SL->getSizeInBytes()) < Offset)
344 break;
345 Idx = SL->getElementContainingOffset(Offset);
346 assert(Idx < STy->getNumElements() && "Offset calculation error!");
347 Rem = Offset - SL->getElementOffset(Idx);
348 Ty = STy->getElementType(Idx);
349 } else if (auto *PTy = dyn_cast<PointerType>(Ty)) {
350 Ty = PTy->getElementType();
351 if (!Ty->isSized())
352 break;
353 uint64_t ElementSize = DL.getTypeAllocSize(Ty);
354 assert(ElementSize && "Expected type with size!");
355 Idx = Offset / ElementSize;
356 Rem = Offset % ElementSize;
357 } else {
358 // Non-aggregate type, we cast and make byte-wise progress now.
359 break;
360 }
361
362 LLVM_DEBUG(errs() << "Ty: " << *Ty << " Offset: " << Offset
363 << " Idx: " << Idx << " Rem: " << Rem << "\n");
364
365 GEPName += "." + std::to_string(Idx);
366 Indices.push_back(ConstantInt::get(IRB.getInt32Ty(), Idx));
367 Offset = Rem;
368 }
369
370 // Create a GEP if we collected indices above.
371 if (Indices.size())
372 Ptr = IRB.CreateGEP(Ptr, Indices, GEPName);
373
374 // If an offset is left we use byte-wise adjustment.
375 if (Offset) {
376 Ptr = IRB.CreateBitCast(Ptr, IRB.getInt8PtrTy());
377 Ptr = IRB.CreateGEP(Ptr, IRB.getInt32(Offset),
378 GEPName + ".b" + Twine(Offset));
379 }
380
381 // Ensure the result has the requested type.
382 Ptr = IRB.CreateBitOrPointerCast(Ptr, ResTy, Ptr->getName() + ".cast");
383
384 LLVM_DEBUG(dbgs() << "Constructed pointer: " << *Ptr << "\n");
385 return Ptr;
386}
387
Johannes Doerfertdef99282019-08-14 21:29:37 +0000388/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000389/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000390/// with the "returned" attribute. Once we cannot look through the value any
391/// further, the callback \p VisitValueCB is invoked and passed the current
Johannes Doerfert52aec322020-02-11 15:11:32 -0600392/// value, the \p State, and a flag to indicate if we stripped anything.
393/// Stripped means that we unpacked the value associated with \p IRP at least
394/// once. Note that the value used for the callback may still be the value
395/// associated with \p IRP (due to PHIs). To limit how much effort is invested,
396/// we will never visit more values than specified by \p MaxValues.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000397template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000398static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000399 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000400 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfert282f5d72020-01-26 02:51:57 -0600401 int MaxValues = 8, const function_ref<Value *(Value *)> StripCB = nullptr) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000402
Johannes Doerfertdef99282019-08-14 21:29:37 +0000403 const AAIsDead *LivenessAA = nullptr;
404 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000405 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000406 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
407 /* TrackDependence */ false);
408 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000409
410 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000411 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000412 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000413 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000414
415 int Iteration = 0;
416 do {
417 Value *V = Worklist.pop_back_val();
Johannes Doerfert282f5d72020-01-26 02:51:57 -0600418 if (StripCB)
419 V = StripCB(V);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000420
421 // Check if we should process the current value. To prevent endless
422 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000423 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000424 continue;
425
426 // Make sure we limit the compile time for complex expressions.
427 if (Iteration++ >= MaxValues)
428 return false;
429
430 // Explicitly look through calls with a "returned" attribute if we do
431 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000432 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000433 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000434 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000435 } else {
436 CallSite CS(V);
437 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000438 for (Argument &Arg : CS.getCalledFunction()->args())
439 if (Arg.hasReturnedAttr()) {
440 NewV = CS.getArgOperand(Arg.getArgNo());
441 break;
442 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000443 }
444 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000445 if (NewV && NewV != V) {
446 Worklist.push_back(NewV);
447 continue;
448 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000449
450 // Look through select instructions, visit both potential values.
451 if (auto *SI = dyn_cast<SelectInst>(V)) {
452 Worklist.push_back(SI->getTrueValue());
453 Worklist.push_back(SI->getFalseValue());
454 continue;
455 }
456
Johannes Doerfertdef99282019-08-14 21:29:37 +0000457 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000458 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000459 assert(LivenessAA &&
460 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000461 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
462 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert23f41f12020-01-12 01:09:22 -0600463 if (A.isAssumedDead(*IncomingBB->getTerminator(), &QueryingAA,
464 LivenessAA,
465 /* CheckBBLivenessOnly */ true)) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000466 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000467 continue;
468 }
469 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000470 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000471 continue;
472 }
473
474 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000475 if (!VisitValueCB(*V, State, Iteration > 1))
476 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000477 } while (!Worklist.empty());
478
Johannes Doerfert19b00432019-08-26 17:48:05 +0000479 // If we actually used liveness information so we have to record a dependence.
480 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -0500481 A.recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000482
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000483 // All values have been visited.
484 return true;
485}
486
Johannes Doerfertaade7822019-06-05 03:02:24 +0000487/// Return true if \p New is equal or worse than \p Old.
488static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
489 if (!Old.isIntAttribute())
490 return true;
491
492 return Old.getValueAsInt() >= New.getValueAsInt();
493}
494
495/// Return true if the information provided by \p Attr was added to the
496/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000497/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000498static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000499 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000500
501 if (Attr.isEnumAttribute()) {
502 Attribute::AttrKind Kind = Attr.getKindAsEnum();
503 if (Attrs.hasAttribute(AttrIdx, Kind))
504 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
505 return false;
506 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
507 return true;
508 }
509 if (Attr.isStringAttribute()) {
510 StringRef Kind = Attr.getKindAsString();
511 if (Attrs.hasAttribute(AttrIdx, Kind))
512 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
513 return false;
514 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
515 return true;
516 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000517 if (Attr.isIntAttribute()) {
518 Attribute::AttrKind Kind = Attr.getKindAsEnum();
519 if (Attrs.hasAttribute(AttrIdx, Kind))
520 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
521 return false;
522 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
523 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
524 return true;
525 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000526
527 llvm_unreachable("Expected enum or string attribute!");
528}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000529
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000530static const Value *
531getBasePointerOfAccessPointerOperand(const Instruction *I, int64_t &BytesOffset,
532 const DataLayout &DL,
533 bool AllowNonInbounds = false) {
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -0600534 const Value *Ptr = getPointerOperand(I, /* AllowVolatile */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000535 if (!Ptr)
536 return nullptr;
537
538 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000539 AllowNonInbounds);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000540}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000541
Johannes Doerfertece81902019-08-12 22:05:53 +0000542ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000543 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
544 if (getState().isAtFixpoint())
545 return HasChanged;
546
547 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
548
Johannes Doerfertece81902019-08-12 22:05:53 +0000549 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000550
551 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
552 << "\n");
553
554 return HasChanged;
555}
556
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000557ChangeStatus
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500558IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000559 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000560 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000561 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000562
Johannes Doerfertaade7822019-06-05 03:02:24 +0000563 // In the following some generic code that will manifest attributes in
564 // DeducedAttrs if they improve the current IR. Due to the different
565 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000566
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000567 AttributeList Attrs;
568 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000569 case IRPosition::IRP_INVALID:
570 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000571 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000572 case IRPosition::IRP_ARGUMENT:
573 case IRPosition::IRP_FUNCTION:
574 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000575 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000576 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000577 case IRPosition::IRP_CALL_SITE:
578 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000579 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000580 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000581 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000582 }
583
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000584 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000585 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000586 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000587 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000588 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000589
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000590 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000591 }
592
593 if (HasChanged == ChangeStatus::UNCHANGED)
594 return HasChanged;
595
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000596 switch (PK) {
597 case IRPosition::IRP_ARGUMENT:
598 case IRPosition::IRP_FUNCTION:
599 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000600 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000601 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000602 case IRPosition::IRP_CALL_SITE:
603 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000604 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000605 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000606 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000607 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000608 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000609 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000610 }
611
612 return HasChanged;
613}
614
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000615const IRPosition IRPosition::EmptyKey(255);
616const IRPosition IRPosition::TombstoneKey(256);
617
618SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
619 IRPositions.emplace_back(IRP);
620
621 ImmutableCallSite ICS(&IRP.getAnchorValue());
622 switch (IRP.getPositionKind()) {
623 case IRPosition::IRP_INVALID:
624 case IRPosition::IRP_FLOAT:
625 case IRPosition::IRP_FUNCTION:
626 return;
627 case IRPosition::IRP_ARGUMENT:
628 case IRPosition::IRP_RETURNED:
629 IRPositions.emplace_back(
630 IRPosition::function(*IRP.getAssociatedFunction()));
631 return;
632 case IRPosition::IRP_CALL_SITE:
633 assert(ICS && "Expected call site!");
634 // TODO: We need to look at the operand bundles similar to the redirection
635 // in CallBase.
636 if (!ICS.hasOperandBundles())
637 if (const Function *Callee = ICS.getCalledFunction())
638 IRPositions.emplace_back(IRPosition::function(*Callee));
639 return;
640 case IRPosition::IRP_CALL_SITE_RETURNED:
641 assert(ICS && "Expected call site!");
642 // TODO: We need to look at the operand bundles similar to the redirection
643 // in CallBase.
644 if (!ICS.hasOperandBundles()) {
645 if (const Function *Callee = ICS.getCalledFunction()) {
646 IRPositions.emplace_back(IRPosition::returned(*Callee));
647 IRPositions.emplace_back(IRPosition::function(*Callee));
Johannes Doerfertf8ad7352020-02-19 23:39:57 -0600648 for (const Argument &Arg : Callee->args())
649 if (Arg.hasReturnedAttr()) {
650 IRPositions.emplace_back(
651 IRPosition::callsite_argument(ICS, Arg.getArgNo()));
652 IRPositions.emplace_back(
653 IRPosition::value(*ICS.getArgOperand(Arg.getArgNo())));
654 IRPositions.emplace_back(IRPosition::argument(Arg));
655 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000656 }
657 }
658 IRPositions.emplace_back(
659 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
660 return;
661 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
662 int ArgNo = IRP.getArgNo();
663 assert(ICS && ArgNo >= 0 && "Expected call site!");
664 // TODO: We need to look at the operand bundles similar to the redirection
665 // in CallBase.
666 if (!ICS.hasOperandBundles()) {
667 const Function *Callee = ICS.getCalledFunction();
668 if (Callee && Callee->arg_size() > unsigned(ArgNo))
669 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
670 if (Callee)
671 IRPositions.emplace_back(IRPosition::function(*Callee));
672 }
673 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
674 return;
675 }
676 }
677}
678
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000679bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
680 bool IgnoreSubsumingPositions) const {
681 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000682 for (Attribute::AttrKind AK : AKs)
683 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
684 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000685 // The first position returned by the SubsumingPositionIterator is
686 // always the position itself. If we ignore subsuming positions we
687 // are done after the first iteration.
688 if (IgnoreSubsumingPositions)
689 break;
690 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000691 return false;
692}
693
694void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600695 SmallVectorImpl<Attribute> &Attrs,
696 bool IgnoreSubsumingPositions) const {
697 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000698 for (Attribute::AttrKind AK : AKs) {
699 const Attribute &Attr = EquivIRP.getAttr(AK);
700 if (Attr.getKindAsEnum() == AK)
701 Attrs.push_back(Attr);
702 }
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600703 // The first position returned by the SubsumingPositionIterator is
704 // always the position itself. If we ignore subsuming positions we
705 // are done after the first iteration.
706 if (IgnoreSubsumingPositions)
707 break;
708 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000709}
710
711void IRPosition::verify() {
712 switch (KindOrArgNo) {
713 default:
714 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
715 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
716 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000717 if (isa<Argument>(AnchorVal)) {
718 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000719 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000720 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
721 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000722 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000723 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000724 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000725 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
726 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000727 "Associated value mismatch!");
728 }
729 break;
730 case IRP_INVALID:
731 assert(!AnchorVal && "Expected no value for an invalid position!");
732 break;
733 case IRP_FLOAT:
734 assert((!isa<CallBase>(&getAssociatedValue()) &&
735 !isa<Argument>(&getAssociatedValue())) &&
736 "Expected specialized kind for call base and argument values!");
737 break;
738 case IRP_RETURNED:
739 assert(isa<Function>(AnchorVal) &&
740 "Expected function for a 'returned' position!");
741 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
742 break;
743 case IRP_CALL_SITE_RETURNED:
744 assert((isa<CallBase>(AnchorVal)) &&
745 "Expected call base for 'call site returned' position!");
746 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
747 break;
748 case IRP_CALL_SITE:
749 assert((isa<CallBase>(AnchorVal)) &&
750 "Expected call base for 'call site function' position!");
751 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
752 break;
753 case IRP_FUNCTION:
754 assert(isa<Function>(AnchorVal) &&
755 "Expected function for a 'function' position!");
756 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
757 break;
758 }
759}
760
Benjamin Kramer564a9de2020-02-17 17:55:03 +0100761namespace {
762
Johannes Doerfert1a746452019-10-20 22:28:49 -0500763/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000764/// information in \p R and indicate/return if \p S did change (as-in update is
765/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000766template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500767ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000768 auto Assumed = S.getAssumed();
769 S ^= R;
770 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
771 : ChangeStatus::CHANGED;
772}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000773
Johannes Doerfert234eda52019-08-16 19:51:23 +0000774/// Clamp the information known for all returned values of a function
775/// (identified by \p QueryingAA) into \p S.
776template <typename AAType, typename StateType = typename AAType::StateType>
777static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
778 StateType &S) {
779 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600780 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000781
782 assert((QueryingAA.getIRPosition().getPositionKind() ==
783 IRPosition::IRP_RETURNED ||
784 QueryingAA.getIRPosition().getPositionKind() ==
785 IRPosition::IRP_CALL_SITE_RETURNED) &&
786 "Can only clamp returned value states for a function returned or call "
787 "site returned position!");
788
789 // Use an optional state as there might not be any return values and we want
790 // to join (IntegerState::operator&) the state of all there are.
791 Optional<StateType> T;
792
793 // Callback for each possibly returned value.
794 auto CheckReturnValue = [&](Value &RV) -> bool {
795 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000796 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
797 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
798 << " @ " << RVPos << "\n");
799 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000800 if (T.hasValue())
801 *T &= AAS;
802 else
803 T = AAS;
804 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
805 << "\n");
806 return T->isValidState();
807 };
808
809 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
810 S.indicatePessimisticFixpoint();
811 else if (T.hasValue())
812 S ^= *T;
813}
814
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000815/// Helper class to compose two generic deduction
816template <typename AAType, typename Base, typename StateType,
817 template <typename...> class F, template <typename...> class G>
818struct AAComposeTwoGenericDeduction
819 : public F<AAType, G<AAType, Base, StateType>, StateType> {
820 AAComposeTwoGenericDeduction(const IRPosition &IRP)
821 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
822
823 /// See AbstractAttribute::updateImpl(...).
824 ChangeStatus updateImpl(Attributor &A) override {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100825 ChangeStatus ChangedF =
826 F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000827 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
828 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000829 }
830};
831
Johannes Doerfert234eda52019-08-16 19:51:23 +0000832/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000833template <typename AAType, typename Base,
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600834 typename StateType = typename Base::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000835struct AAReturnedFromReturnedValues : public Base {
836 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000837
838 /// See AbstractAttribute::updateImpl(...).
839 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600840 StateType S(StateType::getBestState(this->getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000841 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000842 // TODO: If we know we visited all returned values, thus no are assumed
843 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000844 return clampStateAndIndicateChange<StateType>(this->getState(), S);
845 }
846};
847
848/// Clamp the information known at all call sites for a given argument
849/// (identified by \p QueryingAA) into \p S.
850template <typename AAType, typename StateType = typename AAType::StateType>
851static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
852 StateType &S) {
853 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600854 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000855
856 assert(QueryingAA.getIRPosition().getPositionKind() ==
857 IRPosition::IRP_ARGUMENT &&
858 "Can only clamp call site argument states for an argument position!");
859
860 // Use an optional state as there might not be any return values and we want
861 // to join (IntegerState::operator&) the state of all there are.
862 Optional<StateType> T;
863
864 // The argument number which is also the call site argument number.
865 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
866
Johannes Doerfert661db042019-10-07 23:14:58 +0000867 auto CallSiteCheck = [&](AbstractCallSite ACS) {
868 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
869 // Check if a coresponding argument was found or if it is on not associated
870 // (which can happen for callback calls).
871 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
872 return false;
873
874 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
875 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
876 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000877 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000878 if (T.hasValue())
879 *T &= AAS;
880 else
881 T = AAS;
882 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
883 << "\n");
884 return T->isValidState();
885 };
886
Johannes Doerfert368f7ee2019-12-30 16:12:36 -0600887 bool AllCallSitesKnown;
888 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
889 AllCallSitesKnown))
Johannes Doerfert234eda52019-08-16 19:51:23 +0000890 S.indicatePessimisticFixpoint();
891 else if (T.hasValue())
892 S ^= *T;
893}
894
895/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000896template <typename AAType, typename Base,
897 typename StateType = typename AAType::StateType>
898struct AAArgumentFromCallSiteArguments : public Base {
899 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000900
901 /// See AbstractAttribute::updateImpl(...).
902 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertea5fabe2020-01-28 09:46:15 -0600903 StateType S(StateType::getBestState(this->getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000904 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000905 // TODO: If we know we visited all incoming values, thus no are assumed
906 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000907 return clampStateAndIndicateChange<StateType>(this->getState(), S);
908 }
909};
910
911/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000912template <typename AAType, typename Base,
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600913 typename StateType = typename Base::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000914struct AACallSiteReturnedFromReturned : public Base {
915 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000916
917 /// See AbstractAttribute::updateImpl(...).
918 ChangeStatus updateImpl(Attributor &A) override {
919 assert(this->getIRPosition().getPositionKind() ==
920 IRPosition::IRP_CALL_SITE_RETURNED &&
921 "Can only wrap function returned positions for call site returned "
922 "positions!");
923 auto &S = this->getState();
924
925 const Function *AssociatedFunction =
926 this->getIRPosition().getAssociatedFunction();
927 if (!AssociatedFunction)
928 return S.indicatePessimisticFixpoint();
929
930 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000931 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000932 return clampStateAndIndicateChange(
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600933 S, static_cast<const StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000934 }
935};
936
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000937/// Helper class for generic deduction using must-be-executed-context
938/// Base class is required to have `followUse` method.
939
940/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000941/// U - Underlying use.
942/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000943/// `followUse` returns true if the value should be tracked transitively.
944
945template <typename AAType, typename Base,
946 typename StateType = typename AAType::StateType>
947struct AAFromMustBeExecutedContext : public Base {
948 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
949
950 void initialize(Attributor &A) override {
951 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500952 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000953 Instruction *CtxI = IRP.getCtxI();
954
955 if (!CtxI)
956 return;
957
958 for (const Use &U : IRP.getAssociatedValue().uses())
959 Uses.insert(&U);
960 }
961
962 /// See AbstractAttribute::updateImpl(...).
963 ChangeStatus updateImpl(Attributor &A) override {
964 auto BeforeState = this->getState();
965 auto &S = this->getState();
966 Instruction *CtxI = this->getIRPosition().getCtxI();
967 if (!CtxI)
968 return ChangeStatus::UNCHANGED;
969
970 MustBeExecutedContextExplorer &Explorer =
971 A.getInfoCache().getMustBeExecutedContextExplorer();
972
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500973 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100974 for (unsigned u = 0; u < Uses.size(); ++u) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500975 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000976 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500977 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000978 if (Found && Base::followUse(A, U, UserI))
979 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500980 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000981 }
982 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000983
984 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
985 }
986
987private:
988 /// Container for (transitive) uses of the associated value.
989 SetVector<const Use *> Uses;
990};
991
992template <typename AAType, typename Base,
993 typename StateType = typename AAType::StateType>
994using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
995 AAComposeTwoGenericDeduction<AAType, Base, StateType,
996 AAFromMustBeExecutedContext,
997 AAArgumentFromCallSiteArguments>;
998
999template <typename AAType, typename Base,
1000 typename StateType = typename AAType::StateType>
1001using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
1002 AAComposeTwoGenericDeduction<AAType, Base, StateType,
1003 AAFromMustBeExecutedContext,
1004 AACallSiteReturnedFromReturned>;
1005
Stefan Stipanovic53605892019-06-27 11:27:54 +00001006/// -----------------------NoUnwind Function Attribute--------------------------
1007
Johannes Doerfert344d0382019-08-07 22:34:26 +00001008struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001009 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +00001010
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001011 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +00001012 return getAssumed() ? "nounwind" : "may-unwind";
1013 }
1014
1015 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001016 ChangeStatus updateImpl(Attributor &A) override {
1017 auto Opcodes = {
1018 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
1019 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
1020 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
1021
1022 auto CheckForNoUnwind = [&](Instruction &I) {
1023 if (!I.mayThrow())
1024 return true;
1025
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001026 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1027 const auto &NoUnwindAA =
1028 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
1029 return NoUnwindAA.isAssumedNoUnwind();
1030 }
1031 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001032 };
1033
1034 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
1035 return indicatePessimisticFixpoint();
1036
1037 return ChangeStatus::UNCHANGED;
1038 }
Stefan Stipanovic53605892019-06-27 11:27:54 +00001039};
1040
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001041struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001042 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001043
1044 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001045 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001046};
1047
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001048/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001049struct AANoUnwindCallSite final : AANoUnwindImpl {
1050 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
1051
1052 /// See AbstractAttribute::initialize(...).
1053 void initialize(Attributor &A) override {
1054 AANoUnwindImpl::initialize(A);
1055 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001056 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001057 indicatePessimisticFixpoint();
1058 }
1059
1060 /// See AbstractAttribute::updateImpl(...).
1061 ChangeStatus updateImpl(Attributor &A) override {
1062 // TODO: Once we have call site specific value information we can provide
1063 // call site specific liveness information and then it makes
1064 // sense to specialize attributes for call sites arguments instead of
1065 // redirecting requests to the callee argument.
1066 Function *F = getAssociatedFunction();
1067 const IRPosition &FnPos = IRPosition::function(*F);
1068 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
1069 return clampStateAndIndicateChange(
1070 getState(),
1071 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
1072 }
1073
1074 /// See AbstractAttribute::trackStatistics()
1075 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
1076};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001077
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001078/// --------------------- Function Return Values -------------------------------
1079
1080/// "Attribute" that collects all potential returned values and the return
1081/// instructions that they arise from.
1082///
1083/// If there is a unique returned value R, the manifest method will:
1084/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +00001085class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001086
1087 /// Mapping of values potentially returned by the associated function to the
1088 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +00001089 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001090
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001091 /// Mapping to remember the number of returned values for a call site such
1092 /// that we can avoid updates if nothing changed.
1093 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
1094
1095 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001096 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001097
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001098 /// State flags
1099 ///
1100 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001101 bool IsFixed = false;
1102 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001103 ///}
1104
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001105public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001106 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001107
1108 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001109 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001110 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001111 IsFixed = false;
1112 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001113 ReturnedValues.clear();
1114
Johannes Doerfertdef99282019-08-14 21:29:37 +00001115 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001116 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001117 indicatePessimisticFixpoint();
1118 return;
1119 }
Johannes Doerferte273ac42020-01-12 00:13:03 -06001120 assert(!F->getReturnType()->isVoidTy() &&
1121 "Did not expect a void return type!");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001122
1123 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001124 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001125
1126 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001127 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001128 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001129 auto &ReturnInstSet = ReturnedValues[&Arg];
1130 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
1131 ReturnInstSet.insert(cast<ReturnInst>(RI));
1132
1133 indicateOptimisticFixpoint();
1134 return;
1135 }
1136 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001137
1138 if (!F->hasExactDefinition())
1139 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001140 }
1141
1142 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001143 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001144
1145 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001146 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001147
1148 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001149 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001150
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001151 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00001152 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001153
Johannes Doerfertdef99282019-08-14 21:29:37 +00001154 llvm::iterator_range<iterator> returned_values() override {
1155 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1156 }
1157
1158 llvm::iterator_range<const_iterator> returned_values() const override {
1159 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1160 }
1161
Johannes Doerfert695089e2019-08-23 15:23:49 +00001162 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001163 return UnresolvedCalls;
1164 }
1165
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001166 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001167 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001168 return isValidState() ? ReturnedValues.size() : -1;
1169 }
1170
1171 /// Return an assumed unique return value if a single candidate is found. If
1172 /// there cannot be one, return a nullptr. If it is not clear yet, return the
1173 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001174 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001175
Johannes Doerfert14a04932019-08-07 22:27:24 +00001176 /// See AbstractState::checkForAllReturnedValues(...).
1177 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001178 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001179 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001180
1181 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001182 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001183
1184 /// See AbstractState::isAtFixpoint().
1185 bool isAtFixpoint() const override { return IsFixed; }
1186
1187 /// See AbstractState::isValidState().
1188 bool isValidState() const override { return IsValidState; }
1189
1190 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001191 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001192 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001193 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001194 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001195
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001196 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001197 IsFixed = true;
1198 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001199 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001200 }
1201};
1202
1203ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
1204 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1205
1206 // Bookkeeping.
1207 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001208 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
1209 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001210
1211 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001212 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001213
1214 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
1215 return Changed;
1216
1217 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001218 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
1219 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001220
Johannes Doerfert23400e612019-08-23 17:41:37 +00001221 // Callback to replace the uses of CB with the constant C.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06001222 auto ReplaceCallSiteUsersWith = [&A](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +00001223 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +00001224 return ChangeStatus::UNCHANGED;
Johannes Doerfert4c62a352020-01-12 00:17:08 -06001225 if (A.changeValueAfterManifest(CB, C))
1226 return ChangeStatus::CHANGED;
1227 return ChangeStatus::UNCHANGED;
Johannes Doerfert23400e612019-08-23 17:41:37 +00001228 };
1229
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001230 // If the assumed unique return value is an argument, annotate it.
1231 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05001232 // TODO: This should be handled differently!
1233 this->AnchorVal = UniqueRVArg;
1234 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +00001235 Changed = IRAttribute::manifest(A);
1236 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
1237 // We can replace the returned value with the unique returned constant.
1238 Value &AnchorValue = getAnchorValue();
1239 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1240 for (const Use &U : F->uses())
1241 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001242 if (CB->isCallee(&U)) {
1243 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001244 CB->getType() == RVC->getType()
1245 ? RVC
1246 : ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001247 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1248 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001249 } else {
1250 assert(isa<CallBase>(AnchorValue) &&
1251 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001252 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001253 AnchorValue.getType() == RVC->getType()
1254 ? RVC
1255 : ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001256 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001257 }
1258 if (Changed == ChangeStatus::CHANGED)
1259 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1260 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001261 }
1262
1263 return Changed;
1264}
1265
1266const std::string AAReturnedValuesImpl::getAsStr() const {
1267 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001268 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001269 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001270}
1271
Johannes Doerfert14a04932019-08-07 22:27:24 +00001272Optional<Value *>
1273AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1274 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001275 // undef values that can also be present, it is assumed to be the actual
1276 // return value and forwarded to the caller of this method. If there are
1277 // multiple, a nullptr is returned indicating there cannot be a unique
1278 // returned value.
1279 Optional<Value *> UniqueRV;
1280
Johannes Doerfert14a04932019-08-07 22:27:24 +00001281 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001282 // If we found a second returned value and neither the current nor the saved
1283 // one is an undef, there is no unique returned value. Undefs are special
1284 // since we can pretend they have any value.
1285 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1286 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1287 UniqueRV = nullptr;
1288 return false;
1289 }
1290
1291 // Do not overwrite a value with an undef.
1292 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1293 UniqueRV = &RV;
1294
1295 return true;
1296 };
1297
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001298 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001299 UniqueRV = nullptr;
1300
1301 return UniqueRV;
1302}
1303
Johannes Doerfert14a04932019-08-07 22:27:24 +00001304bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001305 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001306 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001307 if (!isValidState())
1308 return false;
1309
1310 // Check all returned values but ignore call sites as long as we have not
1311 // encountered an overdefined one during an update.
1312 for (auto &It : ReturnedValues) {
1313 Value *RV = It.first;
1314
Johannes Doerfertdef99282019-08-14 21:29:37 +00001315 CallBase *CB = dyn_cast<CallBase>(RV);
1316 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001317 continue;
1318
Johannes Doerfert695089e2019-08-23 15:23:49 +00001319 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001320 return false;
1321 }
1322
1323 return true;
1324}
1325
Johannes Doerfertece81902019-08-12 22:05:53 +00001326ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001327 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1328 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001329
Johannes Doerfertdef99282019-08-14 21:29:37 +00001330 // State used in the value traversals starting in returned values.
1331 struct RVState {
1332 // The map in which we collect return values -> return instrs.
1333 decltype(ReturnedValues) &RetValsMap;
1334 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001335 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001336 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001337 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001338 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001339
Johannes Doerfertdef99282019-08-14 21:29:37 +00001340 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001341 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001342 auto Size = RVS.RetValsMap[&Val].size();
1343 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1344 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1345 RVS.Changed |= Inserted;
1346 LLVM_DEBUG({
1347 if (Inserted)
1348 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1349 << " => " << RVS.RetInsts.size() << "\n";
1350 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001351 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001352 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001353
Johannes Doerfertdef99282019-08-14 21:29:37 +00001354 // Helper method to invoke the generic value traversal.
1355 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1356 IRPosition RetValPos = IRPosition::value(RV);
1357 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1358 RVS, VisitValueCB);
1359 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001360
Johannes Doerfertdef99282019-08-14 21:29:37 +00001361 // Callback for all "return intructions" live in the associated function.
1362 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1363 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001364 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001365 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001366 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1367 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001368
Johannes Doerfertdef99282019-08-14 21:29:37 +00001369 // Start by discovering returned values from all live returned instructions in
1370 // the associated function.
1371 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1372 return indicatePessimisticFixpoint();
1373
1374 // Once returned values "directly" present in the code are handled we try to
1375 // resolve returned calls.
1376 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001377 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001378 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1379 << " by #" << It.second.size() << " RIs\n");
1380 CallBase *CB = dyn_cast<CallBase>(It.first);
1381 if (!CB || UnresolvedCalls.count(CB))
1382 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001383
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001384 if (!CB->getCalledFunction()) {
1385 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1386 << "\n");
1387 UnresolvedCalls.insert(CB);
1388 continue;
1389 }
1390
1391 // TODO: use the function scope once we have call site AAReturnedValues.
1392 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1393 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001394 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06001395 << RetValAA << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001396
1397 // Skip dead ends, thus if we do not know anything about the returned
1398 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001399 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001400 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1401 << "\n");
1402 UnresolvedCalls.insert(CB);
1403 continue;
1404 }
1405
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001406 // Do not try to learn partial information. If the callee has unresolved
1407 // return values we will treat the call as unresolved/opaque.
1408 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1409 if (!RetValAAUnresolvedCalls.empty()) {
1410 UnresolvedCalls.insert(CB);
1411 continue;
1412 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001413
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001414 // Now check if we can track transitively returned values. If possible, thus
1415 // if all return value can be represented in the current scope, do so.
1416 bool Unresolved = false;
1417 for (auto &RetValAAIt : RetValAA.returned_values()) {
1418 Value *RetVal = RetValAAIt.first;
1419 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1420 isa<Constant>(RetVal))
1421 continue;
1422 // Anything that did not fit in the above categories cannot be resolved,
1423 // mark the call as unresolved.
1424 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1425 "cannot be translated: "
1426 << *RetVal << "\n");
1427 UnresolvedCalls.insert(CB);
1428 Unresolved = true;
1429 break;
1430 }
1431
1432 if (Unresolved)
1433 continue;
1434
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001435 // Now track transitively returned values.
1436 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1437 if (NumRetAA == RetValAA.getNumReturnValues()) {
1438 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1439 "changed since it was seen last\n");
1440 continue;
1441 }
1442 NumRetAA = RetValAA.getNumReturnValues();
1443
Johannes Doerfertdef99282019-08-14 21:29:37 +00001444 for (auto &RetValAAIt : RetValAA.returned_values()) {
1445 Value *RetVal = RetValAAIt.first;
1446 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1447 // Arguments are mapped to call site operands and we begin the traversal
1448 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001449 bool Unused = false;
1450 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001451 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1452 continue;
1453 } else if (isa<CallBase>(RetVal)) {
1454 // Call sites are resolved by the callee attribute over time, no need to
1455 // do anything for us.
1456 continue;
1457 } else if (isa<Constant>(RetVal)) {
1458 // Constants are valid everywhere, we can simply take them.
1459 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1460 continue;
1461 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001462 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001463 }
1464
Johannes Doerfertdef99282019-08-14 21:29:37 +00001465 // To avoid modifications to the ReturnedValues map while we iterate over it
1466 // we kept record of potential new entries in a copy map, NewRVsMap.
1467 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001468 assert(!It.second.empty() && "Entry does not add anything.");
1469 auto &ReturnInsts = ReturnedValues[It.first];
1470 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001471 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001472 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1473 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001474 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001475 }
1476 }
1477
Johannes Doerfertdef99282019-08-14 21:29:37 +00001478 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1479 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001480}
1481
Johannes Doerfertdef99282019-08-14 21:29:37 +00001482struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1483 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1484
1485 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001486 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001487};
1488
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001489/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001490struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1491 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1492
1493 /// See AbstractAttribute::initialize(...).
1494 void initialize(Attributor &A) override {
1495 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001496 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001497 // sense to specialize attributes for call sites instead of
1498 // redirecting requests to the callee.
1499 llvm_unreachable("Abstract attributes for returned values are not "
1500 "supported for call sites yet!");
1501 }
1502
1503 /// See AbstractAttribute::updateImpl(...).
1504 ChangeStatus updateImpl(Attributor &A) override {
1505 return indicatePessimisticFixpoint();
1506 }
1507
1508 /// See AbstractAttribute::trackStatistics()
1509 void trackStatistics() const override {}
1510};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001511
Stefan Stipanovic06263672019-07-11 21:37:40 +00001512/// ------------------------ NoSync Function Attribute -------------------------
1513
Johannes Doerfert344d0382019-08-07 22:34:26 +00001514struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001515 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001516
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001517 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001518 return getAssumed() ? "nosync" : "may-sync";
1519 }
1520
1521 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001522 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001523
Stefan Stipanovic06263672019-07-11 21:37:40 +00001524 /// Helper function used to determine whether an instruction is non-relaxed
1525 /// atomic. In other words, if an atomic instruction does not have unordered
1526 /// or monotonic ordering
1527 static bool isNonRelaxedAtomic(Instruction *I);
1528
1529 /// Helper function used to determine whether an instruction is volatile.
1530 static bool isVolatile(Instruction *I);
1531
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001532 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1533 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001534 static bool isNoSyncIntrinsic(Instruction *I);
1535};
1536
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001537bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001538 if (!I->isAtomic())
1539 return false;
1540
1541 AtomicOrdering Ordering;
1542 switch (I->getOpcode()) {
1543 case Instruction::AtomicRMW:
1544 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1545 break;
1546 case Instruction::Store:
1547 Ordering = cast<StoreInst>(I)->getOrdering();
1548 break;
1549 case Instruction::Load:
1550 Ordering = cast<LoadInst>(I)->getOrdering();
1551 break;
1552 case Instruction::Fence: {
1553 auto *FI = cast<FenceInst>(I);
1554 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1555 return false;
1556 Ordering = FI->getOrdering();
1557 break;
1558 }
1559 case Instruction::AtomicCmpXchg: {
1560 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1561 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1562 // Only if both are relaxed, than it can be treated as relaxed.
1563 // Otherwise it is non-relaxed.
1564 if (Success != AtomicOrdering::Unordered &&
1565 Success != AtomicOrdering::Monotonic)
1566 return true;
1567 if (Failure != AtomicOrdering::Unordered &&
1568 Failure != AtomicOrdering::Monotonic)
1569 return true;
1570 return false;
1571 }
1572 default:
1573 llvm_unreachable(
1574 "New atomic operations need to be known in the attributor.");
1575 }
1576
1577 // Relaxed.
1578 if (Ordering == AtomicOrdering::Unordered ||
1579 Ordering == AtomicOrdering::Monotonic)
1580 return false;
1581 return true;
1582}
1583
1584/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1585/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001586bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001587 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1588 switch (II->getIntrinsicID()) {
1589 /// Element wise atomic memory intrinsics are can only be unordered,
1590 /// therefore nosync.
1591 case Intrinsic::memset_element_unordered_atomic:
1592 case Intrinsic::memmove_element_unordered_atomic:
1593 case Intrinsic::memcpy_element_unordered_atomic:
1594 return true;
1595 case Intrinsic::memset:
1596 case Intrinsic::memmove:
1597 case Intrinsic::memcpy:
1598 if (!cast<MemIntrinsic>(II)->isVolatile())
1599 return true;
1600 return false;
1601 default:
1602 return false;
1603 }
1604 }
1605 return false;
1606}
1607
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001608bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001609 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1610 "Calls should not be checked here");
1611
1612 switch (I->getOpcode()) {
1613 case Instruction::AtomicRMW:
1614 return cast<AtomicRMWInst>(I)->isVolatile();
1615 case Instruction::Store:
1616 return cast<StoreInst>(I)->isVolatile();
1617 case Instruction::Load:
1618 return cast<LoadInst>(I)->isVolatile();
1619 case Instruction::AtomicCmpXchg:
1620 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1621 default:
1622 return false;
1623 }
1624}
1625
Johannes Doerfertece81902019-08-12 22:05:53 +00001626ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001627
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001628 auto CheckRWInstForNoSync = [&](Instruction &I) {
1629 /// We are looking for volatile instructions or Non-Relaxed atomics.
Pankaj Godeb9a26a82019-11-22 14:46:43 +05301630 /// FIXME: We should improve the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001631
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001632 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1633 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001634
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001635 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1636 if (ICS.hasFnAttr(Attribute::NoSync))
1637 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001638
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001639 const auto &NoSyncAA =
1640 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1641 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001642 return true;
1643 return false;
1644 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001645
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001646 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1647 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001648
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001649 return false;
1650 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001651
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001652 auto CheckForNoSync = [&](Instruction &I) {
1653 // At this point we handled all read/write effects and they are all
1654 // nosync, so they can be skipped.
1655 if (I.mayReadOrWriteMemory())
1656 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001657
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001658 // non-convergent and readnone imply nosync.
1659 return !ImmutableCallSite(&I).isConvergent();
1660 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001661
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001662 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1663 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001664 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001665
Stefan Stipanovic06263672019-07-11 21:37:40 +00001666 return ChangeStatus::UNCHANGED;
1667}
1668
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001669struct AANoSyncFunction final : public AANoSyncImpl {
1670 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1671
1672 /// See AbstractAttribute::trackStatistics()
1673 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1674};
1675
1676/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001677struct AANoSyncCallSite final : AANoSyncImpl {
1678 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1679
1680 /// See AbstractAttribute::initialize(...).
1681 void initialize(Attributor &A) override {
1682 AANoSyncImpl::initialize(A);
1683 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001684 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001685 indicatePessimisticFixpoint();
1686 }
1687
1688 /// See AbstractAttribute::updateImpl(...).
1689 ChangeStatus updateImpl(Attributor &A) override {
1690 // TODO: Once we have call site specific value information we can provide
1691 // call site specific liveness information and then it makes
1692 // sense to specialize attributes for call sites arguments instead of
1693 // redirecting requests to the callee argument.
1694 Function *F = getAssociatedFunction();
1695 const IRPosition &FnPos = IRPosition::function(*F);
1696 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1697 return clampStateAndIndicateChange(
1698 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1699 }
1700
1701 /// See AbstractAttribute::trackStatistics()
1702 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1703};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001704
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001705/// ------------------------ No-Free Attributes ----------------------------
1706
Johannes Doerfert344d0382019-08-07 22:34:26 +00001707struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001708 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001709
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001710 /// See AbstractAttribute::updateImpl(...).
1711 ChangeStatus updateImpl(Attributor &A) override {
1712 auto CheckForNoFree = [&](Instruction &I) {
1713 ImmutableCallSite ICS(&I);
1714 if (ICS.hasFnAttr(Attribute::NoFree))
1715 return true;
1716
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001717 const auto &NoFreeAA =
1718 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1719 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001720 };
1721
1722 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1723 return indicatePessimisticFixpoint();
1724 return ChangeStatus::UNCHANGED;
1725 }
1726
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001727 /// See AbstractAttribute::getAsStr().
1728 const std::string getAsStr() const override {
1729 return getAssumed() ? "nofree" : "may-free";
1730 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001731};
1732
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001733struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001734 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001735
1736 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001737 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001738};
1739
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001740/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001741struct AANoFreeCallSite final : AANoFreeImpl {
1742 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1743
1744 /// See AbstractAttribute::initialize(...).
1745 void initialize(Attributor &A) override {
1746 AANoFreeImpl::initialize(A);
1747 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001748 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001749 indicatePessimisticFixpoint();
1750 }
1751
1752 /// See AbstractAttribute::updateImpl(...).
1753 ChangeStatus updateImpl(Attributor &A) override {
1754 // TODO: Once we have call site specific value information we can provide
1755 // call site specific liveness information and then it makes
1756 // sense to specialize attributes for call sites arguments instead of
1757 // redirecting requests to the callee argument.
1758 Function *F = getAssociatedFunction();
1759 const IRPosition &FnPos = IRPosition::function(*F);
1760 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1761 return clampStateAndIndicateChange(
1762 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1763 }
1764
1765 /// See AbstractAttribute::trackStatistics()
1766 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1767};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001768
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001769/// NoFree attribute for floating values.
1770struct AANoFreeFloating : AANoFreeImpl {
1771 AANoFreeFloating(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1772
1773 /// See AbstractAttribute::trackStatistics()
1774 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
1775
1776 /// See Abstract Attribute::updateImpl(...).
1777 ChangeStatus updateImpl(Attributor &A) override {
1778 const IRPosition &IRP = getIRPosition();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001779
1780 const auto &NoFreeAA =
1781 A.getAAFor<AANoFree>(*this, IRPosition::function_scope(IRP));
1782 if (NoFreeAA.isAssumedNoFree())
1783 return ChangeStatus::UNCHANGED;
1784
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001785 Value &AssociatedValue = getIRPosition().getAssociatedValue();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001786 auto Pred = [&](const Use &U, bool &Follow) -> bool {
1787 Instruction *UserI = cast<Instruction>(U.getUser());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001788 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001789 if (CB->isBundleOperand(&U))
1790 return false;
1791 if (!CB->isArgOperand(&U))
1792 return true;
1793 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001794
1795 const auto &NoFreeArg = A.getAAFor<AANoFree>(
1796 *this, IRPosition::callsite_argument(*CB, ArgNo));
Hideto Ueno63599bd2019-12-12 12:26:09 +00001797 return NoFreeArg.isAssumedNoFree();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001798 }
1799
1800 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
1801 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001802 Follow = true;
1803 return true;
Hideto Ueno4ecf2552019-12-12 13:42:40 +00001804 }
Johannes Doerfertf9555392020-01-10 14:49:45 -06001805 if (isa<ReturnInst>(UserI))
1806 return true;
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001807
1808 // Unknown user.
Hideto Ueno63599bd2019-12-12 12:26:09 +00001809 return false;
1810 };
1811 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001812 return indicatePessimisticFixpoint();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001813
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001814 return ChangeStatus::UNCHANGED;
1815 }
1816};
1817
1818/// NoFree attribute for a call site argument.
1819struct AANoFreeArgument final : AANoFreeFloating {
1820 AANoFreeArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1821
1822 /// See AbstractAttribute::trackStatistics()
1823 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
1824};
1825
1826/// NoFree attribute for call site arguments.
1827struct AANoFreeCallSiteArgument final : AANoFreeFloating {
1828 AANoFreeCallSiteArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1829
1830 /// See AbstractAttribute::updateImpl(...).
1831 ChangeStatus updateImpl(Attributor &A) override {
1832 // TODO: Once we have call site specific value information we can provide
1833 // call site specific liveness information and then it makes
1834 // sense to specialize attributes for call sites arguments instead of
1835 // redirecting requests to the callee argument.
1836 Argument *Arg = getAssociatedArgument();
1837 if (!Arg)
1838 return indicatePessimisticFixpoint();
1839 const IRPosition &ArgPos = IRPosition::argument(*Arg);
1840 auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
1841 return clampStateAndIndicateChange(
1842 getState(), static_cast<const AANoFree::StateType &>(ArgAA.getState()));
1843 }
1844
1845 /// See AbstractAttribute::trackStatistics()
1846 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
1847};
1848
1849/// NoFree attribute for function return value.
1850struct AANoFreeReturned final : AANoFreeFloating {
1851 AANoFreeReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {
1852 llvm_unreachable("NoFree is not applicable to function returns!");
1853 }
1854
1855 /// See AbstractAttribute::initialize(...).
1856 void initialize(Attributor &A) override {
1857 llvm_unreachable("NoFree is not applicable to function returns!");
1858 }
1859
1860 /// See AbstractAttribute::updateImpl(...).
1861 ChangeStatus updateImpl(Attributor &A) override {
1862 llvm_unreachable("NoFree is not applicable to function returns!");
1863 }
1864
1865 /// See AbstractAttribute::trackStatistics()
1866 void trackStatistics() const override {}
1867};
1868
1869/// NoFree attribute deduction for a call site return value.
1870struct AANoFreeCallSiteReturned final : AANoFreeFloating {
1871 AANoFreeCallSiteReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1872
1873 ChangeStatus manifest(Attributor &A) override {
1874 return ChangeStatus::UNCHANGED;
1875 }
1876 /// See AbstractAttribute::trackStatistics()
1877 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
1878};
1879
Hideto Ueno54869ec2019-07-15 06:49:04 +00001880/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001881static int64_t getKnownNonNullAndDerefBytesForUse(
1882 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1883 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001884 TrackUse = false;
1885
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001886 const Value *UseV = U->get();
1887 if (!UseV->getType()->isPointerTy())
1888 return 0;
1889
1890 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001891 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001892 bool NullPointerIsDefined =
1893 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001894 const DataLayout &DL = A.getInfoCache().getDL();
1895 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1896 if (ICS.isBundleOperand(U))
1897 return 0;
1898
1899 if (ICS.isCallee(U)) {
1900 IsNonNull |= !NullPointerIsDefined;
1901 return 0;
1902 }
1903
1904 unsigned ArgNo = ICS.getArgumentNo(U);
1905 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001906 // As long as we only use known information there is no need to track
1907 // dependences here.
1908 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP,
1909 /* TrackDependence */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001910 IsNonNull |= DerefAA.isKnownNonNull();
1911 return DerefAA.getKnownDereferenceableBytes();
1912 }
1913
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001914 // We need to follow common pointer manipulation uses to the accesses they
1915 // feed into. We can try to be smart to avoid looking through things we do not
1916 // like for now, e.g., non-inbounds GEPs.
1917 if (isa<CastInst>(I)) {
1918 TrackUse = true;
1919 return 0;
1920 }
1921 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001922 if (GEP->hasAllConstantIndices()) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001923 TrackUse = true;
1924 return 0;
1925 }
1926
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001927 int64_t Offset;
1928 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09001929 if (Base == &AssociatedValue &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06001930 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001931 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001932 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001933
1934 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001935 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001936 }
1937 }
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001938
1939 /// Corner case when an offset is 0.
1940 if (const Value *Base = getBasePointerOfAccessPointerOperand(
1941 I, Offset, DL, /*AllowNonInbounds*/ true)) {
1942 if (Offset == 0 && Base == &AssociatedValue &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06001943 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001944 int64_t DerefBytes =
1945 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType());
1946 IsNonNull |= !NullPointerIsDefined;
1947 return std::max(int64_t(0), DerefBytes);
1948 }
1949 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001950
1951 return 0;
1952}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001953
Johannes Doerfert344d0382019-08-07 22:34:26 +00001954struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001955 AANonNullImpl(const IRPosition &IRP)
1956 : AANonNull(IRP),
1957 NullIsDefined(NullPointerIsDefined(
1958 getAnchorScope(),
1959 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001960
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001961 /// See AbstractAttribute::initialize(...).
1962 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001963 if (!NullIsDefined &&
1964 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001965 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001966 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1967 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001968 else
1969 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001970 }
1971
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001972 /// See AAFromMustBeExecutedContext
1973 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1974 bool IsNonNull = false;
1975 bool TrackUse = false;
1976 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1977 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001978 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001979 return TrackUse;
1980 }
1981
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001982 /// See AbstractAttribute::getAsStr().
1983 const std::string getAsStr() const override {
1984 return getAssumed() ? "nonnull" : "may-null";
1985 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001986
1987 /// Flag to determine if the underlying value can be null and still allow
1988 /// valid accesses.
1989 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001990};
1991
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001992/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001993struct AANonNullFloating
1994 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1995 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1996 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001997
Hideto Ueno54869ec2019-07-15 06:49:04 +00001998 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001999 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002000 ChangeStatus Change = Base::updateImpl(A);
2001 if (isKnownNonNull())
2002 return Change;
2003
Johannes Doerfertd82385b2019-10-13 20:48:26 +00002004 if (!NullIsDefined) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01002005 const auto &DerefAA =
2006 A.getAAFor<AADereferenceable>(*this, getIRPosition());
Johannes Doerfertd82385b2019-10-13 20:48:26 +00002007 if (DerefAA.getAssumedDereferenceableBytes())
2008 return Change;
2009 }
2010
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002011 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002012
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05002013 DominatorTree *DT = nullptr;
2014 InformationCache &InfoCache = A.getInfoCache();
2015 if (const Function *Fn = getAnchorScope())
2016 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
2017
Johannes Doerfert1a746452019-10-20 22:28:49 -05002018 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002019 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002020 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
2021 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05002022 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002023 T.indicatePessimisticFixpoint();
2024 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002025 // Use abstract attribute information.
2026 const AANonNull::StateType &NS =
2027 static_cast<const AANonNull::StateType &>(AA.getState());
2028 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002029 }
2030 return T.isValidState();
2031 };
2032
2033 StateType T;
2034 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
2035 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002036 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002037
2038 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002039 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002040
2041 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002042 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002043};
2044
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002045/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002046struct AANonNullReturned final
2047 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002048 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002049 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002050
2051 /// See AbstractAttribute::trackStatistics()
2052 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2053};
2054
Hideto Ueno54869ec2019-07-15 06:49:04 +00002055/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002056struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002057 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
2058 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002059 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002060 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
2061 AANonNullImpl>(
2062 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002063
2064 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002065 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002066};
2067
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002068struct AANonNullCallSiteArgument final : AANonNullFloating {
2069 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002070
2071 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00002072 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002073};
Johannes Doerfert007153e2019-08-05 23:26:06 +00002074
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002075/// NonNull attribute for a call site return position.
2076struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002077 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
2078 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002079 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002080 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
2081 AANonNullImpl>(
2082 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002083
2084 /// See AbstractAttribute::trackStatistics()
2085 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2086};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002087
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002088/// ------------------------ No-Recurse Attributes ----------------------------
2089
2090struct AANoRecurseImpl : public AANoRecurse {
2091 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
2092
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002093 /// See AbstractAttribute::getAsStr()
2094 const std::string getAsStr() const override {
2095 return getAssumed() ? "norecurse" : "may-recurse";
2096 }
2097};
2098
2099struct AANoRecurseFunction final : AANoRecurseImpl {
2100 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2101
Hideto Ueno63f60662019-09-21 15:13:19 +00002102 /// See AbstractAttribute::initialize(...).
2103 void initialize(Attributor &A) override {
2104 AANoRecurseImpl::initialize(A);
2105 if (const Function *F = getAnchorScope())
Johannes Doerfert26d02b02019-12-30 16:15:38 -06002106 if (A.getInfoCache().getSccSize(*F) != 1)
2107 indicatePessimisticFixpoint();
Hideto Ueno63f60662019-09-21 15:13:19 +00002108 }
2109
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002110 /// See AbstractAttribute::updateImpl(...).
2111 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00002112
Johannes Doerfert26d02b02019-12-30 16:15:38 -06002113 // If all live call sites are known to be no-recurse, we are as well.
2114 auto CallSitePred = [&](AbstractCallSite ACS) {
2115 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(
2116 *this, IRPosition::function(*ACS.getInstruction()->getFunction()),
2117 /* TrackDependence */ false, DepClassTy::OPTIONAL);
2118 return NoRecurseAA.isKnownNoRecurse();
2119 };
2120 bool AllCallSitesKnown;
2121 if (A.checkForAllCallSites(CallSitePred, *this, true, AllCallSitesKnown)) {
2122 // If we know all call sites and all are known no-recurse, we are done.
2123 // If all known call sites, which might not be all that exist, are known
2124 // to be no-recurse, we are not done but we can continue to assume
2125 // no-recurse. If one of the call sites we have not visited will become
2126 // live, another update is triggered.
2127 if (AllCallSitesKnown)
2128 indicateOptimisticFixpoint();
2129 return ChangeStatus::UNCHANGED;
2130 }
2131
2132 // If the above check does not hold anymore we look at the calls.
Hideto Ueno63f60662019-09-21 15:13:19 +00002133 auto CheckForNoRecurse = [&](Instruction &I) {
2134 ImmutableCallSite ICS(&I);
2135 if (ICS.hasFnAttr(Attribute::NoRecurse))
2136 return true;
2137
2138 const auto &NoRecurseAA =
2139 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
2140 if (!NoRecurseAA.isAssumedNoRecurse())
2141 return false;
2142
2143 // Recursion to the same function
2144 if (ICS.getCalledFunction() == getAnchorScope())
2145 return false;
2146
2147 return true;
2148 };
2149
2150 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
2151 return indicatePessimisticFixpoint();
2152 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002153 }
2154
2155 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2156};
2157
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002158/// NoRecurse attribute deduction for a call sites.
2159struct AANoRecurseCallSite final : AANoRecurseImpl {
2160 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2161
2162 /// See AbstractAttribute::initialize(...).
2163 void initialize(Attributor &A) override {
2164 AANoRecurseImpl::initialize(A);
2165 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002166 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002167 indicatePessimisticFixpoint();
2168 }
2169
2170 /// See AbstractAttribute::updateImpl(...).
2171 ChangeStatus updateImpl(Attributor &A) override {
2172 // TODO: Once we have call site specific value information we can provide
2173 // call site specific liveness information and then it makes
2174 // sense to specialize attributes for call sites arguments instead of
2175 // redirecting requests to the callee argument.
2176 Function *F = getAssociatedFunction();
2177 const IRPosition &FnPos = IRPosition::function(*F);
2178 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
2179 return clampStateAndIndicateChange(
2180 getState(),
2181 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
2182 }
2183
2184 /// See AbstractAttribute::trackStatistics()
2185 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2186};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002187
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002188/// -------------------- Undefined-Behavior Attributes ------------------------
2189
2190struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2191 AAUndefinedBehaviorImpl(const IRPosition &IRP) : AAUndefinedBehavior(IRP) {}
2192
2193 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert5732f562019-12-24 19:25:08 -06002194 // through a pointer (i.e. also branches etc.)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002195 ChangeStatus updateImpl(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002196 const size_t UBPrevSize = KnownUBInsts.size();
2197 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002198
Johannes Doerfert5732f562019-12-24 19:25:08 -06002199 auto InspectMemAccessInstForUB = [&](Instruction &I) {
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002200 // Skip instructions that are already saved.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002201 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002202 return true;
2203
Hideto Uenoef4febd2019-12-29 17:34:08 +09002204 // If we reach here, we know we have an instruction
2205 // that accesses memory through a pointer operand,
2206 // for which getPointerOperand() should give it to us.
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06002207 const Value *PtrOp = getPointerOperand(&I, /* AllowVolatile */ true);
Hideto Uenoef4febd2019-12-29 17:34:08 +09002208 assert(PtrOp &&
2209 "Expected pointer operand of memory accessing instruction");
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002210
Johannes Doerfert5732f562019-12-24 19:25:08 -06002211 // A memory access through a pointer is considered UB
2212 // only if the pointer has constant null value.
2213 // TODO: Expand it to not only check constant values.
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002214 if (!isa<ConstantPointerNull>(PtrOp)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002215 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002216 return true;
2217 }
Johannes Doerfert5732f562019-12-24 19:25:08 -06002218 const Type *PtrTy = PtrOp->getType();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002219
Johannes Doerfert5732f562019-12-24 19:25:08 -06002220 // Because we only consider instructions inside functions,
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002221 // assume that a parent function exists.
2222 const Function *F = I.getFunction();
2223
Johannes Doerfert5732f562019-12-24 19:25:08 -06002224 // A memory access using constant null pointer is only considered UB
2225 // if null pointer is _not_ defined for the target platform.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002226 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()))
2227 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002228 else
Hideto Uenoef4febd2019-12-29 17:34:08 +09002229 KnownUBInsts.insert(&I);
2230 return true;
2231 };
2232
2233 auto InspectBrInstForUB = [&](Instruction &I) {
2234 // A conditional branch instruction is considered UB if it has `undef`
2235 // condition.
2236
2237 // Skip instructions that are already saved.
2238 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2239 return true;
2240
2241 // We know we have a branch instruction.
2242 auto BrInst = cast<BranchInst>(&I);
2243
2244 // Unconditional branches are never considered UB.
2245 if (BrInst->isUnconditional())
2246 return true;
2247
2248 // Either we stopped and the appropriate action was taken,
2249 // or we got back a simplified value to continue.
2250 Optional<Value *> SimplifiedCond =
2251 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2252 if (!SimplifiedCond.hasValue())
2253 return true;
2254 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002255 return true;
2256 };
2257
Johannes Doerfert5732f562019-12-24 19:25:08 -06002258 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
2259 {Instruction::Load, Instruction::Store,
2260 Instruction::AtomicCmpXchg,
Johannes Doerfert23f41f12020-01-12 01:09:22 -06002261 Instruction::AtomicRMW},
2262 /* CheckBBLivenessOnly */ true);
2263 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
2264 /* CheckBBLivenessOnly */ true);
Hideto Uenoef4febd2019-12-29 17:34:08 +09002265 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
2266 UBPrevSize != KnownUBInsts.size())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002267 return ChangeStatus::CHANGED;
2268 return ChangeStatus::UNCHANGED;
2269 }
2270
Hideto Uenoef4febd2019-12-29 17:34:08 +09002271 bool isKnownToCauseUB(Instruction *I) const override {
2272 return KnownUBInsts.count(I);
2273 }
2274
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002275 bool isAssumedToCauseUB(Instruction *I) const override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002276 // In simple words, if an instruction is not in the assumed to _not_
2277 // cause UB, then it is assumed UB (that includes those
2278 // in the KnownUBInsts set). The rest is boilerplate
2279 // is to ensure that it is one of the instructions we test
2280 // for UB.
2281
2282 switch (I->getOpcode()) {
2283 case Instruction::Load:
2284 case Instruction::Store:
2285 case Instruction::AtomicCmpXchg:
2286 case Instruction::AtomicRMW:
2287 return !AssumedNoUBInsts.count(I);
2288 case Instruction::Br: {
2289 auto BrInst = cast<BranchInst>(I);
2290 if (BrInst->isUnconditional())
2291 return false;
2292 return !AssumedNoUBInsts.count(I);
2293 } break;
2294 default:
2295 return false;
2296 }
2297 return false;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002298 }
2299
2300 ChangeStatus manifest(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002301 if (KnownUBInsts.empty())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002302 return ChangeStatus::UNCHANGED;
Hideto Uenoef4febd2019-12-29 17:34:08 +09002303 for (Instruction *I : KnownUBInsts)
Hideto Uenocb5eb132019-12-27 02:39:37 +09002304 A.changeToUnreachableAfterManifest(I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002305 return ChangeStatus::CHANGED;
2306 }
2307
2308 /// See AbstractAttribute::getAsStr()
2309 const std::string getAsStr() const override {
2310 return getAssumed() ? "undefined-behavior" : "no-ub";
2311 }
2312
Hideto Uenoef4febd2019-12-29 17:34:08 +09002313 /// Note: The correctness of this analysis depends on the fact that the
2314 /// following 2 sets will stop changing after some point.
2315 /// "Change" here means that their size changes.
2316 /// The size of each set is monotonically increasing
2317 /// (we only add items to them) and it is upper bounded by the number of
2318 /// instructions in the processed function (we can never save more
2319 /// elements in either set than this number). Hence, at some point,
2320 /// they will stop increasing.
2321 /// Consequently, at some point, both sets will have stopped
2322 /// changing, effectively making the analysis reach a fixpoint.
2323
2324 /// Note: These 2 sets are disjoint and an instruction can be considered
2325 /// one of 3 things:
2326 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
2327 /// the KnownUBInsts set.
2328 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
2329 /// has a reason to assume it).
2330 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
2331 /// could not find a reason to assume or prove that it can cause UB,
2332 /// hence it assumes it doesn't. We have a set for these instructions
2333 /// so that we don't reprocess them in every update.
2334 /// Note however that instructions in this set may cause UB.
2335
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002336protected:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002337 /// A set of all live instructions _known_ to cause UB.
2338 SmallPtrSet<Instruction *, 8> KnownUBInsts;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002339
2340private:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002341 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
2342 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
2343
2344 // Should be called on updates in which if we're processing an instruction
2345 // \p I that depends on a value \p V, one of the following has to happen:
2346 // - If the value is assumed, then stop.
2347 // - If the value is known but undef, then consider it UB.
2348 // - Otherwise, do specific processing with the simplified value.
2349 // We return None in the first 2 cases to signify that an appropriate
2350 // action was taken and the caller should stop.
2351 // Otherwise, we return the simplified value that the caller should
2352 // use for specific processing.
2353 Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
2354 Instruction *I) {
2355 const auto &ValueSimplifyAA =
2356 A.getAAFor<AAValueSimplify>(*this, IRPosition::value(*V));
2357 Optional<Value *> SimplifiedV =
2358 ValueSimplifyAA.getAssumedSimplifiedValue(A);
2359 if (!ValueSimplifyAA.isKnown()) {
2360 // Don't depend on assumed values.
2361 return llvm::None;
2362 }
2363 if (!SimplifiedV.hasValue()) {
2364 // If it is known (which we tested above) but it doesn't have a value,
2365 // then we can assume `undef` and hence the instruction is UB.
2366 KnownUBInsts.insert(I);
2367 return llvm::None;
2368 }
2369 Value *Val = SimplifiedV.getValue();
2370 if (isa<UndefValue>(Val)) {
2371 KnownUBInsts.insert(I);
2372 return llvm::None;
2373 }
2374 return Val;
2375 }
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002376};
2377
2378struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
2379 AAUndefinedBehaviorFunction(const IRPosition &IRP)
2380 : AAUndefinedBehaviorImpl(IRP) {}
2381
2382 /// See AbstractAttribute::trackStatistics()
2383 void trackStatistics() const override {
2384 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
2385 "Number of instructions known to have UB");
2386 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
Hideto Uenoef4febd2019-12-29 17:34:08 +09002387 KnownUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002388 }
2389};
2390
Hideto Ueno11d37102019-07-17 15:15:43 +00002391/// ------------------------ Will-Return Attributes ----------------------------
2392
Hideto Ueno11d37102019-07-17 15:15:43 +00002393// Helper function that checks whether a function has any cycle.
2394// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002395static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00002396 SmallPtrSet<BasicBlock *, 32> Visited;
2397
2398 // Traverse BB by dfs and check whether successor is already visited.
2399 for (BasicBlock *BB : depth_first(&F)) {
2400 Visited.insert(BB);
2401 for (auto *SuccBB : successors(BB)) {
2402 if (Visited.count(SuccBB))
2403 return true;
2404 }
2405 }
2406 return false;
2407}
2408
2409// Helper function that checks the function have a loop which might become an
2410// endless loop
2411// FIXME: Any cycle is regarded as endless loop for now.
2412// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002413static bool containsPossiblyEndlessLoop(Function *F) {
2414 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00002415}
2416
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002417struct AAWillReturnImpl : public AAWillReturn {
2418 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00002419
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002420 /// See AbstractAttribute::initialize(...).
2421 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002422 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00002423
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002424 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002425 if (containsPossiblyEndlessLoop(F))
2426 indicatePessimisticFixpoint();
2427 }
Hideto Ueno11d37102019-07-17 15:15:43 +00002428
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002429 /// See AbstractAttribute::updateImpl(...).
2430 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002431 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002432 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
2433 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
2434 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002435 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002436 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002437 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002438 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
2439 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002440 };
2441
2442 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
2443 return indicatePessimisticFixpoint();
2444
2445 return ChangeStatus::UNCHANGED;
2446 }
2447
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002448 /// See AbstractAttribute::getAsStr()
2449 const std::string getAsStr() const override {
2450 return getAssumed() ? "willreturn" : "may-noreturn";
2451 }
2452};
2453
2454struct AAWillReturnFunction final : AAWillReturnImpl {
2455 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2456
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002457 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002458 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002459};
Hideto Ueno11d37102019-07-17 15:15:43 +00002460
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002461/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002462struct AAWillReturnCallSite final : AAWillReturnImpl {
2463 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2464
2465 /// See AbstractAttribute::initialize(...).
2466 void initialize(Attributor &A) override {
2467 AAWillReturnImpl::initialize(A);
2468 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002469 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002470 indicatePessimisticFixpoint();
2471 }
2472
2473 /// See AbstractAttribute::updateImpl(...).
2474 ChangeStatus updateImpl(Attributor &A) override {
2475 // TODO: Once we have call site specific value information we can provide
2476 // call site specific liveness information and then it makes
2477 // sense to specialize attributes for call sites arguments instead of
2478 // redirecting requests to the callee argument.
2479 Function *F = getAssociatedFunction();
2480 const IRPosition &FnPos = IRPosition::function(*F);
2481 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
2482 return clampStateAndIndicateChange(
2483 getState(),
2484 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
2485 }
2486
2487 /// See AbstractAttribute::trackStatistics()
2488 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
2489};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002490
Pankaj Gode04945c92019-11-22 18:40:47 +05302491/// -------------------AAReachability Attribute--------------------------
2492
2493struct AAReachabilityImpl : AAReachability {
2494 AAReachabilityImpl(const IRPosition &IRP) : AAReachability(IRP) {}
2495
2496 const std::string getAsStr() const override {
2497 // TODO: Return the number of reachable queries.
2498 return "reachable";
2499 }
2500
2501 /// See AbstractAttribute::initialize(...).
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002502 void initialize(Attributor &A) override { indicatePessimisticFixpoint(); }
Pankaj Gode04945c92019-11-22 18:40:47 +05302503
2504 /// See AbstractAttribute::updateImpl(...).
2505 ChangeStatus updateImpl(Attributor &A) override {
2506 return indicatePessimisticFixpoint();
2507 }
2508};
2509
2510struct AAReachabilityFunction final : public AAReachabilityImpl {
2511 AAReachabilityFunction(const IRPosition &IRP) : AAReachabilityImpl(IRP) {}
2512
2513 /// See AbstractAttribute::trackStatistics()
2514 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); }
2515};
2516
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002517/// ------------------------ NoAlias Argument Attribute ------------------------
2518
Johannes Doerfert344d0382019-08-07 22:34:26 +00002519struct AANoAliasImpl : AANoAlias {
Johannes Doerfert32e98a72020-02-14 19:23:21 -06002520 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {
2521 assert(getAssociatedType()->isPointerTy() &&
2522 "Noalias is a pointer attribute");
2523 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002524
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002525 const std::string getAsStr() const override {
2526 return getAssumed() ? "noalias" : "may-alias";
2527 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002528};
2529
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002530/// NoAlias attribute for a floating value.
2531struct AANoAliasFloating final : AANoAliasImpl {
2532 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2533
Hideto Uenocbab3342019-08-29 05:52:00 +00002534 /// See AbstractAttribute::initialize(...).
2535 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002536 AANoAliasImpl::initialize(A);
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002537 Value *Val = &getAssociatedValue();
2538 do {
2539 CastInst *CI = dyn_cast<CastInst>(Val);
2540 if (!CI)
2541 break;
2542 Value *Base = CI->getOperand(0);
2543 if (Base->getNumUses() != 1)
2544 break;
2545 Val = Base;
2546 } while (true);
2547
Johannes Doerfert32e98a72020-02-14 19:23:21 -06002548 if (!Val->getType()->isPointerTy()) {
2549 indicatePessimisticFixpoint();
2550 return;
2551 }
2552
Johannes Doerfert72adda12019-10-10 05:33:21 +00002553 if (isa<AllocaInst>(Val))
2554 indicateOptimisticFixpoint();
Johannes Doerfert24ae77e2020-01-27 22:19:11 -06002555 else if (isa<ConstantPointerNull>(Val) &&
2556 !NullPointerIsDefined(getAnchorScope(),
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002557 Val->getType()->getPointerAddressSpace()))
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002558 indicateOptimisticFixpoint();
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002559 else if (Val != &getAssociatedValue()) {
2560 const auto &ValNoAliasAA =
2561 A.getAAFor<AANoAlias>(*this, IRPosition::value(*Val));
2562 if (ValNoAliasAA.isKnownNoAlias())
2563 indicateOptimisticFixpoint();
2564 }
Hideto Uenocbab3342019-08-29 05:52:00 +00002565 }
2566
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002567 /// See AbstractAttribute::updateImpl(...).
2568 ChangeStatus updateImpl(Attributor &A) override {
2569 // TODO: Implement this.
2570 return indicatePessimisticFixpoint();
2571 }
2572
2573 /// See AbstractAttribute::trackStatistics()
2574 void trackStatistics() const override {
2575 STATS_DECLTRACK_FLOATING_ATTR(noalias)
2576 }
2577};
2578
2579/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00002580struct AANoAliasArgument final
2581 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002582 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
2583 AANoAliasArgument(const IRPosition &IRP) : Base(IRP) {}
2584
Johannes Doerfert2baf0002020-01-12 00:18:07 -06002585 /// See AbstractAttribute::initialize(...).
2586 void initialize(Attributor &A) override {
2587 Base::initialize(A);
2588 // See callsite argument attribute and callee argument attribute.
2589 if (hasAttr({Attribute::ByVal}))
2590 indicateOptimisticFixpoint();
2591 }
2592
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002593 /// See AbstractAttribute::update(...).
2594 ChangeStatus updateImpl(Attributor &A) override {
2595 // We have to make sure no-alias on the argument does not break
2596 // synchronization when this is a callback argument, see also [1] below.
2597 // If synchronization cannot be affected, we delegate to the base updateImpl
2598 // function, otherwise we give up for now.
2599
2600 // If the function is no-sync, no-alias cannot break synchronization.
2601 const auto &NoSyncAA = A.getAAFor<AANoSync>(
2602 *this, IRPosition::function_scope(getIRPosition()));
2603 if (NoSyncAA.isAssumedNoSync())
2604 return Base::updateImpl(A);
2605
2606 // If the argument is read-only, no-alias cannot break synchronization.
2607 const auto &MemBehaviorAA =
2608 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
2609 if (MemBehaviorAA.isAssumedReadOnly())
2610 return Base::updateImpl(A);
2611
2612 // If the argument is never passed through callbacks, no-alias cannot break
2613 // synchronization.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002614 bool AllCallSitesKnown;
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002615 if (A.checkForAllCallSites(
2616 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002617 true, AllCallSitesKnown))
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002618 return Base::updateImpl(A);
2619
2620 // TODO: add no-alias but make sure it doesn't break synchronization by
2621 // introducing fake uses. See:
2622 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
2623 // International Workshop on OpenMP 2018,
2624 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
2625
2626 return indicatePessimisticFixpoint();
2627 }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002628
2629 /// See AbstractAttribute::trackStatistics()
2630 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
2631};
2632
2633struct AANoAliasCallSiteArgument final : AANoAliasImpl {
2634 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2635
Hideto Uenocbab3342019-08-29 05:52:00 +00002636 /// See AbstractAttribute::initialize(...).
2637 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00002638 // See callsite argument attribute and callee argument attribute.
2639 ImmutableCallSite ICS(&getAnchorValue());
2640 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
2641 indicateOptimisticFixpoint();
Johannes Doerfert24ae77e2020-01-27 22:19:11 -06002642 Value &Val = getAssociatedValue();
2643 if (isa<ConstantPointerNull>(Val) &&
2644 !NullPointerIsDefined(getAnchorScope(),
2645 Val.getType()->getPointerAddressSpace()))
2646 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002647 }
2648
Johannes Doerfert53992c72020-01-27 22:24:32 -06002649 /// Determine if the underlying value may alias with the call site argument
2650 /// \p OtherArgNo of \p ICS (= the underlying call site).
2651 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
2652 const AAMemoryBehavior &MemBehaviorAA,
2653 ImmutableCallSite ICS, unsigned OtherArgNo) {
2654 // We do not need to worry about aliasing with the underlying IRP.
2655 if (this->getArgNo() == (int)OtherArgNo)
2656 return false;
2657
2658 // If it is not a pointer or pointer vector we do not alias.
2659 const Value *ArgOp = ICS.getArgOperand(OtherArgNo);
2660 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
2661 return false;
2662
2663 auto &ICSArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
2664 *this, IRPosition::callsite_argument(ICS, OtherArgNo),
2665 /* TrackDependence */ false);
2666
2667 // If the argument is readnone, there is no read-write aliasing.
2668 if (ICSArgMemBehaviorAA.isAssumedReadNone()) {
2669 A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
2670 return false;
2671 }
2672
2673 // If the argument is readonly and the underlying value is readonly, there
2674 // is no read-write aliasing.
2675 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
2676 if (ICSArgMemBehaviorAA.isAssumedReadOnly() && IsReadOnly) {
2677 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
2678 A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
2679 return false;
2680 }
2681
2682 // We have to utilize actual alias analysis queries so we need the object.
2683 if (!AAR)
2684 AAR = A.getInfoCache().getAAResultsForFunction(*getAnchorScope());
2685
2686 // Try to rule it out at the call site.
2687 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
2688 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
2689 "callsite arguments: "
2690 << getAssociatedValue() << " " << *ArgOp << " => "
2691 << (IsAliasing ? "" : "no-") << "alias \n");
2692
2693 return IsAliasing;
2694 }
2695
2696 bool
2697 isKnownNoAliasDueToNoAliasPreservation(Attributor &A, AAResults *&AAR,
2698 const AAMemoryBehavior &MemBehaviorAA,
2699 const AANoAlias &NoAliasAA) {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002700 // We can deduce "noalias" if the following conditions hold.
2701 // (i) Associated value is assumed to be noalias in the definition.
2702 // (ii) Associated value is assumed to be no-capture in all the uses
2703 // possibly executed before this callsite.
2704 // (iii) There is no other pointer argument which could alias with the
2705 // value.
2706
Johannes Doerfert53992c72020-01-27 22:24:32 -06002707 bool AssociatedValueIsNoAliasAtDef = NoAliasAA.isAssumedNoAlias();
2708 if (!AssociatedValueIsNoAliasAtDef) {
2709 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
2710 << " is not no-alias at the definition\n");
2711 return false;
2712 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002713
Johannes Doerfert53992c72020-01-27 22:24:32 -06002714 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
2715 auto &NoCaptureAA =
2716 A.getAAFor<AANoCapture>(*this, VIRP, /* TrackDependence */ false);
2717 // Check whether the value is captured in the scope using AANoCapture.
2718 // FIXME: This is conservative though, it is better to look at CFG and
2719 // check only uses possibly executed before this callsite.
Johannes Doerfert72adda12019-10-10 05:33:21 +00002720 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2721 LLVM_DEBUG(
Johannes Doerfert53992c72020-01-27 22:24:32 -06002722 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
Johannes Doerfert72adda12019-10-10 05:33:21 +00002723 << " cannot be noalias as it is potentially captured\n");
Johannes Doerfert53992c72020-01-27 22:24:32 -06002724 return false;
Johannes Doerfert72adda12019-10-10 05:33:21 +00002725 }
Johannes Doerfert53992c72020-01-27 22:24:32 -06002726 A.recordDependence(NoCaptureAA, *this, DepClassTy::OPTIONAL);
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002727
Johannes Doerfert53992c72020-01-27 22:24:32 -06002728 // Check there is no other pointer argument which could alias with the
2729 // value passed at this call site.
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002730 // TODO: AbstractCallSite
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002731 ImmutableCallSite ICS(&getAnchorValue());
Johannes Doerfert53992c72020-01-27 22:24:32 -06002732 for (unsigned OtherArgNo = 0; OtherArgNo < ICS.getNumArgOperands();
2733 OtherArgNo++)
2734 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, ICS, OtherArgNo))
2735 return false;
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002736
Johannes Doerfert53992c72020-01-27 22:24:32 -06002737 return true;
2738 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002739
Johannes Doerfert53992c72020-01-27 22:24:32 -06002740 /// See AbstractAttribute::updateImpl(...).
2741 ChangeStatus updateImpl(Attributor &A) override {
2742 // If the argument is readnone we are done as there are no accesses via the
2743 // argument.
2744 auto &MemBehaviorAA =
2745 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(),
2746 /* TrackDependence */ false);
2747 if (MemBehaviorAA.isAssumedReadNone()) {
2748 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
2749 return ChangeStatus::UNCHANGED;
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002750 }
2751
Johannes Doerfert53992c72020-01-27 22:24:32 -06002752 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
2753 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, VIRP,
2754 /* TrackDependence */ false);
2755
2756 AAResults *AAR = nullptr;
2757 if (isKnownNoAliasDueToNoAliasPreservation(A, AAR, MemBehaviorAA,
2758 NoAliasAA)) {
2759 LLVM_DEBUG(
2760 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
2761 return ChangeStatus::UNCHANGED;
2762 }
2763
2764 return indicatePessimisticFixpoint();
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002765 }
2766
2767 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002768 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002769};
2770
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002771/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002772struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002773 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002774
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002775 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002776 virtual ChangeStatus updateImpl(Attributor &A) override {
2777
2778 auto CheckReturnValue = [&](Value &RV) -> bool {
2779 if (Constant *C = dyn_cast<Constant>(&RV))
2780 if (C->isNullValue() || isa<UndefValue>(C))
2781 return true;
2782
2783 /// For now, we can only deduce noalias if we have call sites.
2784 /// FIXME: add more support.
2785 ImmutableCallSite ICS(&RV);
2786 if (!ICS)
2787 return false;
2788
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002789 const IRPosition &RVPos = IRPosition::value(RV);
2790 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002791 if (!NoAliasAA.isAssumedNoAlias())
2792 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002793
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002794 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2795 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002796 };
2797
2798 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2799 return indicatePessimisticFixpoint();
2800
2801 return ChangeStatus::UNCHANGED;
2802 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002803
2804 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002805 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002806};
2807
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002808/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002809struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2810 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2811
2812 /// See AbstractAttribute::initialize(...).
2813 void initialize(Attributor &A) override {
2814 AANoAliasImpl::initialize(A);
2815 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002816 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002817 indicatePessimisticFixpoint();
2818 }
2819
2820 /// See AbstractAttribute::updateImpl(...).
2821 ChangeStatus updateImpl(Attributor &A) override {
2822 // TODO: Once we have call site specific value information we can provide
2823 // call site specific liveness information and then it makes
2824 // sense to specialize attributes for call sites arguments instead of
2825 // redirecting requests to the callee argument.
2826 Function *F = getAssociatedFunction();
2827 const IRPosition &FnPos = IRPosition::returned(*F);
2828 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2829 return clampStateAndIndicateChange(
2830 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2831 }
2832
2833 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002834 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002835};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002836
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002837/// -------------------AAIsDead Function Attribute-----------------------
2838
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002839struct AAIsDeadValueImpl : public AAIsDead {
2840 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002841
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002842 /// See AAIsDead::isAssumedDead().
2843 bool isAssumedDead() const override { return getAssumed(); }
2844
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002845 /// See AAIsDead::isKnownDead().
2846 bool isKnownDead() const override { return getKnown(); }
2847
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002848 /// See AAIsDead::isAssumedDead(BasicBlock *).
2849 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2850
2851 /// See AAIsDead::isKnownDead(BasicBlock *).
2852 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2853
2854 /// See AAIsDead::isAssumedDead(Instruction *I).
2855 bool isAssumedDead(const Instruction *I) const override {
2856 return I == getCtxI() && isAssumedDead();
2857 }
2858
2859 /// See AAIsDead::isKnownDead(Instruction *I).
2860 bool isKnownDead(const Instruction *I) const override {
Johannes Doerfert86509e82020-01-12 00:34:38 -06002861 return isAssumedDead(I) && getKnown();
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002862 }
2863
2864 /// See AbstractAttribute::getAsStr().
2865 const std::string getAsStr() const override {
2866 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2867 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002868
Johannes Doerfert86509e82020-01-12 00:34:38 -06002869 /// Check if all uses are assumed dead.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06002870 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
2871 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
2872 // Explicitly set the dependence class to required because we want a long
2873 // chain of N dependent instructions to be considered live as soon as one is
2874 // without going through N update cycles. This is not required for
2875 // correctness.
2876 return A.checkForAllUses(UsePred, *this, V, DepClassTy::REQUIRED);
Johannes Doerfert86509e82020-01-12 00:34:38 -06002877 }
2878
2879 /// Determine if \p I is assumed to be side-effect free.
2880 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
2881 if (!I || wouldInstructionBeTriviallyDead(I))
2882 return true;
2883
2884 auto *CB = dyn_cast<CallBase>(I);
2885 if (!CB || isa<IntrinsicInst>(CB))
2886 return false;
2887
2888 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
2889 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, CallIRP);
2890 if (!NoUnwindAA.isAssumedNoUnwind())
2891 return false;
2892
2893 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, CallIRP);
2894 if (!MemBehaviorAA.isAssumedReadOnly())
2895 return false;
2896
2897 return true;
2898 }
2899};
2900
2901struct AAIsDeadFloating : public AAIsDeadValueImpl {
2902 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2903
2904 /// See AbstractAttribute::initialize(...).
2905 void initialize(Attributor &A) override {
2906 if (isa<UndefValue>(getAssociatedValue())) {
2907 indicatePessimisticFixpoint();
2908 return;
2909 }
2910
2911 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
2912 if (!isAssumedSideEffectFree(A, I))
2913 indicatePessimisticFixpoint();
2914 }
2915
2916 /// See AbstractAttribute::updateImpl(...).
2917 ChangeStatus updateImpl(Attributor &A) override {
2918 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
2919 if (!isAssumedSideEffectFree(A, I))
2920 return indicatePessimisticFixpoint();
2921
Johannes Doerfert23f41f12020-01-12 01:09:22 -06002922 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002923 return indicatePessimisticFixpoint();
2924 return ChangeStatus::UNCHANGED;
2925 }
2926
2927 /// See AbstractAttribute::manifest(...).
2928 ChangeStatus manifest(Attributor &A) override {
2929 Value &V = getAssociatedValue();
Johannes Doerfert86509e82020-01-12 00:34:38 -06002930 if (auto *I = dyn_cast<Instruction>(&V)) {
2931 // If we get here we basically know the users are all dead. We check if
2932 // isAssumedSideEffectFree returns true here again because it might not be
2933 // the case and only the users are dead but the instruction (=call) is
2934 // still needed.
2935 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002936 A.deleteAfterManifest(*I);
2937 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002938 }
Johannes Doerfert86509e82020-01-12 00:34:38 -06002939 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002940 if (V.use_empty())
2941 return ChangeStatus::UNCHANGED;
2942
Johannes Doerfertb2c76002020-01-23 17:12:56 -06002943 bool UsedAssumedInformation = false;
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06002944 Optional<Constant *> C =
Johannes Doerfertb2c76002020-01-23 17:12:56 -06002945 getAssumedConstant(A, V, *this, UsedAssumedInformation);
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06002946 if (C.hasValue() && C.getValue())
Johannes Doerfertb2c76002020-01-23 17:12:56 -06002947 return ChangeStatus::UNCHANGED;
2948
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002949 UndefValue &UV = *UndefValue::get(V.getType());
Hideto Ueno34fe8d02019-12-30 17:08:48 +09002950 bool AnyChange = A.changeValueAfterManifest(V, UV);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002951 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2952 }
2953
2954 /// See AbstractAttribute::trackStatistics()
2955 void trackStatistics() const override {
2956 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2957 }
2958};
2959
2960struct AAIsDeadArgument : public AAIsDeadFloating {
2961 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2962
2963 /// See AbstractAttribute::initialize(...).
2964 void initialize(Attributor &A) override {
2965 if (!getAssociatedFunction()->hasExactDefinition())
2966 indicatePessimisticFixpoint();
2967 }
2968
Johannes Doerfert75133632019-10-10 01:39:16 -05002969 /// See AbstractAttribute::manifest(...).
2970 ChangeStatus manifest(Attributor &A) override {
2971 ChangeStatus Changed = AAIsDeadFloating::manifest(A);
2972 Argument &Arg = *getAssociatedArgument();
Johannes Doerfert89c2e732019-10-30 17:20:20 -05002973 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
Johannes Doerfert75133632019-10-10 01:39:16 -05002974 if (A.registerFunctionSignatureRewrite(
2975 Arg, /* ReplacementTypes */ {},
2976 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{},
2977 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{}))
2978 return ChangeStatus::CHANGED;
2979 return Changed;
2980 }
2981
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002982 /// See AbstractAttribute::trackStatistics()
2983 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2984};
2985
2986struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2987 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2988
2989 /// See AbstractAttribute::initialize(...).
2990 void initialize(Attributor &A) override {
2991 if (isa<UndefValue>(getAssociatedValue()))
2992 indicatePessimisticFixpoint();
2993 }
2994
2995 /// See AbstractAttribute::updateImpl(...).
2996 ChangeStatus updateImpl(Attributor &A) override {
2997 // TODO: Once we have call site specific value information we can provide
2998 // call site specific liveness information and then it makes
2999 // sense to specialize attributes for call sites arguments instead of
3000 // redirecting requests to the callee argument.
3001 Argument *Arg = getAssociatedArgument();
3002 if (!Arg)
3003 return indicatePessimisticFixpoint();
3004 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3005 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
3006 return clampStateAndIndicateChange(
3007 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
3008 }
3009
3010 /// See AbstractAttribute::manifest(...).
3011 ChangeStatus manifest(Attributor &A) override {
3012 CallBase &CB = cast<CallBase>(getAnchorValue());
3013 Use &U = CB.getArgOperandUse(getArgNo());
3014 assert(!isa<UndefValue>(U.get()) &&
3015 "Expected undef values to be filtered out!");
3016 UndefValue &UV = *UndefValue::get(U->getType());
3017 if (A.changeUseAfterManifest(U, UV))
3018 return ChangeStatus::CHANGED;
3019 return ChangeStatus::UNCHANGED;
3020 }
3021
3022 /// See AbstractAttribute::trackStatistics()
3023 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
3024};
3025
Johannes Doerfert86509e82020-01-12 00:34:38 -06003026struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
3027 AAIsDeadCallSiteReturned(const IRPosition &IRP)
3028 : AAIsDeadFloating(IRP), IsAssumedSideEffectFree(true) {}
3029
3030 /// See AAIsDead::isAssumedDead().
3031 bool isAssumedDead() const override {
3032 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
3033 }
3034
Johannes Doerfert86509e82020-01-12 00:34:38 -06003035 /// See AbstractAttribute::initialize(...).
3036 void initialize(Attributor &A) override {
3037 if (isa<UndefValue>(getAssociatedValue())) {
3038 indicatePessimisticFixpoint();
3039 return;
3040 }
3041
3042 // We track this separately as a secondary state.
3043 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
3044 }
3045
3046 /// See AbstractAttribute::updateImpl(...).
3047 ChangeStatus updateImpl(Attributor &A) override {
3048 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3049 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
3050 IsAssumedSideEffectFree = false;
3051 Changed = ChangeStatus::CHANGED;
3052 }
3053
Johannes Doerfert23f41f12020-01-12 01:09:22 -06003054 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
Johannes Doerfert86509e82020-01-12 00:34:38 -06003055 return indicatePessimisticFixpoint();
3056 return Changed;
3057 }
3058
3059 /// See AbstractAttribute::manifest(...).
3060 ChangeStatus manifest(Attributor &A) override {
3061 if (auto *CI = dyn_cast<CallInst>(&getAssociatedValue()))
3062 if (CI->isMustTailCall())
3063 return ChangeStatus::UNCHANGED;
3064 return AAIsDeadFloating::manifest(A);
3065 }
3066
3067 /// See AbstractAttribute::trackStatistics()
3068 void trackStatistics() const override {
3069 if (IsAssumedSideEffectFree)
3070 STATS_DECLTRACK_CSRET_ATTR(IsDead)
3071 else
3072 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
3073 }
3074
3075 /// See AbstractAttribute::getAsStr().
3076 const std::string getAsStr() const override {
3077 return isAssumedDead()
3078 ? "assumed-dead"
3079 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
3080 }
3081
3082private:
3083 bool IsAssumedSideEffectFree;
3084};
3085
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003086struct AAIsDeadReturned : public AAIsDeadValueImpl {
3087 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
3088
3089 /// See AbstractAttribute::updateImpl(...).
3090 ChangeStatus updateImpl(Attributor &A) override {
3091
Johannes Doerfertb70297a2020-02-14 10:34:31 -06003092 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
3093 {Instruction::Ret});
3094
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003095 auto PredForCallSite = [&](AbstractCallSite ACS) {
Johannes Doerfert23f41f12020-01-12 01:09:22 -06003096 if (ACS.isCallbackCall() || !ACS.getInstruction())
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003097 return false;
Johannes Doerfert23f41f12020-01-12 01:09:22 -06003098 return areAllUsesAssumedDead(A, *ACS.getInstruction());
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003099 };
3100
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06003101 bool AllCallSitesKnown;
3102 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
3103 AllCallSitesKnown))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003104 return indicatePessimisticFixpoint();
3105
3106 return ChangeStatus::UNCHANGED;
3107 }
3108
3109 /// See AbstractAttribute::manifest(...).
3110 ChangeStatus manifest(Attributor &A) override {
3111 // TODO: Rewrite the signature to return void?
3112 bool AnyChange = false;
3113 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
3114 auto RetInstPred = [&](Instruction &I) {
3115 ReturnInst &RI = cast<ReturnInst>(I);
Johannes Doerfertb2c76002020-01-23 17:12:56 -06003116 if (auto *CI = dyn_cast<CallInst>(RI.getReturnValue()))
3117 if (CI->isMustTailCall())
3118 return true;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003119 if (!isa<UndefValue>(RI.getReturnValue()))
3120 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
3121 return true;
3122 };
3123 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
3124 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
3125 }
3126
3127 /// See AbstractAttribute::trackStatistics()
3128 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
3129};
3130
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003131struct AAIsDeadFunction : public AAIsDead {
3132 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
3133
3134 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003135 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003136 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003137 if (F && !F->isDeclaration()) {
3138 ToBeExploredFrom.insert(&F->getEntryBlock().front());
3139 assumeLive(A, F->getEntryBlock());
3140 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003141 }
3142
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003143 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003144 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003145 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003146 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003147 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
3148 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003149 }
3150
3151 /// See AbstractAttribute::manifest(...).
3152 ChangeStatus manifest(Attributor &A) override {
3153 assert(getState().isValidState() &&
3154 "Attempted to manifest an invalid state!");
3155
3156 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003157 Function &F = *getAssociatedFunction();
3158
3159 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003160 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003161 return ChangeStatus::CHANGED;
3162 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00003163
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003164 // Flag to determine if we can change an invoke to a call assuming the
3165 // callee is nounwind. This is not possible if the personality of the
3166 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00003167 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003168
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003169 KnownDeadEnds.set_union(ToBeExploredFrom);
3170 for (const Instruction *DeadEndI : KnownDeadEnds) {
3171 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003172 if (!CB)
3173 continue;
3174 const auto &NoReturnAA =
3175 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05003176 bool MayReturn = !NoReturnAA.isAssumedNoReturn();
3177 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003178 continue;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003179
Johannes Doerferta4088c72020-01-07 16:01:57 -06003180 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
3181 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
3182 else
3183 A.changeToUnreachableAfterManifest(
3184 const_cast<Instruction *>(DeadEndI->getNextNode()));
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003185 HasChanged = ChangeStatus::CHANGED;
3186 }
3187
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003188 for (BasicBlock &BB : F)
3189 if (!AssumedLiveBlocks.count(&BB))
3190 A.deleteAfterManifest(BB);
3191
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003192 return HasChanged;
3193 }
3194
3195 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003196 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003197
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003198 /// See AbstractAttribute::trackStatistics()
3199 void trackStatistics() const override {}
3200
3201 /// Returns true if the function is assumed dead.
3202 bool isAssumedDead() const override { return false; }
3203
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06003204 /// See AAIsDead::isKnownDead().
3205 bool isKnownDead() const override { return false; }
3206
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003207 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003208 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003209 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003210 "BB must be in the same anchor scope function.");
3211
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003212 if (!getAssumed())
3213 return false;
3214 return !AssumedLiveBlocks.count(BB);
3215 }
3216
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003217 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003218 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003219 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003220 }
3221
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003222 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003223 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003224 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003225 "Instruction must be in the same anchor scope function.");
3226
Stefan Stipanovic7849e412019-08-03 15:27:41 +00003227 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003228 return false;
3229
3230 // If it is not in AssumedLiveBlocks then it for sure dead.
3231 // Otherwise, it can still be after noreturn call in a live block.
3232 if (!AssumedLiveBlocks.count(I->getParent()))
3233 return true;
3234
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003235 // If it is not after a liveness barrier it is live.
3236 const Instruction *PrevI = I->getPrevNode();
3237 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003238 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003239 return true;
3240 PrevI = PrevI->getPrevNode();
3241 }
3242 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003243 }
3244
3245 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003246 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003247 return getKnown() && isAssumedDead(I);
3248 }
3249
Johannes Doerfert924d2132019-08-05 21:34:45 +00003250 /// Determine if \p F might catch asynchronous exceptions.
3251 static bool mayCatchAsynchronousExceptions(const Function &F) {
3252 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
3253 }
3254
Johannes Doerfert2f622062019-09-04 16:35:20 +00003255 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
3256 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003257 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00003258 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003259 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003260
3261 // We assume that all of BB is (probably) live now and if there are calls to
3262 // internal functions we will assume that those are now live as well. This
3263 // is a performance optimization for blocks with calls to a lot of internal
3264 // functions. It can however cause dead functions to be treated as live.
3265 for (const Instruction &I : BB)
3266 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
3267 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00003268 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00003269 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003270 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003271 }
3272
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003273 /// Collection of instructions that need to be explored again, e.g., we
3274 /// did assume they do not transfer control to (one of their) successors.
3275 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003276
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003277 /// Collection of instructions that are known to not transfer control.
3278 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
3279
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003280 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00003281 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003282};
3283
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003284static bool
3285identifyAliveSuccessors(Attributor &A, const CallBase &CB,
3286 AbstractAttribute &AA,
3287 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3288 const IRPosition &IPos = IRPosition::callsite_function(CB);
3289
3290 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
3291 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003292 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003293 if (CB.isTerminator())
3294 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
3295 else
3296 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003297 return false;
3298}
3299
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003300static bool
3301identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
3302 AbstractAttribute &AA,
3303 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3304 bool UsedAssumedInformation =
3305 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00003306
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003307 // First, determine if we can change an invoke to a call assuming the
3308 // callee is nounwind. This is not possible if the personality of the
3309 // function allows to catch asynchronous exceptions.
3310 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
3311 AliveSuccessors.push_back(&II.getUnwindDest()->front());
3312 } else {
3313 const IRPosition &IPos = IRPosition::callsite_function(II);
3314 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003315 if (AANoUnw.isAssumedNoUnwind()) {
3316 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
3317 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003318 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003319 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003320 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003321 return UsedAssumedInformation;
3322}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003323
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003324static bool
3325identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
3326 AbstractAttribute &AA,
3327 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3328 bool UsedAssumedInformation = false;
3329 if (BI.getNumSuccessors() == 1) {
3330 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3331 } else {
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06003332 Optional<ConstantInt *> CI = getAssumedConstantInt(
3333 A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003334 if (!CI.hasValue()) {
3335 // No value yet, assume both edges are dead.
3336 } else if (CI.getValue()) {
3337 const BasicBlock *SuccBB =
3338 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
3339 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003340 } else {
3341 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3342 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003343 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003344 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003345 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003346 return UsedAssumedInformation;
3347}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003348
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003349static bool
3350identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
3351 AbstractAttribute &AA,
3352 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003353 bool UsedAssumedInformation = false;
3354 Optional<ConstantInt *> CI =
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06003355 getAssumedConstantInt(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003356 if (!CI.hasValue()) {
3357 // No value yet, assume all edges are dead.
3358 } else if (CI.getValue()) {
3359 for (auto &CaseIt : SI.cases()) {
3360 if (CaseIt.getCaseValue() == CI.getValue()) {
3361 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003362 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003363 }
3364 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05003365 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003366 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003367 } else {
3368 for (const BasicBlock *SuccBB : successors(SI.getParent()))
3369 AliveSuccessors.push_back(&SuccBB->front());
3370 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003371 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003372}
3373
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003374ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003375 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003376
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003377 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
3378 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003379 << ToBeExploredFrom.size() << " exploration points and "
3380 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003381
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003382 // Copy and clear the list of instructions we need to explore from. It is
3383 // refilled with instructions the next update has to look at.
3384 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
3385 ToBeExploredFrom.end());
3386 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003387
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003388 SmallVector<const Instruction *, 8> AliveSuccessors;
3389 while (!Worklist.empty()) {
3390 const Instruction *I = Worklist.pop_back_val();
3391 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003392
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003393 AliveSuccessors.clear();
3394
3395 bool UsedAssumedInformation = false;
3396 switch (I->getOpcode()) {
3397 // TODO: look for (assumed) UB to backwards propagate "deadness".
3398 default:
3399 if (I->isTerminator()) {
3400 for (const BasicBlock *SuccBB : successors(I->getParent()))
3401 AliveSuccessors.push_back(&SuccBB->front());
3402 } else {
3403 AliveSuccessors.push_back(I->getNextNode());
3404 }
3405 break;
3406 case Instruction::Call:
3407 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
3408 *this, AliveSuccessors);
3409 break;
3410 case Instruction::Invoke:
3411 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
3412 *this, AliveSuccessors);
3413 break;
3414 case Instruction::Br:
3415 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
3416 *this, AliveSuccessors);
3417 break;
3418 case Instruction::Switch:
3419 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
3420 *this, AliveSuccessors);
3421 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00003422 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003423
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003424 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003425 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003426 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003427 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003428 if (AliveSuccessors.empty() ||
3429 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
3430 KnownDeadEnds.insert(I);
3431 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003432
3433 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
3434 << AliveSuccessors.size() << " UsedAssumedInformation: "
3435 << UsedAssumedInformation << "\n");
3436
3437 for (const Instruction *AliveSuccessor : AliveSuccessors) {
3438 if (!I->isTerminator()) {
3439 assert(AliveSuccessors.size() == 1 &&
3440 "Non-terminator expected to have a single successor!");
3441 Worklist.push_back(AliveSuccessor);
3442 } else {
3443 if (assumeLive(A, *AliveSuccessor->getParent()))
3444 Worklist.push_back(AliveSuccessor);
3445 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00003446 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003447 }
3448
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003449 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003450
Johannes Doerfertd6207812019-08-07 22:32:38 +00003451 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003452 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003453 // "invalid" and all queries to be answered conservatively without lookups.
3454 // To be in this state we have to (1) finished the exploration and (3) not
3455 // discovered any non-trivial dead end and (2) not ruled unreachable code
3456 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003457 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003458 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
3459 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
3460 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
3461 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003462 return indicatePessimisticFixpoint();
3463 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003464}
3465
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003466/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003467struct AAIsDeadCallSite final : AAIsDeadFunction {
3468 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003469
3470 /// See AbstractAttribute::initialize(...).
3471 void initialize(Attributor &A) override {
3472 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003473 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003474 // sense to specialize attributes for call sites instead of
3475 // redirecting requests to the callee.
3476 llvm_unreachable("Abstract attributes for liveness are not "
3477 "supported for call sites yet!");
3478 }
3479
3480 /// See AbstractAttribute::updateImpl(...).
3481 ChangeStatus updateImpl(Attributor &A) override {
3482 return indicatePessimisticFixpoint();
3483 }
3484
3485 /// See AbstractAttribute::trackStatistics()
3486 void trackStatistics() const override {}
3487};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003488
Hideto Ueno19c07af2019-07-23 08:16:17 +00003489/// -------------------- Dereferenceable Argument Attribute --------------------
3490
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003491template <>
3492ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
3493 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05003494 ChangeStatus CS0 =
3495 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
3496 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003497 return CS0 | CS1;
3498}
3499
Hideto Ueno70576ca2019-08-22 14:18:29 +00003500struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003501 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003502 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00003503
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003504 void initialize(Attributor &A) override {
3505 SmallVector<Attribute, 4> Attrs;
3506 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
3507 Attrs);
3508 for (const Attribute &Attr : Attrs)
3509 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
3510
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003511 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition(),
3512 /* TrackDependence */ false);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003513
3514 const IRPosition &IRP = this->getIRPosition();
3515 bool IsFnInterface = IRP.isFnInterfaceKind();
3516 const Function *FnScope = IRP.getAnchorScope();
3517 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
3518 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003519 }
3520
Hideto Ueno19c07af2019-07-23 08:16:17 +00003521 /// See AbstractAttribute::getState()
3522 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00003523 StateType &getState() override { return *this; }
3524 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003525 /// }
3526
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003527 /// Helper function for collecting accessed bytes in must-be-executed-context
3528 void addAccessedBytesForUse(Attributor &A, const Use *U,
3529 const Instruction *I) {
3530 const Value *UseV = U->get();
3531 if (!UseV->getType()->isPointerTy())
3532 return;
3533
3534 Type *PtrTy = UseV->getType();
3535 const DataLayout &DL = A.getDataLayout();
3536 int64_t Offset;
3537 if (const Value *Base = getBasePointerOfAccessPointerOperand(
3538 I, Offset, DL, /*AllowNonInbounds*/ true)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09003539 if (Base == &getAssociatedValue() &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06003540 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003541 uint64_t Size = DL.getTypeStoreSize(PtrTy->getPointerElementType());
3542 addAccessedBytes(Offset, Size);
3543 }
3544 }
3545 return;
3546 }
3547
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003548 /// See AAFromMustBeExecutedContext
3549 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3550 bool IsNonNull = false;
3551 bool TrackUse = false;
3552 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
3553 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003554
3555 addAccessedBytesForUse(A, U, I);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003556 takeKnownDerefBytesMaximum(DerefBytes);
3557 return TrackUse;
3558 }
3559
Hideto Uenodfedae52019-11-29 06:45:07 +00003560 /// See AbstractAttribute::manifest(...).
3561 ChangeStatus manifest(Attributor &A) override {
3562 ChangeStatus Change = AADereferenceable::manifest(A);
3563 if (isAssumedNonNull() && hasAttr(Attribute::DereferenceableOrNull)) {
3564 removeAttrs({Attribute::DereferenceableOrNull});
3565 return ChangeStatus::CHANGED;
3566 }
3567 return Change;
3568 }
3569
Johannes Doerferteccdf082019-08-05 23:35:12 +00003570 void getDeducedAttributes(LLVMContext &Ctx,
3571 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00003572 // TODO: Add *_globally support
3573 if (isAssumedNonNull())
3574 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
3575 Ctx, getAssumedDereferenceableBytes()));
3576 else
3577 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
3578 Ctx, getAssumedDereferenceableBytes()));
3579 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003580
3581 /// See AbstractAttribute::getAsStr().
3582 const std::string getAsStr() const override {
3583 if (!getAssumedDereferenceableBytes())
3584 return "unknown-dereferenceable";
3585 return std::string("dereferenceable") +
3586 (isAssumedNonNull() ? "" : "_or_null") +
3587 (isAssumedGlobal() ? "_globally" : "") + "<" +
3588 std::to_string(getKnownDereferenceableBytes()) + "-" +
3589 std::to_string(getAssumedDereferenceableBytes()) + ">";
3590 }
3591};
3592
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003593/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003594struct AADereferenceableFloating
3595 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
3596 using Base =
3597 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
3598 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00003599
3600 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003601 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003602 ChangeStatus Change = Base::updateImpl(A);
3603
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003604 const DataLayout &DL = A.getDataLayout();
3605
3606 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
3607 unsigned IdxWidth =
3608 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
3609 APInt Offset(IdxWidth, 0);
3610 const Value *Base =
3611 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
3612
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003613 const auto &AA =
3614 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003615 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003616 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003617 // Use IR information if we did not strip anything.
3618 // TODO: track globally.
3619 bool CanBeNull;
3620 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
3621 T.GlobalState.indicatePessimisticFixpoint();
3622 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003623 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003624 DerefBytes = DS.DerefBytesState.getAssumed();
3625 T.GlobalState &= DS.GlobalState;
3626 }
3627
Hideto Ueno188f9a32020-01-15 15:25:52 +09003628 // TODO: Use `AAConstantRange` to infer dereferenceable bytes.
3629
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003630 // For now we do not try to "increase" dereferenceability due to negative
3631 // indices as we first have to come up with code to deal with loops and
3632 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00003633 int64_t OffsetSExt = Offset.getSExtValue();
3634 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00003635 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003636
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003637 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00003638 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003639
Johannes Doerfert785fad32019-08-23 17:29:23 +00003640 if (this == &AA) {
3641 if (!Stripped) {
3642 // If nothing was stripped IR information is all we got.
3643 T.takeKnownDerefBytesMaximum(
3644 std::max(int64_t(0), DerefBytes - OffsetSExt));
3645 T.indicatePessimisticFixpoint();
3646 } else if (OffsetSExt > 0) {
3647 // If something was stripped but there is circular reasoning we look
3648 // for the offset. If it is positive we basically decrease the
3649 // dereferenceable bytes in a circluar loop now, which will simply
3650 // drive them down to the known value in a very slow way which we
3651 // can accelerate.
3652 T.indicatePessimisticFixpoint();
3653 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003654 }
3655
3656 return T.isValidState();
3657 };
3658
3659 DerefState T;
3660 if (!genericValueTraversal<AADereferenceable, DerefState>(
3661 A, getIRPosition(), *this, T, VisitValueCB))
3662 return indicatePessimisticFixpoint();
3663
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003664 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003665 }
3666
3667 /// See AbstractAttribute::trackStatistics()
3668 void trackStatistics() const override {
3669 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
3670 }
3671};
3672
3673/// Dereferenceable attribute for a return value.
3674struct AADereferenceableReturned final
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003675 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003676 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003677 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>(
3678 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003679
3680 /// See AbstractAttribute::trackStatistics()
3681 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003682 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003683 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003684};
3685
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003686/// Dereferenceable attribute for an argument
3687struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003688 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003689 AADereferenceable, AADereferenceableImpl> {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003690 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003691 AADereferenceable, AADereferenceableImpl>;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003692 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003693
3694 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003695 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00003696 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
3697 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003698};
3699
Hideto Ueno19c07af2019-07-23 08:16:17 +00003700/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003701struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003702 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003703 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003704
3705 /// See AbstractAttribute::trackStatistics()
3706 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003707 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003708 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003709};
3710
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003711/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003712struct AADereferenceableCallSiteReturned final
3713 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3714 AADereferenceable, AADereferenceableImpl> {
3715 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3716 AADereferenceable, AADereferenceableImpl>;
3717 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003718
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003719 /// See AbstractAttribute::trackStatistics()
3720 void trackStatistics() const override {
3721 STATS_DECLTRACK_CS_ATTR(dereferenceable);
3722 }
3723};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003724
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003725// ------------------------ Align Argument Attribute ------------------------
3726
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003727static unsigned int getKnownAlignForUse(Attributor &A,
3728 AbstractAttribute &QueryingAA,
3729 Value &AssociatedValue, const Use *U,
3730 const Instruction *I, bool &TrackUse) {
Hideto Ueno78a75022019-11-26 07:51:59 +00003731 // We need to follow common pointer manipulation uses to the accesses they
3732 // feed into.
3733 if (isa<CastInst>(I)) {
Johannes Doerfertc90681b2020-01-02 16:41:17 -06003734 // Follow all but ptr2int casts.
3735 TrackUse = !isa<PtrToIntInst>(I);
Hideto Ueno78a75022019-11-26 07:51:59 +00003736 return 0;
3737 }
3738 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
3739 if (GEP->hasAllConstantIndices()) {
3740 TrackUse = true;
3741 return 0;
3742 }
3743 }
3744
3745 unsigned Alignment = 0;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003746 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
3747 if (ICS.isBundleOperand(U) || ICS.isCallee(U))
3748 return 0;
3749
3750 unsigned ArgNo = ICS.getArgumentNo(U);
3751 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
3752 // As long as we only use known information there is no need to track
3753 // dependences here.
3754 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP,
3755 /* TrackDependence */ false);
Hideto Ueno78a75022019-11-26 07:51:59 +00003756 Alignment = AlignAA.getKnownAlign();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003757 }
3758
Hideto Ueno78a75022019-11-26 07:51:59 +00003759 const Value *UseV = U->get();
Johannes Doerfert30ae8592020-01-10 12:13:10 -06003760 if (auto *SI = dyn_cast<StoreInst>(I)) {
3761 if (SI->getPointerOperand() == UseV)
3762 Alignment = SI->getAlignment();
3763 } else if (auto *LI = dyn_cast<LoadInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003764 Alignment = LI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003765
Hideto Ueno78a75022019-11-26 07:51:59 +00003766 if (Alignment <= 1)
3767 return 0;
3768
3769 auto &DL = A.getDataLayout();
3770 int64_t Offset;
3771
3772 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
3773 if (Base == &AssociatedValue) {
3774 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
3775 // So we can say that the maximum power of two which is a divisor of
3776 // gcd(Offset, Alignment) is an alignment.
3777
3778 uint32_t gcd =
3779 greatestCommonDivisor(uint32_t(abs((int32_t)Offset)), Alignment);
3780 Alignment = llvm::PowerOf2Floor(gcd);
3781 }
3782 }
3783
3784 return Alignment;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003785}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003786struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003787 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003788
Johannes Doerfert234eda52019-08-16 19:51:23 +00003789 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003790 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003791 SmallVector<Attribute, 4> Attrs;
3792 getAttrs({Attribute::Alignment}, Attrs);
3793 for (const Attribute &Attr : Attrs)
3794 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003795
3796 if (getIRPosition().isFnInterfaceKind() &&
3797 (!getAssociatedFunction() ||
3798 !getAssociatedFunction()->hasExactDefinition()))
3799 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003800 }
3801
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003802 /// See AbstractAttribute::manifest(...).
3803 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003804 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003805
3806 // Check for users that allow alignment annotations.
Johannes Doerferta801ee82020-02-19 16:52:16 -06003807 Value &AssociatedValue = getAssociatedValue();
3808 for (const Use &U : AssociatedValue.uses()) {
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003809 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
Johannes Doerferta801ee82020-02-19 16:52:16 -06003810 if (SI->getPointerOperand() == &AssociatedValue)
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003811 if (SI->getAlignment() < getAssumedAlign()) {
3812 STATS_DECLTRACK(AAAlign, Store,
James Hendersond68904f2020-01-06 10:15:44 +00003813 "Number of times alignment added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00003814 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert30179d72020-01-12 00:25:45 -06003815 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003816 }
3817 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
Johannes Doerferta801ee82020-02-19 16:52:16 -06003818 if (LI->getPointerOperand() == &AssociatedValue)
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003819 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00003820 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003821 STATS_DECLTRACK(AAAlign, Load,
James Hendersond68904f2020-01-06 10:15:44 +00003822 "Number of times alignment added to a load");
Johannes Doerfert30179d72020-01-12 00:25:45 -06003823 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003824 }
3825 }
3826 }
3827
Johannes Doerfert30179d72020-01-12 00:25:45 -06003828 ChangeStatus Changed = AAAlign::manifest(A);
3829
3830 MaybeAlign InheritAlign =
3831 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3832 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3833 return LoadStoreChanged;
3834 return Changed | LoadStoreChanged;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003835 }
3836
Johannes Doerfert81df4522019-08-30 15:22:28 +00003837 // TODO: Provide a helper to determine the implied ABI alignment and check in
3838 // the existing manifest method and a new one for AAAlignImpl that value
3839 // to avoid making the alignment explicit if it did not improve.
3840
3841 /// See AbstractAttribute::getDeducedAttributes
3842 virtual void
3843 getDeducedAttributes(LLVMContext &Ctx,
3844 SmallVectorImpl<Attribute> &Attrs) const override {
3845 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00003846 Attrs.emplace_back(
3847 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00003848 }
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003849 /// See AAFromMustBeExecutedContext
3850 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3851 bool TrackUse = false;
3852
Hideto Ueno4ecf2552019-12-12 13:42:40 +00003853 unsigned int KnownAlign =
3854 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003855 takeKnownMaximum(KnownAlign);
3856
3857 return TrackUse;
3858 }
Johannes Doerfert81df4522019-08-30 15:22:28 +00003859
3860 /// See AbstractAttribute::getAsStr().
3861 const std::string getAsStr() const override {
3862 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
3863 "-" + std::to_string(getAssumedAlign()) + ">")
3864 : "unknown-align";
3865 }
3866};
3867
3868/// Align attribute for a floating value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003869struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
3870 using Base = AAFromMustBeExecutedContext<AAAlign, AAAlignImpl>;
3871 AAAlignFloating(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert81df4522019-08-30 15:22:28 +00003872
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003873 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00003874 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003875 Base::updateImpl(A);
3876
Johannes Doerfert234eda52019-08-16 19:51:23 +00003877 const DataLayout &DL = A.getDataLayout();
3878
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003879 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3880 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003881 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3882 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003883 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003884 const MaybeAlign PA = V.getPointerAlignment(DL);
3885 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003886 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003887 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003888 // Use abstract attribute information.
3889 const AAAlign::StateType &DS =
3890 static_cast<const AAAlign::StateType &>(AA.getState());
3891 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003892 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003893 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003894 };
3895
3896 StateType T;
3897 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3898 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003899 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003900
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003901 // TODO: If we know we visited all incoming values, thus no are assumed
3902 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003903 return clampStateAndIndicateChange(getState(), T);
3904 }
3905
3906 /// See AbstractAttribute::trackStatistics()
3907 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3908};
3909
3910/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003911struct AAAlignReturned final
3912 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003913 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003914 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003915
3916 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003917 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003918};
3919
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003920/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003921struct AAAlignArgument final
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003922 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3923 AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003924 AAAlignArgument(const IRPosition &IRP)
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003925 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3926 AAAlignImpl>(
3927 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003928
3929 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003930 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003931};
3932
Johannes Doerfert234eda52019-08-16 19:51:23 +00003933struct AAAlignCallSiteArgument final : AAAlignFloating {
3934 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003935
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003936 /// See AbstractAttribute::manifest(...).
3937 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003938 ChangeStatus Changed = AAAlignImpl::manifest(A);
3939 MaybeAlign InheritAlign =
3940 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3941 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3942 Changed = ChangeStatus::UNCHANGED;
3943 return Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003944 }
3945
Johannes Doerfertdada8132019-12-31 01:27:50 -06003946 /// See AbstractAttribute::updateImpl(Attributor &A).
3947 ChangeStatus updateImpl(Attributor &A) override {
3948 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
3949 if (Argument *Arg = getAssociatedArgument()) {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003950 // We only take known information from the argument
3951 // so we do not need to track a dependence.
Johannes Doerfertdada8132019-12-31 01:27:50 -06003952 const auto &ArgAlignAA = A.getAAFor<AAAlign>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003953 *this, IRPosition::argument(*Arg), /* TrackDependence */ false);
Johannes Doerfertdada8132019-12-31 01:27:50 -06003954 takeKnownMaximum(ArgAlignAA.getKnownAlign());
3955 }
3956 return Changed;
3957 }
3958
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003959 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003960 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003961};
3962
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003963/// Align attribute deduction for a call site return value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003964struct AAAlignCallSiteReturned final
3965 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3966 AAAlignImpl> {
3967 using Base =
3968 AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3969 AAAlignImpl>;
3970 AAAlignCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003971
3972 /// See AbstractAttribute::initialize(...).
3973 void initialize(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003974 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003975 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003976 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003977 indicatePessimisticFixpoint();
3978 }
3979
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003980 /// See AbstractAttribute::trackStatistics()
3981 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3982};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003983
Johannes Doerferte83f3032019-08-05 23:22:05 +00003984/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003985struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003986 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003987
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003988 /// See AbstractAttribute::initialize(...).
3989 void initialize(Attributor &A) override {
3990 AANoReturn::initialize(A);
3991 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003992 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003993 indicatePessimisticFixpoint();
3994 }
3995
Johannes Doerferte83f3032019-08-05 23:22:05 +00003996 /// See AbstractAttribute::getAsStr().
3997 const std::string getAsStr() const override {
3998 return getAssumed() ? "noreturn" : "may-return";
3999 }
4000
Johannes Doerferte83f3032019-08-05 23:22:05 +00004001 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00004002 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004003 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004004 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004005 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00004006 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00004007 return ChangeStatus::UNCHANGED;
4008 }
4009};
4010
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004011struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004012 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00004013
4014 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00004015 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004016};
4017
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00004018/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00004019struct AANoReturnCallSite final : AANoReturnImpl {
4020 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
4021
Johannes Doerfert3fac6682019-08-30 15:24:52 +00004022 /// See AbstractAttribute::updateImpl(...).
4023 ChangeStatus updateImpl(Attributor &A) override {
4024 // TODO: Once we have call site specific value information we can provide
4025 // call site specific liveness information and then it makes
4026 // sense to specialize attributes for call sites arguments instead of
4027 // redirecting requests to the callee argument.
4028 Function *F = getAssociatedFunction();
4029 const IRPosition &FnPos = IRPosition::function(*F);
4030 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
4031 return clampStateAndIndicateChange(
4032 getState(),
4033 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
4034 }
4035
4036 /// See AbstractAttribute::trackStatistics()
4037 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
4038};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00004039
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004040/// ----------------------- Variable Capturing ---------------------------------
4041
4042/// A class to hold the state of for no-capture attributes.
4043struct AANoCaptureImpl : public AANoCapture {
4044 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
4045
4046 /// See AbstractAttribute::initialize(...).
4047 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05004048 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
4049 indicateOptimisticFixpoint();
4050 return;
4051 }
4052 Function *AnchorScope = getAnchorScope();
4053 if (isFnInterfaceKind() &&
4054 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
4055 indicatePessimisticFixpoint();
4056 return;
4057 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004058
Johannes Doerfert72adda12019-10-10 05:33:21 +00004059 // You cannot "capture" null in the default address space.
4060 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
4061 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
4062 indicateOptimisticFixpoint();
4063 return;
4064 }
4065
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05004066 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004067
4068 // Check what state the associated function can actually capture.
4069 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05004070 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004071 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004072 indicatePessimisticFixpoint();
4073 }
4074
4075 /// See AbstractAttribute::updateImpl(...).
4076 ChangeStatus updateImpl(Attributor &A) override;
4077
4078 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
4079 virtual void
4080 getDeducedAttributes(LLVMContext &Ctx,
4081 SmallVectorImpl<Attribute> &Attrs) const override {
4082 if (!isAssumedNoCaptureMaybeReturned())
4083 return;
4084
Hideto Ueno37367642019-09-11 06:52:11 +00004085 if (getArgNo() >= 0) {
4086 if (isAssumedNoCapture())
4087 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
4088 else if (ManifestInternal)
4089 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
4090 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004091 }
4092
4093 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
4094 /// depending on the ability of the function associated with \p IRP to capture
4095 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00004096 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
4097 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05004098 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004099 // TODO: Once we have memory behavior attributes we should use them here.
4100
4101 // If we know we cannot communicate or write to memory, we do not care about
4102 // ptr2int anymore.
4103 if (F.onlyReadsMemory() && F.doesNotThrow() &&
4104 F.getReturnType()->isVoidTy()) {
4105 State.addKnownBits(NO_CAPTURE);
4106 return;
4107 }
4108
4109 // A function cannot capture state in memory if it only reads memory, it can
4110 // however return/throw state and the state might be influenced by the
4111 // pointer value, e.g., loading from a returned pointer might reveal a bit.
4112 if (F.onlyReadsMemory())
4113 State.addKnownBits(NOT_CAPTURED_IN_MEM);
4114
4115 // A function cannot communicate state back if it does not through
4116 // exceptions and doesn not return values.
4117 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
4118 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004119
4120 // Check existing "returned" attributes.
4121 int ArgNo = IRP.getArgNo();
4122 if (F.doesNotThrow() && ArgNo >= 0) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01004123 for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
Johannes Doerfert3839b572019-10-21 00:48:42 +00004124 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00004125 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00004126 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
4127 else if (F.onlyReadsMemory())
4128 State.addKnownBits(NO_CAPTURE);
4129 else
4130 State.addKnownBits(NOT_CAPTURED_IN_RET);
4131 break;
4132 }
4133 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004134 }
4135
4136 /// See AbstractState::getAsStr().
4137 const std::string getAsStr() const override {
4138 if (isKnownNoCapture())
4139 return "known not-captured";
4140 if (isAssumedNoCapture())
4141 return "assumed not-captured";
4142 if (isKnownNoCaptureMaybeReturned())
4143 return "known not-captured-maybe-returned";
4144 if (isAssumedNoCaptureMaybeReturned())
4145 return "assumed not-captured-maybe-returned";
4146 return "assumed-captured";
4147 }
4148};
4149
4150/// Attributor-aware capture tracker.
4151struct AACaptureUseTracker final : public CaptureTracker {
4152
4153 /// Create a capture tracker that can lookup in-flight abstract attributes
4154 /// through the Attributor \p A.
4155 ///
4156 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
4157 /// search is stopped. If a use leads to a return instruction,
4158 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
4159 /// If a use leads to a ptr2int which may capture the value,
4160 /// \p CapturedInInteger is set. If a use is found that is currently assumed
4161 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
4162 /// set. All values in \p PotentialCopies are later tracked as well. For every
4163 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
4164 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
4165 /// conservatively set to true.
4166 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05004167 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004168 SmallVectorImpl<const Value *> &PotentialCopies,
4169 unsigned &RemainingUsesToExplore)
4170 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
4171 PotentialCopies(PotentialCopies),
4172 RemainingUsesToExplore(RemainingUsesToExplore) {}
4173
4174 /// Determine if \p V maybe captured. *Also updates the state!*
4175 bool valueMayBeCaptured(const Value *V) {
4176 if (V->getType()->isPointerTy()) {
4177 PointerMayBeCaptured(V, this);
4178 } else {
4179 State.indicatePessimisticFixpoint();
4180 }
4181 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4182 }
4183
4184 /// See CaptureTracker::tooManyUses().
4185 void tooManyUses() override {
4186 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
4187 }
4188
4189 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
4190 if (CaptureTracker::isDereferenceableOrNull(O, DL))
4191 return true;
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004192 const auto &DerefAA = A.getAAFor<AADereferenceable>(
4193 NoCaptureAA, IRPosition::value(*O), /* TrackDependence */ true,
4194 DepClassTy::OPTIONAL);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004195 return DerefAA.getAssumedDereferenceableBytes();
4196 }
4197
4198 /// See CaptureTracker::captured(...).
4199 bool captured(const Use *U) override {
4200 Instruction *UInst = cast<Instruction>(U->getUser());
4201 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
4202 << "\n");
4203
4204 // Because we may reuse the tracker multiple times we keep track of the
4205 // number of explored uses ourselves as well.
4206 if (RemainingUsesToExplore-- == 0) {
4207 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
4208 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4209 /* Return */ true);
4210 }
4211
4212 // Deal with ptr2int by following uses.
4213 if (isa<PtrToIntInst>(UInst)) {
4214 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
4215 return valueMayBeCaptured(UInst);
4216 }
4217
4218 // Explicitly catch return instructions.
4219 if (isa<ReturnInst>(UInst))
4220 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4221 /* Return */ true);
4222
4223 // For now we only use special logic for call sites. However, the tracker
4224 // itself knows about a lot of other non-capturing cases already.
4225 CallSite CS(UInst);
4226 if (!CS || !CS.isArgOperand(U))
4227 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4228 /* Return */ true);
4229
4230 unsigned ArgNo = CS.getArgumentNo(U);
4231 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
4232 // If we have a abstract no-capture attribute for the argument we can use
4233 // it to justify a non-capture attribute here. This allows recursion!
4234 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
4235 if (ArgNoCaptureAA.isAssumedNoCapture())
4236 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4237 /* Return */ false);
4238 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4239 addPotentialCopy(CS);
4240 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4241 /* Return */ false);
4242 }
4243
4244 // Lastly, we could not find a reason no-capture can be assumed so we don't.
4245 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4246 /* Return */ true);
4247 }
4248
4249 /// Register \p CS as potential copy of the value we are checking.
4250 void addPotentialCopy(CallSite CS) {
4251 PotentialCopies.push_back(CS.getInstruction());
4252 }
4253
4254 /// See CaptureTracker::shouldExplore(...).
4255 bool shouldExplore(const Use *U) override {
Johannes Doerfert23f41f12020-01-12 01:09:22 -06004256 // Check liveness.
4257 return !A.isAssumedDead(*U, &NoCaptureAA, &IsDeadAA);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004258 }
4259
4260 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
4261 /// \p CapturedInRet, then return the appropriate value for use in the
4262 /// CaptureTracker::captured() interface.
4263 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
4264 bool CapturedInRet) {
4265 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
4266 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
4267 if (CapturedInMem)
4268 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
4269 if (CapturedInInt)
4270 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
4271 if (CapturedInRet)
4272 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
4273 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4274 }
4275
4276private:
4277 /// The attributor providing in-flight abstract attributes.
4278 Attributor &A;
4279
4280 /// The abstract attribute currently updated.
4281 AANoCapture &NoCaptureAA;
4282
4283 /// The abstract liveness state.
4284 const AAIsDead &IsDeadAA;
4285
4286 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05004287 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004288
4289 /// Set of potential copies of the tracked value.
4290 SmallVectorImpl<const Value *> &PotentialCopies;
4291
4292 /// Global counter to limit the number of explored uses.
4293 unsigned &RemainingUsesToExplore;
4294};
4295
4296ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
4297 const IRPosition &IRP = getIRPosition();
4298 const Value *V =
4299 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
4300 if (!V)
4301 return indicatePessimisticFixpoint();
4302
4303 const Function *F =
4304 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
4305 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00004306 const IRPosition &FnPos = IRPosition::function(*F);
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004307 const auto &IsDeadAA =
4308 A.getAAFor<AAIsDead>(*this, FnPos, /* TrackDependence */ false);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004309
4310 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004311
Johannes Doerfert3839b572019-10-21 00:48:42 +00004312 // Readonly means we cannot capture through memory.
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004313 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(
4314 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004315 if (FnMemAA.isAssumedReadOnly()) {
4316 T.addKnownBits(NOT_CAPTURED_IN_MEM);
4317 if (FnMemAA.isKnownReadOnly())
4318 addKnownBits(NOT_CAPTURED_IN_MEM);
4319 }
4320
4321 // Make sure all returned values are different than the underlying value.
4322 // TODO: we could do this in a more sophisticated way inside
4323 // AAReturnedValues, e.g., track all values that escape through returns
4324 // directly somehow.
4325 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
4326 bool SeenConstant = false;
4327 for (auto &It : RVAA.returned_values()) {
4328 if (isa<Constant>(It.first)) {
4329 if (SeenConstant)
4330 return false;
4331 SeenConstant = true;
4332 } else if (!isa<Argument>(It.first) ||
4333 It.first == getAssociatedArgument())
4334 return false;
4335 }
4336 return true;
4337 };
4338
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004339 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(
4340 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004341 if (NoUnwindAA.isAssumedNoUnwind()) {
4342 bool IsVoidTy = F->getReturnType()->isVoidTy();
4343 const AAReturnedValues *RVAA =
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004344 IsVoidTy ? nullptr
4345 : &A.getAAFor<AAReturnedValues>(*this, FnPos,
4346 /* TrackDependence */ true,
4347 DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004348 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
4349 T.addKnownBits(NOT_CAPTURED_IN_RET);
4350 if (T.isKnown(NOT_CAPTURED_IN_MEM))
4351 return ChangeStatus::UNCHANGED;
4352 if (NoUnwindAA.isKnownNoUnwind() &&
4353 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
4354 addKnownBits(NOT_CAPTURED_IN_RET);
4355 if (isKnown(NOT_CAPTURED_IN_MEM))
4356 return indicateOptimisticFixpoint();
4357 }
4358 }
4359 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004360
4361 // Use the CaptureTracker interface and logic with the specialized tracker,
4362 // defined in AACaptureUseTracker, that can look at in-flight abstract
4363 // attributes and directly updates the assumed state.
4364 SmallVector<const Value *, 4> PotentialCopies;
4365 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
4366 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
4367 RemainingUsesToExplore);
4368
4369 // Check all potential copies of the associated value until we can assume
4370 // none will be captured or we have to assume at least one might be.
4371 unsigned Idx = 0;
4372 PotentialCopies.push_back(V);
4373 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
4374 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
4375
Johannes Doerfert1a746452019-10-20 22:28:49 -05004376 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004377 auto Assumed = S.getAssumed();
4378 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05004379 if (!isAssumedNoCaptureMaybeReturned())
4380 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004381 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
4382 : ChangeStatus::CHANGED;
4383}
4384
4385/// NoCapture attribute for function arguments.
4386struct AANoCaptureArgument final : AANoCaptureImpl {
4387 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4388
4389 /// See AbstractAttribute::trackStatistics()
4390 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
4391};
4392
4393/// NoCapture attribute for call site arguments.
4394struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
4395 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4396
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004397 /// See AbstractAttribute::initialize(...).
4398 void initialize(Attributor &A) override {
4399 if (Argument *Arg = getAssociatedArgument())
4400 if (Arg->hasByValAttr())
4401 indicateOptimisticFixpoint();
4402 AANoCaptureImpl::initialize(A);
4403 }
4404
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004405 /// See AbstractAttribute::updateImpl(...).
4406 ChangeStatus updateImpl(Attributor &A) override {
4407 // TODO: Once we have call site specific value information we can provide
4408 // call site specific liveness information and then it makes
4409 // sense to specialize attributes for call sites arguments instead of
4410 // redirecting requests to the callee argument.
4411 Argument *Arg = getAssociatedArgument();
4412 if (!Arg)
4413 return indicatePessimisticFixpoint();
4414 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4415 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
4416 return clampStateAndIndicateChange(
4417 getState(),
4418 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
4419 }
4420
4421 /// See AbstractAttribute::trackStatistics()
4422 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
4423};
4424
4425/// NoCapture attribute for floating values.
4426struct AANoCaptureFloating final : AANoCaptureImpl {
4427 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4428
4429 /// See AbstractAttribute::trackStatistics()
4430 void trackStatistics() const override {
4431 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
4432 }
4433};
4434
4435/// NoCapture attribute for function return value.
4436struct AANoCaptureReturned final : AANoCaptureImpl {
4437 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
4438 llvm_unreachable("NoCapture is not applicable to function returns!");
4439 }
4440
4441 /// See AbstractAttribute::initialize(...).
4442 void initialize(Attributor &A) override {
4443 llvm_unreachable("NoCapture is not applicable to function returns!");
4444 }
4445
4446 /// See AbstractAttribute::updateImpl(...).
4447 ChangeStatus updateImpl(Attributor &A) override {
4448 llvm_unreachable("NoCapture is not applicable to function returns!");
4449 }
4450
4451 /// See AbstractAttribute::trackStatistics()
4452 void trackStatistics() const override {}
4453};
4454
4455/// NoCapture attribute deduction for a call site return value.
4456struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
4457 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4458
4459 /// See AbstractAttribute::trackStatistics()
4460 void trackStatistics() const override {
4461 STATS_DECLTRACK_CSRET_ATTR(nocapture)
4462 }
4463};
4464
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004465/// ------------------ Value Simplify Attribute ----------------------------
4466struct AAValueSimplifyImpl : AAValueSimplify {
4467 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
4468
Johannes Doerfert9dcf8892020-01-11 23:59:36 -06004469 /// See AbstractAttribute::initialize(...).
4470 void initialize(Attributor &A) override {
4471 if (getAssociatedValue().getType()->isVoidTy())
4472 indicatePessimisticFixpoint();
4473 }
4474
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004475 /// See AbstractAttribute::getAsStr().
4476 const std::string getAsStr() const override {
4477 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
4478 : "not-simple";
4479 }
4480
4481 /// See AbstractAttribute::trackStatistics()
4482 void trackStatistics() const override {}
4483
4484 /// See AAValueSimplify::getAssumedSimplifiedValue()
4485 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
4486 if (!getAssumed())
4487 return const_cast<Value *>(&getAssociatedValue());
4488 return SimplifiedAssociatedValue;
4489 }
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004490
4491 /// Helper function for querying AAValueSimplify and updating candicate.
4492 /// \param QueryingValue Value trying to unify with SimplifiedValue
4493 /// \param AccumulatedSimplifiedValue Current simplification result.
4494 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
4495 Value &QueryingValue,
4496 Optional<Value *> &AccumulatedSimplifiedValue) {
4497 // FIXME: Add a typecast support.
4498
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004499 auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004500 QueryingAA, IRPosition::value(QueryingValue));
4501
4502 Optional<Value *> QueryingValueSimplified =
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004503 ValueSimplifyAA.getAssumedSimplifiedValue(A);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004504
4505 if (!QueryingValueSimplified.hasValue())
4506 return true;
4507
4508 if (!QueryingValueSimplified.getValue())
4509 return false;
4510
4511 Value &QueryingValueSimplifiedUnwrapped =
4512 *QueryingValueSimplified.getValue();
4513
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004514 if (AccumulatedSimplifiedValue.hasValue() &&
4515 !isa<UndefValue>(AccumulatedSimplifiedValue.getValue()) &&
4516 !isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004517 return AccumulatedSimplifiedValue == QueryingValueSimplified;
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004518 if (AccumulatedSimplifiedValue.hasValue() &&
4519 isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
4520 return true;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004521
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004522 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << QueryingValue
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004523 << " is assumed to be "
4524 << QueryingValueSimplifiedUnwrapped << "\n");
4525
4526 AccumulatedSimplifiedValue = QueryingValueSimplified;
4527 return true;
4528 }
4529
Hideto Ueno188f9a32020-01-15 15:25:52 +09004530 bool askSimplifiedValueForAAValueConstantRange(Attributor &A) {
4531 if (!getAssociatedValue().getType()->isIntegerTy())
4532 return false;
4533
4534 const auto &ValueConstantRangeAA =
4535 A.getAAFor<AAValueConstantRange>(*this, getIRPosition());
4536
4537 Optional<ConstantInt *> COpt =
4538 ValueConstantRangeAA.getAssumedConstantInt(A);
4539 if (COpt.hasValue()) {
4540 if (auto *C = COpt.getValue())
4541 SimplifiedAssociatedValue = C;
4542 else
4543 return false;
4544 } else {
Johannes Doerfert63adbb92020-02-09 20:21:56 -06004545 SimplifiedAssociatedValue = llvm::None;
Hideto Ueno188f9a32020-01-15 15:25:52 +09004546 }
4547 return true;
4548 }
4549
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004550 /// See AbstractAttribute::manifest(...).
4551 ChangeStatus manifest(Attributor &A) override {
4552 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4553
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004554 if (SimplifiedAssociatedValue.hasValue() &&
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004555 !SimplifiedAssociatedValue.getValue())
4556 return Changed;
4557
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004558 Value &V = getAssociatedValue();
4559 auto *C = SimplifiedAssociatedValue.hasValue()
4560 ? dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())
4561 : UndefValue::get(V.getType());
4562 if (C) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004563 // We can replace the AssociatedValue with the constant.
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004564 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004565 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *C
4566 << " :: " << *this << "\n");
Johannes Doerfert4c62a352020-01-12 00:17:08 -06004567 if (A.changeValueAfterManifest(V, *C))
4568 Changed = ChangeStatus::CHANGED;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004569 }
4570 }
4571
4572 return Changed | AAValueSimplify::manifest(A);
4573 }
4574
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004575 /// See AbstractState::indicatePessimisticFixpoint(...).
4576 ChangeStatus indicatePessimisticFixpoint() override {
4577 // NOTE: Associated value will be returned in a pessimistic fixpoint and is
4578 // regarded as known. That's why`indicateOptimisticFixpoint` is called.
4579 SimplifiedAssociatedValue = &getAssociatedValue();
Johannes Doerferta4b35882019-12-31 13:25:47 -06004580 indicateOptimisticFixpoint();
4581 return ChangeStatus::CHANGED;
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004582 }
4583
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004584protected:
4585 // An assumed simplified value. Initially, it is set to Optional::None, which
4586 // means that the value is not clear under current assumption. If in the
4587 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4588 // returns orignal associated value.
4589 Optional<Value *> SimplifiedAssociatedValue;
4590};
4591
4592struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
4593 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4594
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004595 void initialize(Attributor &A) override {
4596 AAValueSimplifyImpl::initialize(A);
4597 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
4598 indicatePessimisticFixpoint();
4599 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
4600 /* IgnoreSubsumingPositions */ true))
4601 indicatePessimisticFixpoint();
Johannes Doerfert16188f92020-02-16 23:04:25 -06004602
4603 // FIXME: This is a hack to prevent us from propagating function poiner in
4604 // the new pass manager CGSCC pass as it creates call edges the
4605 // CallGraphUpdater cannot handle yet.
4606 Value &V = getAssociatedValue();
4607 if (V.getType()->isPointerTy() &&
4608 V.getType()->getPointerElementType()->isFunctionTy() &&
4609 !A.isModulePass() &&
4610 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
4611 *getAnchorScope()))
4612 indicatePessimisticFixpoint();
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004613 }
4614
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004615 /// See AbstractAttribute::updateImpl(...).
4616 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004617 // Byval is only replacable if it is readonly otherwise we would write into
4618 // the replaced value and not the copy that byval creates implicitly.
4619 Argument *Arg = getAssociatedArgument();
4620 if (Arg->hasByValAttr()) {
Johannes Doerfert8e76fec2020-02-16 17:37:50 -06004621 // TODO: We probably need to verify synchronization is not an issue, e.g.,
4622 // there is no race by not copying a constant byval.
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004623 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
4624 if (!MemAA.isAssumedReadOnly())
4625 return indicatePessimisticFixpoint();
4626 }
4627
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004628 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4629
Johannes Doerfert661db042019-10-07 23:14:58 +00004630 auto PredForCallSite = [&](AbstractCallSite ACS) {
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004631 const IRPosition &ACSArgPos =
4632 IRPosition::callsite_argument(ACS, getArgNo());
4633 // Check if a coresponding argument was found or if it is on not
4634 // associated (which can happen for callback calls).
4635 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004636 return false;
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004637
Johannes Doerferte360ee62019-11-01 18:45:25 -05004638 // We can only propagate thread independent values through callbacks.
4639 // This is different to direct/indirect call sites because for them we
4640 // know the thread executing the caller and callee is the same. For
4641 // callbacks this is not guaranteed, thus a thread dependent value could
4642 // be different for the caller and callee, making it invalid to propagate.
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004643 Value &ArgOp = ACSArgPos.getAssociatedValue();
Johannes Doerferte360ee62019-11-01 18:45:25 -05004644 if (ACS.isCallbackCall())
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004645 if (auto *C = dyn_cast<Constant>(&ArgOp))
Johannes Doerferte360ee62019-11-01 18:45:25 -05004646 if (C->isThreadDependent())
4647 return false;
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004648 return checkAndUpdate(A, *this, ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004649 };
4650
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004651 bool AllCallSitesKnown;
4652 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4653 AllCallSitesKnown))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004654 if (!askSimplifiedValueForAAValueConstantRange(A))
4655 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004656
4657 // If a candicate was found in this update, return CHANGED.
4658 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4659 ? ChangeStatus::UNCHANGED
4660 : ChangeStatus ::CHANGED;
4661 }
4662
4663 /// See AbstractAttribute::trackStatistics()
4664 void trackStatistics() const override {
4665 STATS_DECLTRACK_ARG_ATTR(value_simplify)
4666 }
4667};
4668
4669struct AAValueSimplifyReturned : AAValueSimplifyImpl {
4670 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4671
4672 /// See AbstractAttribute::updateImpl(...).
4673 ChangeStatus updateImpl(Attributor &A) override {
4674 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4675
4676 auto PredForReturned = [&](Value &V) {
4677 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4678 };
4679
4680 if (!A.checkForAllReturnedValues(PredForReturned, *this))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004681 if (!askSimplifiedValueForAAValueConstantRange(A))
4682 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004683
4684 // If a candicate was found in this update, return CHANGED.
4685 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4686 ? ChangeStatus::UNCHANGED
4687 : ChangeStatus ::CHANGED;
4688 }
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004689
4690 ChangeStatus manifest(Attributor &A) override {
4691 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4692
4693 if (SimplifiedAssociatedValue.hasValue() &&
4694 !SimplifiedAssociatedValue.getValue())
4695 return Changed;
4696
4697 Value &V = getAssociatedValue();
4698 auto *C = SimplifiedAssociatedValue.hasValue()
4699 ? dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())
4700 : UndefValue::get(V.getType());
4701 if (C) {
4702 auto PredForReturned =
4703 [&](Value &V, const SmallSetVector<ReturnInst *, 4> &RetInsts) {
4704 // We can replace the AssociatedValue with the constant.
4705 if (&V == C || V.getType() != C->getType() || isa<UndefValue>(V))
4706 return true;
4707 if (auto *CI = dyn_cast<CallInst>(&V))
4708 if (CI->isMustTailCall())
4709 return true;
4710
4711 for (ReturnInst *RI : RetInsts) {
4712 if (RI->getFunction() != getAnchorScope())
4713 continue;
4714 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *C
4715 << " in " << *RI << " :: " << *this << "\n");
4716 if (A.changeUseAfterManifest(RI->getOperandUse(0), *C))
4717 Changed = ChangeStatus::CHANGED;
4718 }
4719 return true;
4720 };
4721 A.checkForAllReturnedValuesAndReturnInsts(PredForReturned, *this);
4722 }
4723
4724 return Changed | AAValueSimplify::manifest(A);
4725 }
4726
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004727 /// See AbstractAttribute::trackStatistics()
4728 void trackStatistics() const override {
4729 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
4730 }
4731};
4732
4733struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4734 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4735
4736 /// See AbstractAttribute::initialize(...).
4737 void initialize(Attributor &A) override {
Johannes Doerfert16188f92020-02-16 23:04:25 -06004738 AAValueSimplifyImpl::initialize(A);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004739 Value &V = getAnchorValue();
4740
4741 // TODO: add other stuffs
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004742 if (isa<Constant>(V))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004743 indicatePessimisticFixpoint();
4744 }
4745
4746 /// See AbstractAttribute::updateImpl(...).
4747 ChangeStatus updateImpl(Attributor &A) override {
4748 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4749
Johannes Doerfert76843ba2020-01-28 23:51:25 -06004750 auto VisitValueCB = [&](Value &V, bool &, bool Stripped) -> bool {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004751 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
4752 if (!Stripped && this == &AA) {
4753 // TODO: Look the instruction and check recursively.
Hideto Ueno188f9a32020-01-15 15:25:52 +09004754
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004755 LLVM_DEBUG(dbgs() << "[ValueSimplify] Can't be stripped more : " << V
4756 << "\n");
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004757 return false;
4758 }
4759 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4760 };
4761
Johannes Doerfert76843ba2020-01-28 23:51:25 -06004762 bool Dummy = false;
Johannes Doerfert6626d1b2020-01-28 11:49:59 -06004763 if (!genericValueTraversal<AAValueSimplify, bool>(A, getIRPosition(), *this,
4764 Dummy, VisitValueCB))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004765 if (!askSimplifiedValueForAAValueConstantRange(A))
4766 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004767
4768 // If a candicate was found in this update, return CHANGED.
4769
4770 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4771 ? ChangeStatus::UNCHANGED
4772 : ChangeStatus ::CHANGED;
4773 }
4774
4775 /// See AbstractAttribute::trackStatistics()
4776 void trackStatistics() const override {
4777 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
4778 }
4779};
4780
4781struct AAValueSimplifyFunction : AAValueSimplifyImpl {
4782 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4783
4784 /// See AbstractAttribute::initialize(...).
4785 void initialize(Attributor &A) override {
4786 SimplifiedAssociatedValue = &getAnchorValue();
4787 indicateOptimisticFixpoint();
4788 }
4789 /// See AbstractAttribute::initialize(...).
4790 ChangeStatus updateImpl(Attributor &A) override {
4791 llvm_unreachable(
4792 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
4793 }
4794 /// See AbstractAttribute::trackStatistics()
4795 void trackStatistics() const override {
4796 STATS_DECLTRACK_FN_ATTR(value_simplify)
4797 }
4798};
4799
4800struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
4801 AAValueSimplifyCallSite(const IRPosition &IRP)
4802 : AAValueSimplifyFunction(IRP) {}
4803 /// See AbstractAttribute::trackStatistics()
4804 void trackStatistics() const override {
4805 STATS_DECLTRACK_CS_ATTR(value_simplify)
4806 }
4807};
4808
4809struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
4810 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
4811 : AAValueSimplifyReturned(IRP) {}
4812
Johannes Doerfertb2c76002020-01-23 17:12:56 -06004813 /// See AbstractAttribute::manifest(...).
4814 ChangeStatus manifest(Attributor &A) override {
4815 if (auto *CI = dyn_cast<CallInst>(&getAssociatedValue()))
4816 if (CI->isMustTailCall())
4817 return ChangeStatus::UNCHANGED;
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004818 return AAValueSimplifyImpl::manifest(A);
Johannes Doerfertb2c76002020-01-23 17:12:56 -06004819 }
4820
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004821 void trackStatistics() const override {
4822 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
4823 }
4824};
4825struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
4826 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
4827 : AAValueSimplifyFloating(IRP) {}
4828
4829 void trackStatistics() const override {
4830 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
4831 }
4832};
4833
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004834/// ----------------------- Heap-To-Stack Conversion ---------------------------
4835struct AAHeapToStackImpl : public AAHeapToStack {
4836 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
4837
4838 const std::string getAsStr() const override {
4839 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
4840 }
4841
4842 ChangeStatus manifest(Attributor &A) override {
4843 assert(getState().isValidState() &&
4844 "Attempted to manifest an invalid state!");
4845
4846 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4847 Function *F = getAssociatedFunction();
4848 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4849
4850 for (Instruction *MallocCall : MallocCalls) {
4851 // This malloc cannot be replaced.
4852 if (BadMallocCalls.count(MallocCall))
4853 continue;
4854
4855 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
4856 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
4857 A.deleteAfterManifest(*FreeCall);
4858 HasChanged = ChangeStatus::CHANGED;
4859 }
4860
4861 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
4862 << "\n");
4863
4864 Constant *Size;
4865 if (isCallocLikeFn(MallocCall, TLI)) {
4866 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
4867 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
4868 APInt TotalSize = SizeT->getValue() * Num->getValue();
4869 Size =
4870 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
4871 } else {
4872 Size = cast<ConstantInt>(MallocCall->getOperand(0));
4873 }
4874
4875 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
4876 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
4877 Size, "", MallocCall->getNextNode());
4878
4879 if (AI->getType() != MallocCall->getType())
4880 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
4881 AI->getNextNode());
4882
Johannes Doerfert4c62a352020-01-12 00:17:08 -06004883 A.changeValueAfterManifest(*MallocCall, *AI);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004884
4885 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
4886 auto *NBB = II->getNormalDest();
4887 BranchInst::Create(NBB, MallocCall->getParent());
4888 A.deleteAfterManifest(*MallocCall);
4889 } else {
4890 A.deleteAfterManifest(*MallocCall);
4891 }
4892
4893 if (isCallocLikeFn(MallocCall, TLI)) {
4894 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
4895 AI->getNextNode());
4896 Value *Ops[] = {
4897 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
4898 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
4899
4900 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
4901 Module *M = F->getParent();
4902 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
4903 CallInst::Create(Fn, Ops, "", BI->getNextNode());
4904 }
4905 HasChanged = ChangeStatus::CHANGED;
4906 }
4907
4908 return HasChanged;
4909 }
4910
4911 /// Collection of all malloc calls in a function.
4912 SmallSetVector<Instruction *, 4> MallocCalls;
4913
4914 /// Collection of malloc calls that cannot be converted.
4915 DenseSet<const Instruction *> BadMallocCalls;
4916
4917 /// A map for each malloc call to the set of associated free calls.
4918 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
4919
4920 ChangeStatus updateImpl(Attributor &A) override;
4921};
4922
4923ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4924 const Function *F = getAssociatedFunction();
4925 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4926
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004927 MustBeExecutedContextExplorer &Explorer =
4928 A.getInfoCache().getMustBeExecutedContextExplorer();
4929
4930 auto FreeCheck = [&](Instruction &I) {
4931 const auto &Frees = FreesForMalloc.lookup(&I);
4932 if (Frees.size() != 1)
4933 return false;
4934 Instruction *UniqueFree = *Frees.begin();
4935 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
4936 };
4937
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004938 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004939 bool ValidUsesOnly = true;
4940 bool MustUse = true;
Hideto Ueno827bade2019-12-12 12:26:30 +00004941 auto Pred = [&](const Use &U, bool &Follow) -> bool {
4942 Instruction *UserI = cast<Instruction>(U.getUser());
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004943 if (isa<LoadInst>(UserI))
Hideto Ueno827bade2019-12-12 12:26:30 +00004944 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004945 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004946 if (SI->getValueOperand() == U.get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004947 LLVM_DEBUG(dbgs()
4948 << "[H2S] escaping store to memory: " << *UserI << "\n");
4949 ValidUsesOnly = false;
4950 } else {
4951 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004952 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004953 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004954 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004955 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004956 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
4957 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004958 // Record malloc.
4959 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004960 if (MustUse) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004961 FreesForMalloc[&I].insert(UserI);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004962 } else {
4963 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
4964 << *UserI << "\n");
4965 ValidUsesOnly = false;
4966 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004967 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004968 }
4969
Hideto Ueno827bade2019-12-12 12:26:30 +00004970 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004971
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004972 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
4973 *this, IRPosition::callsite_argument(*CB, ArgNo));
4974
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004975 // If a callsite argument use is nofree, we are fine.
4976 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
4977 *this, IRPosition::callsite_argument(*CB, ArgNo));
4978
Hideto Ueno827bade2019-12-12 12:26:30 +00004979 if (!NoCaptureAA.isAssumedNoCapture() ||
4980 !ArgNoFreeAA.isAssumedNoFree()) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004981 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004982 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004983 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004984 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004985 }
4986
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004987 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
4988 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
4989 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Hideto Ueno827bade2019-12-12 12:26:30 +00004990 Follow = true;
4991 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004992 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004993 // Unknown user for which we can not track uses further (in a way that
4994 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004995 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004996 ValidUsesOnly = false;
Hideto Ueno827bade2019-12-12 12:26:30 +00004997 return true;
4998 };
4999 A.checkForAllUses(Pred, *this, I);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005000 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005001 };
5002
5003 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005004 if (BadMallocCalls.count(&I))
5005 return true;
5006
5007 bool IsMalloc = isMallocLikeFn(&I, TLI);
5008 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
5009 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005010 BadMallocCalls.insert(&I);
5011 return true;
5012 }
5013
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005014 if (IsMalloc) {
5015 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01005016 if (Size->getValue().ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005017 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005018 MallocCalls.insert(&I);
5019 return true;
5020 }
5021 } else if (IsCalloc) {
5022 bool Overflow = false;
5023 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
5024 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
5025 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01005026 .ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005027 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005028 MallocCalls.insert(&I);
5029 return true;
5030 }
5031 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005032
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005033 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005034 return true;
5035 };
5036
5037 size_t NumBadMallocs = BadMallocCalls.size();
5038
5039 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
5040
5041 if (NumBadMallocs != BadMallocCalls.size())
5042 return ChangeStatus::CHANGED;
5043
5044 return ChangeStatus::UNCHANGED;
5045}
5046
5047struct AAHeapToStackFunction final : public AAHeapToStackImpl {
5048 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
5049
5050 /// See AbstractAttribute::trackStatistics()
5051 void trackStatistics() const override {
5052 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005053 "Number of malloc calls converted to allocas");
5054 for (auto *C : MallocCalls)
5055 if (!BadMallocCalls.count(C))
5056 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005057 }
5058};
5059
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005060/// ----------------------- Privatizable Pointers ------------------------------
5061struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
5062 AAPrivatizablePtrImpl(const IRPosition &IRP)
5063 : AAPrivatizablePtr(IRP), PrivatizableType(llvm::None) {}
5064
5065 ChangeStatus indicatePessimisticFixpoint() override {
5066 AAPrivatizablePtr::indicatePessimisticFixpoint();
5067 PrivatizableType = nullptr;
5068 return ChangeStatus::CHANGED;
5069 }
5070
5071 /// Identify the type we can chose for a private copy of the underlying
5072 /// argument. None means it is not clear yet, nullptr means there is none.
5073 virtual Optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
5074
5075 /// Return a privatizable type that encloses both T0 and T1.
5076 /// TODO: This is merely a stub for now as we should manage a mapping as well.
5077 Optional<Type *> combineTypes(Optional<Type *> T0, Optional<Type *> T1) {
5078 if (!T0.hasValue())
5079 return T1;
5080 if (!T1.hasValue())
5081 return T0;
5082 if (T0 == T1)
5083 return T0;
5084 return nullptr;
5085 }
5086
5087 Optional<Type *> getPrivatizableType() const override {
5088 return PrivatizableType;
5089 }
5090
5091 const std::string getAsStr() const override {
5092 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
5093 }
5094
5095protected:
5096 Optional<Type *> PrivatizableType;
5097};
5098
5099// TODO: Do this for call site arguments (probably also other values) as well.
5100
5101struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
5102 AAPrivatizablePtrArgument(const IRPosition &IRP)
5103 : AAPrivatizablePtrImpl(IRP) {}
5104
5105 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
5106 Optional<Type *> identifyPrivatizableType(Attributor &A) override {
5107 // If this is a byval argument and we know all the call sites (so we can
5108 // rewrite them), there is no need to check them explicitly.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005109 bool AllCallSitesKnown;
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005110 if (getIRPosition().hasAttr(Attribute::ByVal) &&
5111 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005112 true, AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005113 return getAssociatedValue().getType()->getPointerElementType();
5114
5115 Optional<Type *> Ty;
5116 unsigned ArgNo = getIRPosition().getArgNo();
5117
5118 // Make sure the associated call site argument has the same type at all call
5119 // sites and it is an allocation we know is safe to privatize, for now that
5120 // means we only allow alloca instructions.
5121 // TODO: We can additionally analyze the accesses in the callee to create
5122 // the type from that information instead. That is a little more
5123 // involved and will be done in a follow up patch.
5124 auto CallSiteCheck = [&](AbstractCallSite ACS) {
5125 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
5126 // Check if a coresponding argument was found or if it is one not
5127 // associated (which can happen for callback calls).
5128 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
5129 return false;
5130
5131 // Check that all call sites agree on a type.
5132 auto &PrivCSArgAA = A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos);
5133 Optional<Type *> CSTy = PrivCSArgAA.getPrivatizableType();
5134
5135 LLVM_DEBUG({
5136 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
5137 if (CSTy.hasValue() && CSTy.getValue())
5138 CSTy.getValue()->print(dbgs());
5139 else if (CSTy.hasValue())
5140 dbgs() << "<nullptr>";
5141 else
5142 dbgs() << "<none>";
5143 });
5144
5145 Ty = combineTypes(Ty, CSTy);
5146
5147 LLVM_DEBUG({
5148 dbgs() << " : New Type: ";
5149 if (Ty.hasValue() && Ty.getValue())
5150 Ty.getValue()->print(dbgs());
5151 else if (Ty.hasValue())
5152 dbgs() << "<nullptr>";
5153 else
5154 dbgs() << "<none>";
5155 dbgs() << "\n";
5156 });
5157
5158 return !Ty.hasValue() || Ty.getValue();
5159 };
5160
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005161 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005162 return nullptr;
5163 return Ty;
5164 }
5165
5166 /// See AbstractAttribute::updateImpl(...).
5167 ChangeStatus updateImpl(Attributor &A) override {
5168 PrivatizableType = identifyPrivatizableType(A);
5169 if (!PrivatizableType.hasValue())
5170 return ChangeStatus::UNCHANGED;
5171 if (!PrivatizableType.getValue())
5172 return indicatePessimisticFixpoint();
5173
5174 // Avoid arguments with padding for now.
5175 if (!getIRPosition().hasAttr(Attribute::ByVal) &&
5176 !ArgumentPromotionPass::isDenselyPacked(PrivatizableType.getValue(),
5177 A.getInfoCache().getDL())) {
5178 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
5179 return indicatePessimisticFixpoint();
5180 }
5181
5182 // Verify callee and caller agree on how the promoted argument would be
5183 // passed.
5184 // TODO: The use of the ArgumentPromotion interface here is ugly, we need a
5185 // specialized form of TargetTransformInfo::areFunctionArgsABICompatible
5186 // which doesn't require the arguments ArgumentPromotion wanted to pass.
5187 Function &Fn = *getIRPosition().getAnchorScope();
5188 SmallPtrSet<Argument *, 1> ArgsToPromote, Dummy;
5189 ArgsToPromote.insert(getAssociatedArgument());
5190 const auto *TTI =
5191 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
5192 if (!TTI ||
5193 !ArgumentPromotionPass::areFunctionArgsABICompatible(
5194 Fn, *TTI, ArgsToPromote, Dummy) ||
5195 ArgsToPromote.empty()) {
5196 LLVM_DEBUG(
5197 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
5198 << Fn.getName() << "\n");
5199 return indicatePessimisticFixpoint();
5200 }
5201
5202 // Collect the types that will replace the privatizable type in the function
5203 // signature.
5204 SmallVector<Type *, 16> ReplacementTypes;
5205 identifyReplacementTypes(PrivatizableType.getValue(), ReplacementTypes);
5206
5207 // Register a rewrite of the argument.
5208 Argument *Arg = getAssociatedArgument();
5209 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
5210 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
5211 return indicatePessimisticFixpoint();
5212 }
5213
5214 unsigned ArgNo = Arg->getArgNo();
5215
5216 // Helper to check if for the given call site the associated argument is
5217 // passed to a callback where the privatization would be different.
5218 auto IsCompatiblePrivArgOfCallback = [&](CallSite CS) {
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005219 SmallVector<const Use *, 4> CBUses;
5220 AbstractCallSite::getCallbackUses(CS, CBUses);
5221 for (const Use *U : CBUses) {
5222 AbstractCallSite CBACS(U);
5223 assert(CBACS && CBACS.isCallbackCall());
5224 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
5225 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
5226
5227 LLVM_DEBUG({
5228 dbgs()
5229 << "[AAPrivatizablePtr] Argument " << *Arg
5230 << "check if can be privatized in the context of its parent ("
5231 << Arg->getParent()->getName()
5232 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5233 "callback ("
5234 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
5235 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
Michael Forster676c2962020-01-30 10:20:49 +01005236 << CBACS.getCallArgOperand(CBArg) << " vs "
5237 << CS.getArgOperand(ArgNo) << "\n"
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005238 << "[AAPrivatizablePtr] " << CBArg << " : "
5239 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
5240 });
5241
5242 if (CBArgNo != int(ArgNo))
5243 continue;
5244 const auto &CBArgPrivAA =
5245 A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(CBArg));
5246 if (CBArgPrivAA.isValidState()) {
5247 auto CBArgPrivTy = CBArgPrivAA.getPrivatizableType();
5248 if (!CBArgPrivTy.hasValue())
5249 continue;
5250 if (CBArgPrivTy.getValue() == PrivatizableType)
5251 continue;
5252 }
5253
5254 LLVM_DEBUG({
5255 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5256 << " cannot be privatized in the context of its parent ("
5257 << Arg->getParent()->getName()
5258 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5259 "callback ("
5260 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
5261 << ").\n[AAPrivatizablePtr] for which the argument "
5262 "privatization is not compatible.\n";
5263 });
5264 return false;
5265 }
5266 }
5267 return true;
5268 };
5269
5270 // Helper to check if for the given call site the associated argument is
5271 // passed to a direct call where the privatization would be different.
5272 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
5273 CallBase *DC = cast<CallBase>(ACS.getInstruction());
5274 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
5275 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->getNumArgOperands() &&
5276 "Expected a direct call operand for callback call operand");
5277
5278 LLVM_DEBUG({
5279 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5280 << " check if be privatized in the context of its parent ("
5281 << Arg->getParent()->getName()
5282 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5283 "direct call of ("
5284 << DCArgNo << "@" << DC->getCalledFunction()->getName()
5285 << ").\n";
5286 });
5287
5288 Function *DCCallee = DC->getCalledFunction();
5289 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
5290 const auto &DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
5291 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)));
5292 if (DCArgPrivAA.isValidState()) {
5293 auto DCArgPrivTy = DCArgPrivAA.getPrivatizableType();
5294 if (!DCArgPrivTy.hasValue())
5295 return true;
5296 if (DCArgPrivTy.getValue() == PrivatizableType)
5297 return true;
5298 }
5299 }
5300
5301 LLVM_DEBUG({
5302 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5303 << " cannot be privatized in the context of its parent ("
5304 << Arg->getParent()->getName()
5305 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5306 "direct call of ("
5307 << ACS.getCallSite().getCalledFunction()->getName()
5308 << ").\n[AAPrivatizablePtr] for which the argument "
5309 "privatization is not compatible.\n";
5310 });
5311 return false;
5312 };
5313
5314 // Helper to check if the associated argument is used at the given abstract
5315 // call site in a way that is incompatible with the privatization assumed
5316 // here.
5317 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
5318 if (ACS.isDirectCall())
5319 return IsCompatiblePrivArgOfCallback(ACS.getCallSite());
5320 if (ACS.isCallbackCall())
5321 return IsCompatiblePrivArgOfDirectCS(ACS);
5322 return false;
5323 };
5324
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005325 bool AllCallSitesKnown;
5326 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
5327 AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005328 return indicatePessimisticFixpoint();
5329
5330 return ChangeStatus::UNCHANGED;
5331 }
5332
5333 /// Given a type to private \p PrivType, collect the constituates (which are
5334 /// used) in \p ReplacementTypes.
5335 static void
5336 identifyReplacementTypes(Type *PrivType,
5337 SmallVectorImpl<Type *> &ReplacementTypes) {
5338 // TODO: For now we expand the privatization type to the fullest which can
5339 // lead to dead arguments that need to be removed later.
5340 assert(PrivType && "Expected privatizable type!");
5341
5342 // Traverse the type, extract constituate types on the outermost level.
5343 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5344 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
5345 ReplacementTypes.push_back(PrivStructType->getElementType(u));
5346 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5347 ReplacementTypes.append(PrivArrayType->getNumElements(),
5348 PrivArrayType->getElementType());
5349 } else {
5350 ReplacementTypes.push_back(PrivType);
5351 }
5352 }
5353
5354 /// Initialize \p Base according to the type \p PrivType at position \p IP.
5355 /// The values needed are taken from the arguments of \p F starting at
5356 /// position \p ArgNo.
5357 static void createInitialization(Type *PrivType, Value &Base, Function &F,
5358 unsigned ArgNo, Instruction &IP) {
5359 assert(PrivType && "Expected privatizable type!");
5360
5361 IRBuilder<NoFolder> IRB(&IP);
5362 const DataLayout &DL = F.getParent()->getDataLayout();
5363
5364 // Traverse the type, build GEPs and stores.
5365 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5366 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
5367 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
5368 Type *PointeeTy = PrivStructType->getElementType(u)->getPointerTo();
5369 Value *Ptr = constructPointer(
5370 PointeeTy, &Base, PrivStructLayout->getElementOffset(u), IRB, DL);
5371 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
5372 }
5373 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5374 Type *PointeePtrTy = PrivArrayType->getElementType()->getPointerTo();
5375 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeePtrTy);
5376 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
5377 Value *Ptr =
5378 constructPointer(PointeePtrTy, &Base, u * PointeeTySize, IRB, DL);
5379 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
5380 }
5381 } else {
5382 new StoreInst(F.getArg(ArgNo), &Base, &IP);
5383 }
5384 }
5385
5386 /// Extract values from \p Base according to the type \p PrivType at the
5387 /// call position \p ACS. The values are appended to \p ReplacementValues.
5388 void createReplacementValues(Type *PrivType, AbstractCallSite ACS,
5389 Value *Base,
5390 SmallVectorImpl<Value *> &ReplacementValues) {
5391 assert(Base && "Expected base value!");
5392 assert(PrivType && "Expected privatizable type!");
5393 Instruction *IP = ACS.getInstruction();
5394
5395 IRBuilder<NoFolder> IRB(IP);
5396 const DataLayout &DL = IP->getModule()->getDataLayout();
5397
5398 if (Base->getType()->getPointerElementType() != PrivType)
5399 Base = BitCastInst::CreateBitOrPointerCast(Base, PrivType->getPointerTo(),
5400 "", ACS.getInstruction());
5401
5402 // TODO: Improve the alignment of the loads.
5403 // Traverse the type, build GEPs and loads.
5404 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5405 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
5406 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
5407 Type *PointeeTy = PrivStructType->getElementType(u);
5408 Value *Ptr =
5409 constructPointer(PointeeTy->getPointerTo(), Base,
5410 PrivStructLayout->getElementOffset(u), IRB, DL);
5411 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP);
5412 L->setAlignment(MaybeAlign(1));
5413 ReplacementValues.push_back(L);
5414 }
5415 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5416 Type *PointeeTy = PrivArrayType->getElementType();
5417 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
5418 Type *PointeePtrTy = PointeeTy->getPointerTo();
5419 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
5420 Value *Ptr =
5421 constructPointer(PointeePtrTy, Base, u * PointeeTySize, IRB, DL);
5422 LoadInst *L = new LoadInst(PointeePtrTy, Ptr, "", IP);
5423 L->setAlignment(MaybeAlign(1));
5424 ReplacementValues.push_back(L);
5425 }
5426 } else {
5427 LoadInst *L = new LoadInst(PrivType, Base, "", IP);
5428 L->setAlignment(MaybeAlign(1));
5429 ReplacementValues.push_back(L);
5430 }
5431 }
5432
5433 /// See AbstractAttribute::manifest(...)
5434 ChangeStatus manifest(Attributor &A) override {
5435 if (!PrivatizableType.hasValue())
5436 return ChangeStatus::UNCHANGED;
5437 assert(PrivatizableType.getValue() && "Expected privatizable type!");
5438
5439 // Collect all tail calls in the function as we cannot allow new allocas to
5440 // escape into tail recursion.
5441 // TODO: Be smarter about new allocas escaping into tail calls.
5442 SmallVector<CallInst *, 16> TailCalls;
5443 if (!A.checkForAllInstructions(
5444 [&](Instruction &I) {
5445 CallInst &CI = cast<CallInst>(I);
5446 if (CI.isTailCall())
5447 TailCalls.push_back(&CI);
5448 return true;
5449 },
5450 *this, {Instruction::Call}))
5451 return ChangeStatus::UNCHANGED;
5452
5453 Argument *Arg = getAssociatedArgument();
5454
5455 // Callback to repair the associated function. A new alloca is placed at the
5456 // beginning and initialized with the values passed through arguments. The
5457 // new alloca replaces the use of the old pointer argument.
5458 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB =
5459 [=](const Attributor::ArgumentReplacementInfo &ARI,
5460 Function &ReplacementFn, Function::arg_iterator ArgIt) {
5461 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
5462 Instruction *IP = &*EntryBB.getFirstInsertionPt();
5463 auto *AI = new AllocaInst(PrivatizableType.getValue(), 0,
5464 Arg->getName() + ".priv", IP);
5465 createInitialization(PrivatizableType.getValue(), *AI, ReplacementFn,
5466 ArgIt->getArgNo(), *IP);
5467 Arg->replaceAllUsesWith(AI);
5468
5469 for (CallInst *CI : TailCalls)
5470 CI->setTailCall(false);
5471 };
5472
5473 // Callback to repair a call site of the associated function. The elements
5474 // of the privatizable type are loaded prior to the call and passed to the
5475 // new function version.
5476 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB =
5477 [=](const Attributor::ArgumentReplacementInfo &ARI,
5478 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
5479 createReplacementValues(
5480 PrivatizableType.getValue(), ACS,
5481 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
5482 NewArgOperands);
5483 };
5484
5485 // Collect the types that will replace the privatizable type in the function
5486 // signature.
5487 SmallVector<Type *, 16> ReplacementTypes;
5488 identifyReplacementTypes(PrivatizableType.getValue(), ReplacementTypes);
5489
5490 // Register a rewrite of the argument.
5491 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
5492 std::move(FnRepairCB),
5493 std::move(ACSRepairCB)))
5494 return ChangeStatus::CHANGED;
5495 return ChangeStatus::UNCHANGED;
5496 }
5497
5498 /// See AbstractAttribute::trackStatistics()
5499 void trackStatistics() const override {
5500 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
5501 }
5502};
5503
5504struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
5505 AAPrivatizablePtrFloating(const IRPosition &IRP)
5506 : AAPrivatizablePtrImpl(IRP) {}
5507
5508 /// See AbstractAttribute::initialize(...).
5509 virtual void initialize(Attributor &A) override {
5510 // TODO: We can privatize more than arguments.
5511 indicatePessimisticFixpoint();
5512 }
5513
5514 ChangeStatus updateImpl(Attributor &A) override {
5515 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
5516 "updateImpl will not be called");
5517 }
5518
5519 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
5520 Optional<Type *> identifyPrivatizableType(Attributor &A) override {
5521 Value *Obj =
5522 GetUnderlyingObject(&getAssociatedValue(), A.getInfoCache().getDL());
5523 if (!Obj) {
5524 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
5525 return nullptr;
5526 }
5527
5528 if (auto *AI = dyn_cast<AllocaInst>(Obj))
5529 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
5530 if (CI->isOne())
5531 return Obj->getType()->getPointerElementType();
5532 if (auto *Arg = dyn_cast<Argument>(Obj)) {
5533 auto &PrivArgAA =
5534 A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(*Arg));
5535 if (PrivArgAA.isAssumedPrivatizablePtr())
5536 return Obj->getType()->getPointerElementType();
5537 }
5538
5539 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
5540 "alloca nor privatizable argument: "
5541 << *Obj << "!\n");
5542 return nullptr;
5543 }
5544
5545 /// See AbstractAttribute::trackStatistics()
5546 void trackStatistics() const override {
5547 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
5548 }
5549};
5550
5551struct AAPrivatizablePtrCallSiteArgument final
5552 : public AAPrivatizablePtrFloating {
5553 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP)
5554 : AAPrivatizablePtrFloating(IRP) {}
5555
5556 /// See AbstractAttribute::initialize(...).
5557 void initialize(Attributor &A) override {
5558 if (getIRPosition().hasAttr(Attribute::ByVal))
5559 indicateOptimisticFixpoint();
5560 }
5561
5562 /// See AbstractAttribute::updateImpl(...).
5563 ChangeStatus updateImpl(Attributor &A) override {
5564 PrivatizableType = identifyPrivatizableType(A);
5565 if (!PrivatizableType.hasValue())
5566 return ChangeStatus::UNCHANGED;
5567 if (!PrivatizableType.getValue())
5568 return indicatePessimisticFixpoint();
5569
5570 const IRPosition &IRP = getIRPosition();
5571 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
5572 if (!NoCaptureAA.isAssumedNoCapture()) {
5573 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
5574 return indicatePessimisticFixpoint();
5575 }
5576
5577 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
5578 if (!NoAliasAA.isAssumedNoAlias()) {
5579 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
5580 return indicatePessimisticFixpoint();
5581 }
5582
5583 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, IRP);
5584 if (!MemBehaviorAA.isAssumedReadOnly()) {
5585 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
5586 return indicatePessimisticFixpoint();
5587 }
5588
5589 return ChangeStatus::UNCHANGED;
5590 }
5591
5592 /// See AbstractAttribute::trackStatistics()
5593 void trackStatistics() const override {
5594 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
5595 }
5596};
5597
5598struct AAPrivatizablePtrCallSiteReturned final
5599 : public AAPrivatizablePtrFloating {
5600 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP)
5601 : AAPrivatizablePtrFloating(IRP) {}
5602
5603 /// See AbstractAttribute::initialize(...).
5604 void initialize(Attributor &A) override {
5605 // TODO: We can privatize more than arguments.
5606 indicatePessimisticFixpoint();
5607 }
5608
5609 /// See AbstractAttribute::trackStatistics()
5610 void trackStatistics() const override {
5611 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
5612 }
5613};
5614
5615struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
5616 AAPrivatizablePtrReturned(const IRPosition &IRP)
5617 : AAPrivatizablePtrFloating(IRP) {}
5618
5619 /// See AbstractAttribute::initialize(...).
5620 void initialize(Attributor &A) override {
5621 // TODO: We can privatize more than arguments.
5622 indicatePessimisticFixpoint();
5623 }
5624
5625 /// See AbstractAttribute::trackStatistics()
5626 void trackStatistics() const override {
5627 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
5628 }
5629};
5630
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005631/// -------------------- Memory Behavior Attributes ----------------------------
5632/// Includes read-none, read-only, and write-only.
5633/// ----------------------------------------------------------------------------
5634struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
5635 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
5636
5637 /// See AbstractAttribute::initialize(...).
5638 void initialize(Attributor &A) override {
5639 intersectAssumedBits(BEST_STATE);
5640 getKnownStateFromValue(getIRPosition(), getState());
5641 IRAttribute::initialize(A);
5642 }
5643
5644 /// Return the memory behavior information encoded in the IR for \p IRP.
5645 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005646 BitIntegerState &State,
5647 bool IgnoreSubsumingPositions = false) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005648 SmallVector<Attribute, 2> Attrs;
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005649 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005650 for (const Attribute &Attr : Attrs) {
5651 switch (Attr.getKindAsEnum()) {
5652 case Attribute::ReadNone:
5653 State.addKnownBits(NO_ACCESSES);
5654 break;
5655 case Attribute::ReadOnly:
5656 State.addKnownBits(NO_WRITES);
5657 break;
5658 case Attribute::WriteOnly:
5659 State.addKnownBits(NO_READS);
5660 break;
5661 default:
Johannes Doerfert282f5d72020-01-26 02:51:57 -06005662 llvm_unreachable("Unexpected attribute!");
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005663 }
5664 }
5665
5666 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
5667 if (!I->mayReadFromMemory())
5668 State.addKnownBits(NO_READS);
5669 if (!I->mayWriteToMemory())
5670 State.addKnownBits(NO_WRITES);
5671 }
5672 }
5673
5674 /// See AbstractAttribute::getDeducedAttributes(...).
5675 void getDeducedAttributes(LLVMContext &Ctx,
5676 SmallVectorImpl<Attribute> &Attrs) const override {
5677 assert(Attrs.size() == 0);
5678 if (isAssumedReadNone())
5679 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
5680 else if (isAssumedReadOnly())
5681 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
5682 else if (isAssumedWriteOnly())
5683 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
5684 assert(Attrs.size() <= 1);
5685 }
5686
5687 /// See AbstractAttribute::manifest(...).
5688 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert282f5d72020-01-26 02:51:57 -06005689 if (hasAttr(Attribute::ReadNone, /* IgnoreSubsumingPositions */ true))
5690 return ChangeStatus::UNCHANGED;
5691
Johannes Doerfertb2083c52019-10-20 22:46:48 -05005692 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005693
5694 // Check if we would improve the existing attributes first.
5695 SmallVector<Attribute, 4> DeducedAttrs;
5696 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
5697 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
5698 return IRP.hasAttr(Attr.getKindAsEnum(),
5699 /* IgnoreSubsumingPositions */ true);
5700 }))
5701 return ChangeStatus::UNCHANGED;
5702
5703 // Clear existing attributes.
5704 IRP.removeAttrs(AttrKinds);
5705
5706 // Use the generic manifest method.
5707 return IRAttribute::manifest(A);
5708 }
5709
5710 /// See AbstractState::getAsStr().
5711 const std::string getAsStr() const override {
5712 if (isAssumedReadNone())
5713 return "readnone";
5714 if (isAssumedReadOnly())
5715 return "readonly";
5716 if (isAssumedWriteOnly())
5717 return "writeonly";
5718 return "may-read/write";
5719 }
5720
5721 /// The set of IR attributes AAMemoryBehavior deals with.
5722 static const Attribute::AttrKind AttrKinds[3];
5723};
5724
5725const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
5726 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
5727
5728/// Memory behavior attribute for a floating value.
5729struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
5730 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5731
5732 /// See AbstractAttribute::initialize(...).
5733 void initialize(Attributor &A) override {
5734 AAMemoryBehaviorImpl::initialize(A);
5735 // Initialize the use vector with all direct uses of the associated value.
5736 for (const Use &U : getAssociatedValue().uses())
5737 Uses.insert(&U);
5738 }
5739
5740 /// See AbstractAttribute::updateImpl(...).
5741 ChangeStatus updateImpl(Attributor &A) override;
5742
5743 /// See AbstractAttribute::trackStatistics()
5744 void trackStatistics() const override {
5745 if (isAssumedReadNone())
5746 STATS_DECLTRACK_FLOATING_ATTR(readnone)
5747 else if (isAssumedReadOnly())
5748 STATS_DECLTRACK_FLOATING_ATTR(readonly)
5749 else if (isAssumedWriteOnly())
5750 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
5751 }
5752
5753private:
5754 /// Return true if users of \p UserI might access the underlying
5755 /// variable/location described by \p U and should therefore be analyzed.
5756 bool followUsersOfUseIn(Attributor &A, const Use *U,
5757 const Instruction *UserI);
5758
5759 /// Update the state according to the effect of use \p U in \p UserI.
5760 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
5761
5762protected:
5763 /// Container for (transitive) uses of the associated argument.
5764 SetVector<const Use *> Uses;
5765};
5766
5767/// Memory behavior attribute for function argument.
5768struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
5769 AAMemoryBehaviorArgument(const IRPosition &IRP)
5770 : AAMemoryBehaviorFloating(IRP) {}
5771
5772 /// See AbstractAttribute::initialize(...).
5773 void initialize(Attributor &A) override {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005774 intersectAssumedBits(BEST_STATE);
5775 const IRPosition &IRP = getIRPosition();
5776 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
5777 // can query it when we use has/getAttr. That would allow us to reuse the
5778 // initialize of the base class here.
5779 bool HasByVal =
5780 IRP.hasAttr({Attribute::ByVal}, /* IgnoreSubsumingPositions */ true);
5781 getKnownStateFromValue(IRP, getState(),
5782 /* IgnoreSubsumingPositions */ HasByVal);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005783
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005784 // Initialize the use vector with all direct uses of the associated value.
5785 Argument *Arg = getAssociatedArgument();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005786 if (!Arg || !Arg->getParent()->hasExactDefinition()) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005787 indicatePessimisticFixpoint();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005788 } else {
5789 // Initialize the use vector with all direct uses of the associated value.
5790 for (const Use &U : Arg->uses())
5791 Uses.insert(&U);
5792 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005793 }
5794
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005795 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert282f5d72020-01-26 02:51:57 -06005796 // TODO: Pointer arguments are not supported on vectors of pointers yet.
5797 if (!getAssociatedValue().getType()->isPointerTy())
5798 return ChangeStatus::UNCHANGED;
5799
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005800 // TODO: From readattrs.ll: "inalloca parameters are always
5801 // considered written"
5802 if (hasAttr({Attribute::InAlloca})) {
5803 removeKnownBits(NO_WRITES);
5804 removeAssumedBits(NO_WRITES);
5805 }
5806 return AAMemoryBehaviorFloating::manifest(A);
5807 }
5808
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005809 /// See AbstractAttribute::trackStatistics()
5810 void trackStatistics() const override {
5811 if (isAssumedReadNone())
5812 STATS_DECLTRACK_ARG_ATTR(readnone)
5813 else if (isAssumedReadOnly())
5814 STATS_DECLTRACK_ARG_ATTR(readonly)
5815 else if (isAssumedWriteOnly())
5816 STATS_DECLTRACK_ARG_ATTR(writeonly)
5817 }
5818};
5819
5820struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
5821 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
5822 : AAMemoryBehaviorArgument(IRP) {}
5823
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005824 /// See AbstractAttribute::initialize(...).
5825 void initialize(Attributor &A) override {
5826 if (Argument *Arg = getAssociatedArgument()) {
5827 if (Arg->hasByValAttr()) {
5828 addKnownBits(NO_WRITES);
5829 removeKnownBits(NO_READS);
5830 removeAssumedBits(NO_READS);
5831 }
5832 } else {
5833 }
5834 AAMemoryBehaviorArgument::initialize(A);
5835 }
5836
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005837 /// See AbstractAttribute::updateImpl(...).
5838 ChangeStatus updateImpl(Attributor &A) override {
5839 // TODO: Once we have call site specific value information we can provide
5840 // call site specific liveness liveness information and then it makes
5841 // sense to specialize attributes for call sites arguments instead of
5842 // redirecting requests to the callee argument.
5843 Argument *Arg = getAssociatedArgument();
5844 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5845 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
5846 return clampStateAndIndicateChange(
5847 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05005848 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005849 }
5850
5851 /// See AbstractAttribute::trackStatistics()
5852 void trackStatistics() const override {
5853 if (isAssumedReadNone())
5854 STATS_DECLTRACK_CSARG_ATTR(readnone)
5855 else if (isAssumedReadOnly())
5856 STATS_DECLTRACK_CSARG_ATTR(readonly)
5857 else if (isAssumedWriteOnly())
5858 STATS_DECLTRACK_CSARG_ATTR(writeonly)
5859 }
5860};
5861
5862/// Memory behavior attribute for a call site return position.
5863struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
5864 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
5865 : AAMemoryBehaviorFloating(IRP) {}
5866
5867 /// See AbstractAttribute::manifest(...).
5868 ChangeStatus manifest(Attributor &A) override {
5869 // We do not annotate returned values.
5870 return ChangeStatus::UNCHANGED;
5871 }
5872
5873 /// See AbstractAttribute::trackStatistics()
5874 void trackStatistics() const override {}
5875};
5876
5877/// An AA to represent the memory behavior function attributes.
5878struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
5879 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5880
5881 /// See AbstractAttribute::updateImpl(Attributor &A).
5882 virtual ChangeStatus updateImpl(Attributor &A) override;
5883
5884 /// See AbstractAttribute::manifest(...).
5885 ChangeStatus manifest(Attributor &A) override {
5886 Function &F = cast<Function>(getAnchorValue());
5887 if (isAssumedReadNone()) {
5888 F.removeFnAttr(Attribute::ArgMemOnly);
5889 F.removeFnAttr(Attribute::InaccessibleMemOnly);
5890 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
5891 }
5892 return AAMemoryBehaviorImpl::manifest(A);
5893 }
5894
5895 /// See AbstractAttribute::trackStatistics()
5896 void trackStatistics() const override {
5897 if (isAssumedReadNone())
5898 STATS_DECLTRACK_FN_ATTR(readnone)
5899 else if (isAssumedReadOnly())
5900 STATS_DECLTRACK_FN_ATTR(readonly)
5901 else if (isAssumedWriteOnly())
5902 STATS_DECLTRACK_FN_ATTR(writeonly)
5903 }
5904};
5905
5906/// AAMemoryBehavior attribute for call sites.
5907struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
5908 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5909
5910 /// See AbstractAttribute::initialize(...).
5911 void initialize(Attributor &A) override {
5912 AAMemoryBehaviorImpl::initialize(A);
5913 Function *F = getAssociatedFunction();
5914 if (!F || !F->hasExactDefinition())
5915 indicatePessimisticFixpoint();
5916 }
5917
5918 /// See AbstractAttribute::updateImpl(...).
5919 ChangeStatus updateImpl(Attributor &A) override {
5920 // TODO: Once we have call site specific value information we can provide
5921 // call site specific liveness liveness information and then it makes
5922 // sense to specialize attributes for call sites arguments instead of
5923 // redirecting requests to the callee argument.
5924 Function *F = getAssociatedFunction();
5925 const IRPosition &FnPos = IRPosition::function(*F);
5926 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
5927 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05005928 getState(),
5929 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005930 }
5931
5932 /// See AbstractAttribute::trackStatistics()
5933 void trackStatistics() const override {
5934 if (isAssumedReadNone())
5935 STATS_DECLTRACK_CS_ATTR(readnone)
5936 else if (isAssumedReadOnly())
5937 STATS_DECLTRACK_CS_ATTR(readonly)
5938 else if (isAssumedWriteOnly())
5939 STATS_DECLTRACK_CS_ATTR(writeonly)
5940 }
5941};
5942
5943ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
5944
5945 // The current assumed state used to determine a change.
5946 auto AssumedState = getAssumed();
5947
5948 auto CheckRWInst = [&](Instruction &I) {
5949 // If the instruction has an own memory behavior state, use it to restrict
5950 // the local state. No further analysis is required as the other memory
5951 // state is as optimistic as it gets.
5952 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
5953 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
5954 *this, IRPosition::callsite_function(ICS));
5955 intersectAssumedBits(MemBehaviorAA.getAssumed());
5956 return !isAtFixpoint();
5957 }
5958
5959 // Remove access kind modifiers if necessary.
5960 if (I.mayReadFromMemory())
5961 removeAssumedBits(NO_READS);
5962 if (I.mayWriteToMemory())
5963 removeAssumedBits(NO_WRITES);
5964 return !isAtFixpoint();
5965 };
5966
5967 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
5968 return indicatePessimisticFixpoint();
5969
5970 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5971 : ChangeStatus::UNCHANGED;
5972}
5973
5974ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
5975
5976 const IRPosition &IRP = getIRPosition();
5977 const IRPosition &FnPos = IRPosition::function_scope(IRP);
5978 AAMemoryBehavior::StateType &S = getState();
5979
5980 // First, check the function scope. We take the known information and we avoid
5981 // work if the assumed information implies the current assumed information for
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005982 // this attribute. This is a valid for all but byval arguments.
5983 Argument *Arg = IRP.getAssociatedArgument();
5984 AAMemoryBehavior::base_t FnMemAssumedState =
5985 AAMemoryBehavior::StateType::getWorstState();
5986 if (!Arg || !Arg->hasByValAttr()) {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005987 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(
5988 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005989 FnMemAssumedState = FnMemAA.getAssumed();
5990 S.addKnownBits(FnMemAA.getKnown());
5991 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
5992 return ChangeStatus::UNCHANGED;
5993 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005994
5995 // Make sure the value is not captured (except through "return"), if
5996 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005997 // check the potential aliases introduced by the capture. However, no need
5998 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert28880192019-12-31 00:57:00 -06005999 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
6000 *this, IRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00006001 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06006002 S.intersectAssumedBits(FnMemAssumedState);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00006003 return ChangeStatus::CHANGED;
6004 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006005
6006 // The current assumed state used to determine a change.
6007 auto AssumedState = S.getAssumed();
6008
6009 // Liveness information to exclude dead users.
6010 // TODO: Take the FnPos once we have call site specific liveness information.
6011 const auto &LivenessAA = A.getAAFor<AAIsDead>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06006012 *this, IRPosition::function(*IRP.getAssociatedFunction()),
6013 /* TrackDependence */ false);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006014
6015 // Visit and expand uses until all are analyzed or a fixpoint is reached.
6016 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
6017 const Use *U = Uses[i];
6018 Instruction *UserI = cast<Instruction>(U->getUser());
6019 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
Johannes Doerfert23f41f12020-01-12 01:09:22 -06006020 << " [Dead: " << (A.isAssumedDead(*U, this, &LivenessAA))
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006021 << "]\n");
Johannes Doerfert23f41f12020-01-12 01:09:22 -06006022 if (A.isAssumedDead(*U, this, &LivenessAA))
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006023 continue;
6024
6025 // Check if the users of UserI should also be visited.
6026 if (followUsersOfUseIn(A, U, UserI))
6027 for (const Use &UserIUse : UserI->uses())
6028 Uses.insert(&UserIUse);
6029
6030 // If UserI might touch memory we analyze the use in detail.
6031 if (UserI->mayReadOrWriteMemory())
6032 analyzeUseIn(A, U, UserI);
6033 }
6034
6035 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
6036 : ChangeStatus::UNCHANGED;
6037}
6038
6039bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
6040 const Instruction *UserI) {
6041 // The loaded value is unrelated to the pointer argument, no need to
6042 // follow the users of the load.
6043 if (isa<LoadInst>(UserI))
6044 return false;
6045
6046 // By default we follow all uses assuming UserI might leak information on U,
6047 // we have special handling for call sites operands though.
6048 ImmutableCallSite ICS(UserI);
6049 if (!ICS || !ICS.isArgOperand(U))
6050 return true;
6051
6052 // If the use is a call argument known not to be captured, the users of
6053 // the call do not need to be visited because they have to be unrelated to
6054 // the input. Note that this check is not trivial even though we disallow
6055 // general capturing of the underlying argument. The reason is that the
6056 // call might the argument "through return", which we allow and for which we
6057 // need to check call users.
Johannes Doerfertff6254d2020-01-10 12:32:24 -06006058 if (U->get()->getType()->isPointerTy()) {
6059 unsigned ArgNo = ICS.getArgumentNo(U);
6060 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06006061 *this, IRPosition::callsite_argument(ICS, ArgNo),
6062 /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfertff6254d2020-01-10 12:32:24 -06006063 return !ArgNoCaptureAA.isAssumedNoCapture();
6064 }
6065
6066 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006067}
6068
6069void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
6070 const Instruction *UserI) {
6071 assert(UserI->mayReadOrWriteMemory());
6072
6073 switch (UserI->getOpcode()) {
6074 default:
6075 // TODO: Handle all atomics and other side-effect operations we know of.
6076 break;
6077 case Instruction::Load:
6078 // Loads cause the NO_READS property to disappear.
6079 removeAssumedBits(NO_READS);
6080 return;
6081
6082 case Instruction::Store:
6083 // Stores cause the NO_WRITES property to disappear if the use is the
6084 // pointer operand. Note that we do assume that capturing was taken care of
6085 // somewhere else.
6086 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
6087 removeAssumedBits(NO_WRITES);
6088 return;
6089
6090 case Instruction::Call:
6091 case Instruction::CallBr:
6092 case Instruction::Invoke: {
6093 // For call sites we look at the argument memory behavior attribute (this
6094 // could be recursive!) in order to restrict our own state.
6095 ImmutableCallSite ICS(UserI);
6096
6097 // Give up on operand bundles.
6098 if (ICS.isBundleOperand(U)) {
6099 indicatePessimisticFixpoint();
6100 return;
6101 }
6102
6103 // Calling a function does read the function pointer, maybe write it if the
6104 // function is self-modifying.
6105 if (ICS.isCallee(U)) {
6106 removeAssumedBits(NO_READS);
6107 break;
6108 }
6109
6110 // Adjust the possible access behavior based on the information on the
6111 // argument.
Johannes Doerfertff6254d2020-01-10 12:32:24 -06006112 IRPosition Pos;
6113 if (U->get()->getType()->isPointerTy())
6114 Pos = IRPosition::callsite_argument(ICS, ICS.getArgumentNo(U));
6115 else
6116 Pos = IRPosition::callsite_function(ICS);
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06006117 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
6118 *this, Pos,
6119 /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006120 // "assumed" has at most the same bits as the MemBehaviorAA assumed
6121 // and at least "known".
6122 intersectAssumedBits(MemBehaviorAA.getAssumed());
6123 return;
6124 }
6125 };
6126
6127 // Generally, look at the "may-properties" and adjust the assumed state if we
6128 // did not trigger special handling before.
6129 if (UserI->mayReadFromMemory())
6130 removeAssumedBits(NO_READS);
6131 if (UserI->mayWriteToMemory())
6132 removeAssumedBits(NO_WRITES);
6133}
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006134
Benjamin Kramer564a9de2020-02-17 17:55:03 +01006135} // namespace
6136
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006137/// -------------------- Memory Locations Attributes ---------------------------
6138/// Includes read-none, argmemonly, inaccessiblememonly,
6139/// inaccessiblememorargmemonly
6140/// ----------------------------------------------------------------------------
6141
6142std::string AAMemoryLocation::getMemoryLocationsAsStr(
6143 AAMemoryLocation::MemoryLocationsKind MLK) {
6144 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
6145 return "all memory";
6146 if (MLK == AAMemoryLocation::NO_LOCATIONS)
6147 return "no memory";
6148 std::string S = "memory:";
6149 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
6150 S += "stack,";
6151 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
6152 S += "constant,";
6153 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_INTERNAL_MEM))
6154 S += "internal global,";
6155 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_EXTERNAL_MEM))
6156 S += "external global,";
6157 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
6158 S += "argument,";
6159 if (0 == (MLK & AAMemoryLocation::NO_INACCESSIBLE_MEM))
6160 S += "inaccessible,";
6161 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
6162 S += "malloced,";
6163 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
6164 S += "unknown,";
6165 S.pop_back();
6166 return S;
6167}
6168
Benjamin Kramer564a9de2020-02-17 17:55:03 +01006169namespace {
6170
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006171struct AAMemoryLocationImpl : public AAMemoryLocation {
6172
6173 AAMemoryLocationImpl(const IRPosition &IRP) : AAMemoryLocation(IRP) {}
6174
6175 /// See AbstractAttribute::initialize(...).
6176 void initialize(Attributor &A) override {
6177 intersectAssumedBits(BEST_STATE);
6178 getKnownStateFromValue(getIRPosition(), getState());
6179 IRAttribute::initialize(A);
6180 }
6181
6182 /// Return the memory behavior information encoded in the IR for \p IRP.
6183 static void getKnownStateFromValue(const IRPosition &IRP,
6184 BitIntegerState &State,
6185 bool IgnoreSubsumingPositions = false) {
6186 SmallVector<Attribute, 2> Attrs;
6187 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
6188 for (const Attribute &Attr : Attrs) {
6189 switch (Attr.getKindAsEnum()) {
6190 case Attribute::ReadNone:
6191 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
6192 break;
6193 case Attribute::InaccessibleMemOnly:
6194 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
6195 break;
6196 case Attribute::ArgMemOnly:
6197 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
6198 break;
6199 case Attribute::InaccessibleMemOrArgMemOnly:
6200 State.addKnownBits(
6201 inverseLocation(NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
6202 break;
6203 default:
6204 llvm_unreachable("Unexpected attribute!");
6205 }
6206 }
6207 }
6208
6209 /// See AbstractAttribute::getDeducedAttributes(...).
6210 void getDeducedAttributes(LLVMContext &Ctx,
6211 SmallVectorImpl<Attribute> &Attrs) const override {
6212 assert(Attrs.size() == 0);
6213 if (isAssumedReadNone()) {
6214 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
6215 } else if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
6216 if (isAssumedInaccessibleMemOnly())
6217 Attrs.push_back(Attribute::get(Ctx, Attribute::InaccessibleMemOnly));
6218 else if (isAssumedArgMemOnly())
6219 Attrs.push_back(Attribute::get(Ctx, Attribute::ArgMemOnly));
6220 else if (isAssumedInaccessibleOrArgMemOnly())
6221 Attrs.push_back(
6222 Attribute::get(Ctx, Attribute::InaccessibleMemOrArgMemOnly));
6223 }
6224 assert(Attrs.size() <= 1);
6225 }
6226
6227 /// See AbstractAttribute::manifest(...).
6228 ChangeStatus manifest(Attributor &A) override {
6229 const IRPosition &IRP = getIRPosition();
6230
6231 // Check if we would improve the existing attributes first.
6232 SmallVector<Attribute, 4> DeducedAttrs;
6233 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
6234 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
6235 return IRP.hasAttr(Attr.getKindAsEnum(),
6236 /* IgnoreSubsumingPositions */ true);
6237 }))
6238 return ChangeStatus::UNCHANGED;
6239
6240 // Clear existing attributes.
6241 IRP.removeAttrs(AttrKinds);
6242 if (isAssumedReadNone())
6243 IRP.removeAttrs(AAMemoryBehaviorImpl::AttrKinds);
6244
6245 // Use the generic manifest method.
6246 return IRAttribute::manifest(A);
6247 }
6248
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006249 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
6250 bool checkForAllAccessesToMemoryKind(
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006251 const function_ref<bool(const Instruction *, const Value *, AccessKind,
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006252 MemoryLocationsKind)> &Pred,
6253 MemoryLocationsKind RequestedMLK) const override {
6254 if (!isValidState())
6255 return false;
6256
6257 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
6258 if (AssumedMLK == NO_LOCATIONS)
6259 return true;
6260
6261 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
6262 if (CurMLK & RequestedMLK)
6263 continue;
6264
6265 const auto &Accesses = AccessKindAccessesMap.lookup(CurMLK);
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006266 for (const AccessInfo &AI : Accesses) {
6267 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006268 return false;
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006269 }
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006270 }
6271
6272 return true;
6273 }
6274
6275 ChangeStatus indicatePessimisticFixpoint() override {
6276 // If we give up and indicate a pessimistic fixpoint this instruction will
6277 // become an access for all potential access kinds:
6278 // TODO: Add pointers for argmemonly and globals to improve the results of
6279 // checkForAllAccessesToMemoryKind.
6280 bool Changed = false;
6281 MemoryLocationsKind KnownMLK = getKnown();
6282 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
6283 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
6284 if (!(CurMLK & KnownMLK))
6285 updateStateAndAccessesMap(getState(), AccessKindAccessesMap, CurMLK, I,
6286 nullptr, Changed);
6287 return AAMemoryLocation::indicatePessimisticFixpoint();
6288 }
6289
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006290protected:
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006291 /// Helper struct to tie together an instruction that has a read or write
6292 /// effect with the pointer it accesses (if any).
6293 struct AccessInfo {
6294
6295 /// The instruction that caused the access.
6296 const Instruction *I;
6297
6298 /// The base pointer that is accessed, or null if unknown.
6299 const Value *Ptr;
6300
6301 /// The kind of access (read/write/read+write).
6302 AccessKind Kind;
6303
6304 bool operator==(const AccessInfo &RHS) const {
Simon Pilgrim8a48c4a2020-02-15 13:53:18 +00006305 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006306 }
6307 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
6308 if (LHS.I != RHS.I)
6309 return LHS.I < RHS.I;
6310 if (LHS.Ptr != RHS.Ptr)
6311 return LHS.Ptr < RHS.Ptr;
6312 if (LHS.Kind != RHS.Kind)
6313 return LHS.Kind < RHS.Kind;
6314 return false;
6315 }
6316 };
6317
6318 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
6319 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
6320 using AccessKindAccessesMapTy =
6321 DenseMap<unsigned, SmallSet<AccessInfo, 8, AccessInfo>>;
6322 AccessKindAccessesMapTy AccessKindAccessesMap;
6323
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006324 /// Return the kind(s) of location that may be accessed by \p V.
6325 AAMemoryLocation::MemoryLocationsKind
6326 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
6327
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006328 /// Update the state \p State and the AccessKindAccessesMap given that \p I is
6329 /// an access to a \p MLK memory location with the access pointer \p Ptr.
6330 static void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
6331 AccessKindAccessesMapTy &AccessMap,
6332 MemoryLocationsKind MLK,
6333 const Instruction *I, const Value *Ptr,
6334 bool &Changed) {
6335 // TODO: The kind should be determined at the call sites based on the
6336 // information we have there.
6337 AccessKind Kind = READ_WRITE;
6338 if (I) {
6339 Kind = I->mayReadFromMemory() ? READ : NONE;
6340 Kind = AccessKind(Kind | (I->mayWriteToMemory() ? WRITE : NONE));
6341 }
6342
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006343 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006344 Changed |= AccessMap[MLK].insert(AccessInfo{I, Ptr, Kind}).second;
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006345 State.removeAssumedBits(MLK);
6346 }
6347
6348 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
6349 /// arguments, and update the state and access map accordingly.
6350 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
6351 AAMemoryLocation::StateType &State, bool &Changed);
6352
6353 /// The set of IR attributes AAMemoryLocation deals with.
6354 static const Attribute::AttrKind AttrKinds[4];
6355};
6356
6357const Attribute::AttrKind AAMemoryLocationImpl::AttrKinds[] = {
6358 Attribute::ReadNone, Attribute::InaccessibleMemOnly, Attribute::ArgMemOnly,
6359 Attribute::InaccessibleMemOrArgMemOnly};
6360
6361void AAMemoryLocationImpl::categorizePtrValue(
6362 Attributor &A, const Instruction &I, const Value &Ptr,
6363 AAMemoryLocation::StateType &State, bool &Changed) {
6364 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
6365 << Ptr << " ["
6366 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
6367
6368 auto StripGEPCB = [](Value *V) -> Value * {
6369 auto *GEP = dyn_cast<GEPOperator>(V);
6370 while (GEP) {
6371 V = GEP->getPointerOperand();
6372 GEP = dyn_cast<GEPOperator>(V);
6373 }
6374 return V;
6375 };
6376
6377 auto VisitValueCB = [&](Value &V, AAMemoryLocation::StateType &T,
6378 bool Stripped) -> bool {
6379 assert(!isa<GEPOperator>(V) && "GEPs should have been stripped.");
6380 if (isa<UndefValue>(V))
6381 return true;
6382 if (auto *Arg = dyn_cast<Argument>(&V)) {
6383 if (Arg->hasByValAttr())
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006384 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_LOCAL_MEM, &I,
6385 &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006386 else
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006387 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_ARGUMENT_MEM, &I,
6388 &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006389 return true;
6390 }
6391 if (auto *GV = dyn_cast<GlobalValue>(&V)) {
6392 if (GV->hasLocalLinkage())
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006393 updateStateAndAccessesMap(T, AccessKindAccessesMap,
6394 NO_GLOBAL_INTERNAL_MEM, &I, &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006395 else
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006396 updateStateAndAccessesMap(T, AccessKindAccessesMap,
6397 NO_GLOBAL_EXTERNAL_MEM, &I, &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006398 return true;
6399 }
6400 if (isa<AllocaInst>(V)) {
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006401 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_LOCAL_MEM, &I, &V,
6402 Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006403 return true;
6404 }
6405 if (ImmutableCallSite ICS = ImmutableCallSite(&V)) {
6406 const auto &NoAliasAA =
6407 A.getAAFor<AANoAlias>(*this, IRPosition::callsite_returned(ICS));
6408 if (NoAliasAA.isAssumedNoAlias()) {
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006409 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_MALLOCED_MEM, &I,
6410 &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006411 return true;
6412 }
6413 }
6414
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006415 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_UNKOWN_MEM, &I, &V,
6416 Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006417 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value cannot be categorized: "
6418 << V << " -> " << getMemoryLocationsAsStr(T.getAssumed())
6419 << "\n");
6420 return true;
6421 };
6422
6423 if (!genericValueTraversal<AAMemoryLocation, AAMemoryLocation::StateType>(
6424 A, IRPosition::value(Ptr), *this, State, VisitValueCB,
6425 /* MaxValues */ 32, StripGEPCB)) {
6426 LLVM_DEBUG(
6427 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006428 updateStateAndAccessesMap(State, AccessKindAccessesMap, NO_UNKOWN_MEM, &I,
6429 nullptr, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006430 } else {
6431 LLVM_DEBUG(
6432 dbgs()
6433 << "[AAMemoryLocation] Accessed locations with pointer locations: "
6434 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
6435 }
6436}
6437
6438AAMemoryLocation::MemoryLocationsKind
6439AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
6440 bool &Changed) {
6441 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
6442 << I << "\n");
6443
6444 AAMemoryLocation::StateType AccessedLocs;
6445 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
6446
6447 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
6448
6449 // First check if we assume any memory is access is visible.
6450 const auto &ICSMemLocationAA =
6451 A.getAAFor<AAMemoryLocation>(*this, IRPosition::callsite_function(ICS));
6452 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
6453 << " [" << ICSMemLocationAA << "]\n");
6454
6455 if (ICSMemLocationAA.isAssumedReadNone())
6456 return NO_LOCATIONS;
6457
6458 if (ICSMemLocationAA.isAssumedInaccessibleMemOnly()) {
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006459 updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap,
6460 NO_INACCESSIBLE_MEM, &I, nullptr, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006461 return AccessedLocs.getAssumed();
6462 }
6463
6464 uint32_t ICSAssumedNotAccessedLocs =
6465 ICSMemLocationAA.getAssumedNotAccessedLocation();
6466
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006467 // Set the argmemonly and global bit as we handle them separately below.
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006468 uint32_t ICSAssumedNotAccessedLocsNoArgMem =
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006469 ICSAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006470
6471 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
6472 if (ICSAssumedNotAccessedLocsNoArgMem & CurMLK)
6473 continue;
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006474 updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap, CurMLK, &I,
6475 nullptr, Changed);
6476 }
6477
6478 // Now handle global memory if it might be accessed.
6479 bool HasGlobalAccesses = !(ICSAssumedNotAccessedLocs & NO_GLOBAL_MEM);
6480 if (HasGlobalAccesses) {
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006481 auto AccessPred = [&](const Instruction *, const Value *Ptr,
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006482 AccessKind Kind, MemoryLocationsKind MLK) {
6483 updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap, MLK, &I,
6484 Ptr, Changed);
6485 return true;
6486 };
6487 if (!ICSMemLocationAA.checkForAllAccessesToMemoryKind(
6488 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
6489 return AccessedLocs.getWorstState();
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006490 }
6491
6492 LLVM_DEBUG(
6493 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
6494 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
6495
6496 // Now handle argument memory if it might be accessed.
6497 bool HasArgAccesses = !(ICSAssumedNotAccessedLocs & NO_ARGUMENT_MEM);
6498 if (HasArgAccesses) {
6499 for (unsigned ArgNo = 0, e = ICS.getNumArgOperands(); ArgNo < e;
6500 ++ArgNo) {
6501
6502 // Skip non-pointer arguments.
6503 const Value *ArgOp = ICS.getArgOperand(ArgNo);
6504 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
6505 continue;
6506
6507 // Skip readnone arguments.
6508 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(ICS, ArgNo);
6509 const auto &ArgOpMemLocationAA = A.getAAFor<AAMemoryBehavior>(
6510 *this, ArgOpIRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
6511
6512 if (ArgOpMemLocationAA.isAssumedReadNone())
6513 continue;
6514
6515 // Categorize potentially accessed pointer arguments as if there was an
6516 // access instruction with them as pointer.
6517 categorizePtrValue(A, I, *ArgOp, AccessedLocs, Changed);
6518 }
6519 }
6520
6521 LLVM_DEBUG(
6522 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
6523 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
6524
6525 return AccessedLocs.getAssumed();
6526 }
6527
6528 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
6529 LLVM_DEBUG(
6530 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
6531 << I << " [" << *Ptr << "]\n");
6532 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed);
6533 return AccessedLocs.getAssumed();
6534 }
6535
6536 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
6537 << I << "\n");
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006538 updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap, NO_UNKOWN_MEM,
6539 &I, nullptr, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006540 return AccessedLocs.getAssumed();
6541}
6542
6543/// An AA to represent the memory behavior function attributes.
6544struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
6545 AAMemoryLocationFunction(const IRPosition &IRP) : AAMemoryLocationImpl(IRP) {}
6546
6547 /// See AbstractAttribute::updateImpl(Attributor &A).
6548 virtual ChangeStatus updateImpl(Attributor &A) override {
6549
6550 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
6551 *this, getIRPosition(), /* TrackDependence */ false);
6552 if (MemBehaviorAA.isAssumedReadNone()) {
6553 if (MemBehaviorAA.isKnownReadNone())
6554 return indicateOptimisticFixpoint();
6555 assert(isAssumedReadNone() &&
6556 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
6557 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
6558 return ChangeStatus::UNCHANGED;
6559 }
6560
6561 // The current assumed state used to determine a change.
6562 auto AssumedState = getAssumed();
6563 bool Changed = false;
6564
6565 auto CheckRWInst = [&](Instruction &I) {
6566 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
6567 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
6568 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
6569 removeAssumedBits(inverseLocation(MLK, false, false));
6570 return true;
6571 };
6572
6573 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
6574 return indicatePessimisticFixpoint();
6575
6576 Changed |= AssumedState != getAssumed();
6577 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
6578 }
6579
6580 /// See AbstractAttribute::trackStatistics()
6581 void trackStatistics() const override {
6582 if (isAssumedReadNone())
6583 STATS_DECLTRACK_FN_ATTR(readnone)
6584 else if (isAssumedArgMemOnly())
6585 STATS_DECLTRACK_FN_ATTR(argmemonly)
6586 else if (isAssumedInaccessibleMemOnly())
6587 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
6588 else if (isAssumedInaccessibleOrArgMemOnly())
6589 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
6590 }
6591};
6592
6593/// AAMemoryLocation attribute for call sites.
6594struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
6595 AAMemoryLocationCallSite(const IRPosition &IRP) : AAMemoryLocationImpl(IRP) {}
6596
6597 /// See AbstractAttribute::initialize(...).
6598 void initialize(Attributor &A) override {
6599 AAMemoryLocationImpl::initialize(A);
6600 Function *F = getAssociatedFunction();
6601 if (!F || !F->hasExactDefinition())
6602 indicatePessimisticFixpoint();
6603 }
6604
6605 /// See AbstractAttribute::updateImpl(...).
6606 ChangeStatus updateImpl(Attributor &A) override {
6607 // TODO: Once we have call site specific value information we can provide
6608 // call site specific liveness liveness information and then it makes
6609 // sense to specialize attributes for call sites arguments instead of
6610 // redirecting requests to the callee argument.
6611 Function *F = getAssociatedFunction();
6612 const IRPosition &FnPos = IRPosition::function(*F);
6613 auto &FnAA = A.getAAFor<AAMemoryLocation>(*this, FnPos);
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006614 bool Changed = false;
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006615 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006616 AccessKind Kind, MemoryLocationsKind MLK) {
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006617 updateStateAndAccessesMap(getState(), AccessKindAccessesMap, MLK, I, Ptr,
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006618 Changed);
6619 return true;
6620 };
6621 if (!FnAA.checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
6622 return indicatePessimisticFixpoint();
6623 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006624 }
6625
6626 /// See AbstractAttribute::trackStatistics()
6627 void trackStatistics() const override {
6628 if (isAssumedReadNone())
6629 STATS_DECLTRACK_CS_ATTR(readnone)
6630 }
6631};
6632
Hideto Ueno188f9a32020-01-15 15:25:52 +09006633/// ------------------ Value Constant Range Attribute -------------------------
Hideto Uenoe9963032020-01-01 15:25:19 +09006634
Hideto Ueno188f9a32020-01-15 15:25:52 +09006635struct AAValueConstantRangeImpl : AAValueConstantRange {
6636 using StateType = IntegerRangeState;
6637 AAValueConstantRangeImpl(const IRPosition &IRP) : AAValueConstantRange(IRP) {}
6638
6639 /// See AbstractAttribute::getAsStr().
6640 const std::string getAsStr() const override {
6641 std::string Str;
6642 llvm::raw_string_ostream OS(Str);
6643 OS << "range(" << getBitWidth() << ")<";
6644 getKnown().print(OS);
6645 OS << " / ";
6646 getAssumed().print(OS);
6647 OS << ">";
6648 return OS.str();
6649 }
6650
6651 /// Helper function to get a SCEV expr for the associated value at program
6652 /// point \p I.
6653 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
6654 if (!getAnchorScope())
6655 return nullptr;
6656
6657 ScalarEvolution *SE =
6658 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
6659 *getAnchorScope());
6660
6661 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
6662 *getAnchorScope());
6663
6664 if (!SE || !LI)
6665 return nullptr;
6666
6667 const SCEV *S = SE->getSCEV(&getAssociatedValue());
6668 if (!I)
6669 return S;
6670
6671 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
6672 }
6673
6674 /// Helper function to get a range from SCEV for the associated value at
6675 /// program point \p I.
6676 ConstantRange getConstantRangeFromSCEV(Attributor &A,
6677 const Instruction *I = nullptr) const {
6678 if (!getAnchorScope())
6679 return getWorstState(getBitWidth());
6680
6681 ScalarEvolution *SE =
6682 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
6683 *getAnchorScope());
6684
6685 const SCEV *S = getSCEV(A, I);
6686 if (!SE || !S)
6687 return getWorstState(getBitWidth());
6688
6689 return SE->getUnsignedRange(S);
6690 }
6691
6692 /// Helper function to get a range from LVI for the associated value at
6693 /// program point \p I.
6694 ConstantRange
6695 getConstantRangeFromLVI(Attributor &A,
6696 const Instruction *CtxI = nullptr) const {
6697 if (!getAnchorScope())
6698 return getWorstState(getBitWidth());
6699
6700 LazyValueInfo *LVI =
6701 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
6702 *getAnchorScope());
6703
6704 if (!LVI || !CtxI)
6705 return getWorstState(getBitWidth());
6706 return LVI->getConstantRange(&getAssociatedValue(),
6707 const_cast<BasicBlock *>(CtxI->getParent()),
6708 const_cast<Instruction *>(CtxI));
6709 }
6710
6711 /// See AAValueConstantRange::getKnownConstantRange(..).
6712 ConstantRange
6713 getKnownConstantRange(Attributor &A,
6714 const Instruction *CtxI = nullptr) const override {
6715 if (!CtxI || CtxI == getCtxI())
6716 return getKnown();
6717
6718 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
6719 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
6720 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
6721 }
6722
6723 /// See AAValueConstantRange::getAssumedConstantRange(..).
6724 ConstantRange
6725 getAssumedConstantRange(Attributor &A,
6726 const Instruction *CtxI = nullptr) const override {
6727 // TODO: Make SCEV use Attributor assumption.
6728 // We may be able to bound a variable range via assumptions in
6729 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
6730 // evolve to x^2 + x, then we can say that y is in [2, 12].
6731
6732 if (!CtxI || CtxI == getCtxI())
6733 return getAssumed();
6734
6735 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
6736 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
6737 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
6738 }
6739
6740 /// See AbstractAttribute::initialize(..).
6741 void initialize(Attributor &A) override {
6742 // Intersect a range given by SCEV.
6743 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
6744
6745 // Intersect a range given by LVI.
6746 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
6747 }
6748
6749 /// Helper function to create MDNode for range metadata.
6750 static MDNode *
6751 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
6752 const ConstantRange &AssumedConstantRange) {
6753 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
6754 Ty, AssumedConstantRange.getLower())),
6755 ConstantAsMetadata::get(ConstantInt::get(
6756 Ty, AssumedConstantRange.getUpper()))};
6757 return MDNode::get(Ctx, LowAndHigh);
6758 }
6759
6760 /// Return true if \p Assumed is included in \p KnownRanges.
6761 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) {
6762
6763 if (Assumed.isFullSet())
6764 return false;
6765
6766 if (!KnownRanges)
6767 return true;
6768
6769 // If multiple ranges are annotated in IR, we give up to annotate assumed
6770 // range for now.
6771
6772 // TODO: If there exists a known range which containts assumed range, we
6773 // can say assumed range is better.
6774 if (KnownRanges->getNumOperands() > 2)
6775 return false;
6776
6777 ConstantInt *Lower =
6778 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
6779 ConstantInt *Upper =
6780 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
6781
6782 ConstantRange Known(Lower->getValue(), Upper->getValue());
6783 return Known.contains(Assumed) && Known != Assumed;
6784 }
6785
6786 /// Helper function to set range metadata.
6787 static bool
6788 setRangeMetadataIfisBetterRange(Instruction *I,
6789 const ConstantRange &AssumedConstantRange) {
6790 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range);
6791 if (isBetterRange(AssumedConstantRange, OldRangeMD)) {
6792 if (!AssumedConstantRange.isEmptySet()) {
6793 I->setMetadata(LLVMContext::MD_range,
6794 getMDNodeForConstantRange(I->getType(), I->getContext(),
6795 AssumedConstantRange));
6796 return true;
6797 }
6798 }
6799 return false;
6800 }
6801
6802 /// See AbstractAttribute::manifest()
6803 ChangeStatus manifest(Attributor &A) override {
6804 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6805 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
6806 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
6807
6808 auto &V = getAssociatedValue();
6809 if (!AssumedConstantRange.isEmptySet() &&
6810 !AssumedConstantRange.isSingleElement()) {
6811 if (Instruction *I = dyn_cast<Instruction>(&V))
6812 if (isa<CallInst>(I) || isa<LoadInst>(I))
6813 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
6814 Changed = ChangeStatus::CHANGED;
6815 }
6816
6817 return Changed;
6818 }
6819};
6820
Johannes Doerfertea5fabe2020-01-28 09:46:15 -06006821struct AAValueConstantRangeArgument final
6822 : AAArgumentFromCallSiteArguments<
6823 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState> {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006824 AAValueConstantRangeArgument(const IRPosition &IRP)
Johannes Doerfertea5fabe2020-01-28 09:46:15 -06006825 : AAArgumentFromCallSiteArguments<
6826 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState>(
6827 IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006828
6829 /// See AbstractAttribute::trackStatistics()
6830 void trackStatistics() const override {
6831 STATS_DECLTRACK_ARG_ATTR(value_range)
6832 }
6833};
6834
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006835struct AAValueConstantRangeReturned
6836 : AAReturnedFromReturnedValues<AAValueConstantRange,
6837 AAValueConstantRangeImpl> {
6838 using Base = AAReturnedFromReturnedValues<AAValueConstantRange,
6839 AAValueConstantRangeImpl>;
6840 AAValueConstantRangeReturned(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006841
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006842 /// See AbstractAttribute::initialize(...).
6843 void initialize(Attributor &A) override {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006844
6845 /// See AbstractAttribute::trackStatistics()
6846 void trackStatistics() const override {
6847 STATS_DECLTRACK_FNRET_ATTR(value_range)
6848 }
6849};
6850
6851struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
6852 AAValueConstantRangeFloating(const IRPosition &IRP)
6853 : AAValueConstantRangeImpl(IRP) {}
6854
6855 /// See AbstractAttribute::initialize(...).
6856 void initialize(Attributor &A) override {
Johannes Doerfert028db8c42020-02-09 19:05:15 -06006857 AAValueConstantRangeImpl::initialize(A);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006858 Value &V = getAssociatedValue();
6859
6860 if (auto *C = dyn_cast<ConstantInt>(&V)) {
6861 unionAssumed(ConstantRange(C->getValue()));
6862 indicateOptimisticFixpoint();
6863 return;
6864 }
6865
6866 if (isa<UndefValue>(&V)) {
Johannes Doerfertb53af0e2020-02-14 20:08:20 -06006867 // Collapse the undef state to 0.
6868 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
Hideto Ueno188f9a32020-01-15 15:25:52 +09006869 indicateOptimisticFixpoint();
6870 return;
6871 }
6872
Johannes Doerfert7cbb1072020-02-13 14:22:26 -06006873 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
6874 return;
Hideto Ueno188f9a32020-01-15 15:25:52 +09006875 // If it is a load instruction with range metadata, use it.
6876 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
6877 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
6878 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
6879 return;
6880 }
6881
Johannes Doerfert81554392020-02-09 20:14:35 -06006882 // We can work with PHI and select instruction as we traverse their operands
Johannes Doerfert7e7e6592020-02-09 19:08:04 -06006883 // during update.
Johannes Doerfert81554392020-02-09 20:14:35 -06006884 if (isa<SelectInst>(V) || isa<PHINode>(V))
Johannes Doerfert7e7e6592020-02-09 19:08:04 -06006885 return;
6886
Hideto Ueno188f9a32020-01-15 15:25:52 +09006887 // Otherwise we give up.
6888 indicatePessimisticFixpoint();
6889
Johannes Doerfert02bd8182020-01-28 11:49:35 -06006890 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
6891 << getAssociatedValue() << "\n");
Hideto Ueno188f9a32020-01-15 15:25:52 +09006892 }
6893
Johannes Doerfert81554392020-02-09 20:14:35 -06006894 bool calculateBinaryOperator(
6895 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
6896 Instruction *CtxI,
6897 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006898 Value *LHS = BinOp->getOperand(0);
6899 Value *RHS = BinOp->getOperand(1);
Johannes Doerfert7cbb1072020-02-13 14:22:26 -06006900 // TODO: Allow non integers as well.
6901 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
6902 return false;
Hideto Ueno188f9a32020-01-15 15:25:52 +09006903
6904 auto &LHSAA =
6905 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006906 QuerriedAAs.push_back(&LHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006907 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
6908
6909 auto &RHSAA =
6910 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006911 QuerriedAAs.push_back(&RHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006912 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
6913
6914 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
6915
6916 T.unionAssumed(AssumedRange);
6917
6918 // TODO: Track a known state too.
6919
6920 return T.isValidState();
6921 }
6922
Johannes Doerfert81554392020-02-09 20:14:35 -06006923 bool calculateCastInst(
6924 Attributor &A, CastInst *CastI, IntegerRangeState &T, Instruction *CtxI,
6925 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006926 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
6927 // TODO: Allow non integers as well.
6928 Value &OpV = *CastI->getOperand(0);
Johannes Doerfert7cbb1072020-02-13 14:22:26 -06006929 if (!OpV.getType()->isIntegerTy())
6930 return false;
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006931
6932 auto &OpAA =
6933 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV));
Johannes Doerfert81554392020-02-09 20:14:35 -06006934 QuerriedAAs.push_back(&OpAA);
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006935 T.unionAssumed(
6936 OpAA.getAssumed().castOp(CastI->getOpcode(), getState().getBitWidth()));
6937 return T.isValidState();
6938 }
6939
Johannes Doerfert81554392020-02-09 20:14:35 -06006940 bool
6941 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
6942 Instruction *CtxI,
6943 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006944 Value *LHS = CmpI->getOperand(0);
6945 Value *RHS = CmpI->getOperand(1);
Johannes Doerfert7cbb1072020-02-13 14:22:26 -06006946 // TODO: Allow non integers as well.
6947 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
6948 return false;
Hideto Ueno188f9a32020-01-15 15:25:52 +09006949
6950 auto &LHSAA =
6951 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006952 QuerriedAAs.push_back(&LHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006953 auto &RHSAA =
6954 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006955 QuerriedAAs.push_back(&RHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006956
6957 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
6958 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
6959
6960 // If one of them is empty set, we can't decide.
6961 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
6962 return true;
6963
6964 bool MustTrue = false, MustFalse = false;
6965
6966 auto AllowedRegion =
6967 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange);
6968
6969 auto SatisfyingRegion = ConstantRange::makeSatisfyingICmpRegion(
6970 CmpI->getPredicate(), RHSAARange);
6971
6972 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
6973 MustFalse = true;
6974
6975 if (SatisfyingRegion.contains(LHSAARange))
6976 MustTrue = true;
6977
6978 assert((!MustTrue || !MustFalse) &&
6979 "Either MustTrue or MustFalse should be false!");
6980
6981 if (MustTrue)
6982 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
6983 else if (MustFalse)
6984 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
6985 else
6986 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
6987
6988 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " " << LHSAA
6989 << " " << RHSAA << "\n");
6990
6991 // TODO: Track a known state too.
6992 return T.isValidState();
6993 }
6994
6995 /// See AbstractAttribute::updateImpl(...).
6996 ChangeStatus updateImpl(Attributor &A) override {
6997 Instruction *CtxI = getCtxI();
6998 auto VisitValueCB = [&](Value &V, IntegerRangeState &T,
6999 bool Stripped) -> bool {
7000 Instruction *I = dyn_cast<Instruction>(&V);
7001 if (!I) {
7002
7003 // If the value is not instruction, we query AA to Attributor.
7004 const auto &AA =
7005 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(V));
7006
7007 // Clamp operator is not used to utilize a program point CtxI.
7008 T.unionAssumed(AA.getAssumedConstantRange(A, CtxI));
7009
7010 return T.isValidState();
7011 }
7012
Johannes Doerfert81554392020-02-09 20:14:35 -06007013 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs;
7014 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
7015 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
7016 return false;
7017 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
7018 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
7019 return false;
7020 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
7021 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
7022 return false;
7023 } else {
Hideto Ueno188f9a32020-01-15 15:25:52 +09007024 // Give up with other instructions.
7025 // TODO: Add other instructions
7026
7027 T.indicatePessimisticFixpoint();
7028 return false;
7029 }
Johannes Doerfert81554392020-02-09 20:14:35 -06007030
7031 // Catch circular reasoning in a pessimistic way for now.
7032 // TODO: Check how the range evolves and if we stripped anything, see also
7033 // AADereferenceable or AAAlign for similar situations.
7034 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
7035 if (QueriedAA != this)
7036 continue;
7037 // If we are in a stady state we do not need to worry.
7038 if (T.getAssumed() == getState().getAssumed())
7039 continue;
7040 T.indicatePessimisticFixpoint();
7041 }
7042
7043 return T.isValidState();
Hideto Ueno188f9a32020-01-15 15:25:52 +09007044 };
7045
7046 IntegerRangeState T(getBitWidth());
7047
7048 if (!genericValueTraversal<AAValueConstantRange, IntegerRangeState>(
7049 A, getIRPosition(), *this, T, VisitValueCB))
7050 return indicatePessimisticFixpoint();
7051
7052 return clampStateAndIndicateChange(getState(), T);
7053 }
7054
7055 /// See AbstractAttribute::trackStatistics()
7056 void trackStatistics() const override {
7057 STATS_DECLTRACK_FLOATING_ATTR(value_range)
7058 }
7059};
7060
7061struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
7062 AAValueConstantRangeFunction(const IRPosition &IRP)
7063 : AAValueConstantRangeImpl(IRP) {}
7064
7065 /// See AbstractAttribute::initialize(...).
7066 ChangeStatus updateImpl(Attributor &A) override {
7067 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
7068 "not be called");
7069 }
7070
7071 /// See AbstractAttribute::trackStatistics()
7072 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
7073};
7074
7075struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
7076 AAValueConstantRangeCallSite(const IRPosition &IRP)
7077 : AAValueConstantRangeFunction(IRP) {}
7078
7079 /// See AbstractAttribute::trackStatistics()
7080 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
7081};
7082
Johannes Doerfert791c9f12020-01-29 18:02:42 -06007083struct AAValueConstantRangeCallSiteReturned
7084 : AACallSiteReturnedFromReturned<AAValueConstantRange,
7085 AAValueConstantRangeImpl> {
Hideto Ueno188f9a32020-01-15 15:25:52 +09007086 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP)
Johannes Doerfert791c9f12020-01-29 18:02:42 -06007087 : AACallSiteReturnedFromReturned<AAValueConstantRange,
7088 AAValueConstantRangeImpl>(IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09007089
7090 /// See AbstractAttribute::initialize(...).
7091 void initialize(Attributor &A) override {
7092 // If it is a load instruction with range metadata, use the metadata.
7093 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue()))
7094 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range))
7095 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
7096
Johannes Doerfert791c9f12020-01-29 18:02:42 -06007097 AAValueConstantRangeImpl::initialize(A);
Hideto Ueno188f9a32020-01-15 15:25:52 +09007098 }
7099
7100 /// See AbstractAttribute::trackStatistics()
7101 void trackStatistics() const override {
7102 STATS_DECLTRACK_CSRET_ATTR(value_range)
7103 }
7104};
7105struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
7106 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP)
7107 : AAValueConstantRangeFloating(IRP) {}
7108
7109 /// See AbstractAttribute::trackStatistics()
7110 void trackStatistics() const override {
7111 STATS_DECLTRACK_CSARG_ATTR(value_range)
7112 }
7113};
Benjamin Kramer564a9de2020-02-17 17:55:03 +01007114
7115} // namespace
Johannes Doerfertaade7822019-06-05 03:02:24 +00007116/// ----------------------------------------------------------------------------
7117/// Attributor
7118/// ----------------------------------------------------------------------------
7119
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007120bool Attributor::isAssumedDead(const AbstractAttribute &AA,
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007121 const AAIsDead *FnLivenessAA,
7122 bool CheckBBLivenessOnly, DepClassTy DepClass) {
7123 const IRPosition &IRP = AA.getIRPosition();
7124 if (!Functions.count(IRP.getAnchorScope()))
7125 return false;
7126 return isAssumedDead(IRP, &AA, FnLivenessAA, CheckBBLivenessOnly, DepClass);
7127}
7128
7129bool Attributor::isAssumedDead(const Use &U,
7130 const AbstractAttribute *QueryingAA,
7131 const AAIsDead *FnLivenessAA,
7132 bool CheckBBLivenessOnly, DepClassTy DepClass) {
7133 Instruction *UserI = dyn_cast<Instruction>(U.getUser());
7134 if (!UserI)
7135 return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
7136 CheckBBLivenessOnly, DepClass);
7137
7138 if (CallSite CS = CallSite(UserI)) {
7139 // For call site argument uses we can check if the argument is
7140 // unused/dead.
7141 if (CS.isArgOperand(&U)) {
7142 const IRPosition &CSArgPos =
7143 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
7144 return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
7145 CheckBBLivenessOnly, DepClass);
7146 }
7147 } else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
7148 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
7149 return isAssumedDead(RetPos, QueryingAA, FnLivenessAA, CheckBBLivenessOnly,
7150 DepClass);
7151 } else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
7152 BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
7153 return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
7154 CheckBBLivenessOnly, DepClass);
7155 }
7156
7157 return isAssumedDead(IRPosition::value(*UserI), QueryingAA, FnLivenessAA,
7158 CheckBBLivenessOnly, DepClass);
7159}
7160
7161bool Attributor::isAssumedDead(const Instruction &I,
7162 const AbstractAttribute *QueryingAA,
7163 const AAIsDead *FnLivenessAA,
7164 bool CheckBBLivenessOnly, DepClassTy DepClass) {
7165 if (!FnLivenessAA)
7166 FnLivenessAA = lookupAAFor<AAIsDead>(IRPosition::function(*I.getFunction()),
7167 QueryingAA,
7168 /* TrackDependence */ false);
7169
7170 // If we have a context instruction and a liveness AA we use it.
7171 if (FnLivenessAA &&
7172 FnLivenessAA->getIRPosition().getAnchorScope() == I.getFunction() &&
7173 FnLivenessAA->isAssumedDead(&I)) {
7174 if (QueryingAA)
7175 recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
7176 return true;
7177 }
7178
7179 if (CheckBBLivenessOnly)
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007180 return false;
7181
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007182 const AAIsDead &IsDeadAA = getOrCreateAAFor<AAIsDead>(
7183 IRPosition::value(I), QueryingAA, /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00007184 // Don't check liveness for AAIsDead.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007185 if (QueryingAA == &IsDeadAA)
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00007186 return false;
7187
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007188 if (IsDeadAA.isAssumedDead()) {
7189 if (QueryingAA)
7190 recordDependence(IsDeadAA, *QueryingAA, DepClass);
7191 return true;
7192 }
7193
7194 return false;
7195}
7196
7197bool Attributor::isAssumedDead(const IRPosition &IRP,
7198 const AbstractAttribute *QueryingAA,
7199 const AAIsDead *FnLivenessAA,
7200 bool CheckBBLivenessOnly, DepClassTy DepClass) {
7201 Instruction *CtxI = IRP.getCtxI();
7202 if (CtxI &&
7203 isAssumedDead(*CtxI, QueryingAA, FnLivenessAA,
7204 /* CheckBBLivenessOnly */ true,
7205 CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
7206 return true;
7207
7208 if (CheckBBLivenessOnly)
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007209 return false;
7210
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007211 // If we haven't succeeded we query the specific liveness info for the IRP.
7212 const AAIsDead *IsDeadAA;
7213 if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE)
7214 IsDeadAA = &getOrCreateAAFor<AAIsDead>(
7215 IRPosition::callsite_returned(cast<CallBase>(IRP.getAssociatedValue())),
7216 QueryingAA, /* TrackDependence */ false);
7217 else
7218 IsDeadAA = &getOrCreateAAFor<AAIsDead>(IRP, QueryingAA,
7219 /* TrackDependence */ false);
7220 // Don't check liveness for AAIsDead.
7221 if (QueryingAA == IsDeadAA)
7222 return false;
Johannes Doerfert19b00432019-08-26 17:48:05 +00007223
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007224 if (IsDeadAA->isAssumedDead()) {
7225 if (QueryingAA)
7226 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
7227 return true;
7228 }
7229
7230 return false;
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007231}
7232
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007233bool Attributor::checkForAllUses(
7234 const function_ref<bool(const Use &, bool &)> &Pred,
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007235 const AbstractAttribute &QueryingAA, const Value &V,
7236 DepClassTy LivenessDepClass) {
Johannes Doerfertb2c76002020-01-23 17:12:56 -06007237
7238 // Check the trivial case first as it catches void values.
7239 if (V.use_empty())
7240 return true;
7241
7242 // If the value is replaced by another one, for now a constant, we do not have
7243 // uses. Note that this requires users of `checkForAllUses` to not recurse but
7244 // instead use the `follow` callback argument to look at transitive users,
7245 // however, that should be clear from the presence of the argument.
7246 bool UsedAssumedInformation = false;
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06007247 Optional<Constant *> C =
Johannes Doerfertb2c76002020-01-23 17:12:56 -06007248 getAssumedConstant(*this, V, QueryingAA, UsedAssumedInformation);
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06007249 if (C.hasValue() && C.getValue()) {
Johannes Doerfertb2c76002020-01-23 17:12:56 -06007250 LLVM_DEBUG(dbgs() << "[Attributor] Value is simplified, uses skipped: " << V
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06007251 << " -> " << *C.getValue() << "\n");
Johannes Doerfertb2c76002020-01-23 17:12:56 -06007252 return true;
7253 }
7254
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007255 const IRPosition &IRP = QueryingAA.getIRPosition();
7256 SmallVector<const Use *, 16> Worklist;
7257 SmallPtrSet<const Use *, 16> Visited;
7258
7259 for (const Use &U : V.uses())
7260 Worklist.push_back(&U);
7261
7262 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
7263 << " initial uses to check\n");
7264
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007265 const Function *ScopeFn = IRP.getAnchorScope();
7266 const auto *LivenessAA =
7267 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
7268 /* TrackDependence */ false)
7269 : nullptr;
7270
7271 while (!Worklist.empty()) {
7272 const Use *U = Worklist.pop_back_val();
7273 if (!Visited.insert(U).second)
7274 continue;
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007275 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << " in "
7276 << *U->getUser() << "\n");
7277 if (isAssumedDead(*U, &QueryingAA, LivenessAA,
7278 /* CheckBBLivenessOnly */ false, LivenessDepClass)) {
7279 LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
7280 continue;
Johannes Doerfert8e629682020-02-11 00:10:35 -06007281 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007282
7283 bool Follow = false;
7284 if (!Pred(*U, Follow))
7285 return false;
7286 if (!Follow)
7287 continue;
7288 for (const Use &UU : U->getUser()->uses())
7289 Worklist.push_back(&UU);
7290 }
7291
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007292 return true;
7293}
7294
Johannes Doerfert661db042019-10-07 23:14:58 +00007295bool Attributor::checkForAllCallSites(
7296 const function_ref<bool(AbstractCallSite)> &Pred,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007297 const AbstractAttribute &QueryingAA, bool RequireAllCallSites,
7298 bool &AllCallSitesKnown) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00007299 // We can try to determine information from
7300 // the call sites. However, this is only possible all call sites are known,
7301 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007302 const IRPosition &IRP = QueryingAA.getIRPosition();
7303 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00007304 if (!AssociatedFunction) {
7305 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
7306 << "\n");
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007307 AllCallSitesKnown = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007308 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00007309 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007310
Johannes Doerfert3753aa72019-10-13 04:16:02 +00007311 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007312 &QueryingAA, AllCallSitesKnown);
Johannes Doerfert3753aa72019-10-13 04:16:02 +00007313}
7314
7315bool Attributor::checkForAllCallSites(
7316 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007317 bool RequireAllCallSites, const AbstractAttribute *QueryingAA,
7318 bool &AllCallSitesKnown) {
Johannes Doerfert3753aa72019-10-13 04:16:02 +00007319 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00007320 LLVM_DEBUG(
7321 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00007322 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00007323 << " has no internal linkage, hence not all call sites are known\n");
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007324 AllCallSitesKnown = false;
Hideto Ueno54869ec2019-07-15 06:49:04 +00007325 return false;
7326 }
7327
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007328 // If we do not require all call sites we might not see all.
7329 AllCallSitesKnown = RequireAllCallSites;
7330
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06007331 SmallVector<const Use *, 8> Uses(make_pointer_range(Fn.uses()));
7332 for (unsigned u = 0; u < Uses.size(); ++u) {
7333 const Use &U = *Uses[u];
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007334 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << *U << " in "
7335 << *U.getUser() << "\n");
7336 if (isAssumedDead(U, QueryingAA, nullptr, /* CheckBBLivenessOnly */ true)) {
7337 LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
7338 continue;
7339 }
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06007340 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
7341 if (CE->isCast() && CE->getType()->isPointerTy() &&
7342 CE->getType()->getPointerElementType()->isFunctionTy()) {
7343 for (const Use &CEU : CE->uses())
7344 Uses.push_back(&CEU);
7345 continue;
7346 }
7347 }
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007348
Johannes Doerfert661db042019-10-07 23:14:58 +00007349 AbstractCallSite ACS(&U);
7350 if (!ACS) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007351 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00007352 << " has non call site use " << *U.get() << " in "
7353 << *U.getUser() << "\n");
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05007354 // BlockAddress users are allowed.
7355 if (isa<BlockAddress>(U.getUser()))
7356 continue;
Johannes Doerfertd98f9752019-08-21 21:48:56 +00007357 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00007358 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00007359
Johannes Doerfert661db042019-10-07 23:14:58 +00007360 const Use *EffectiveUse =
7361 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
7362 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00007363 if (!RequireAllCallSites)
7364 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00007365 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007366 << " is an invalid use of " << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00007367 return false;
7368 }
7369
Johannes Doerfert1e99fc92020-02-16 16:42:47 -06007370 // Make sure the arguments that can be matched between the call site and the
7371 // callee argee on their type. It is unlikely they do not and it doesn't
7372 // make sense for all attributes to know/care about this.
7373 assert(&Fn == ACS.getCalledFunction() && "Expected known callee");
7374 unsigned MinArgsParams =
7375 std::min(size_t(ACS.getNumArgOperands()), Fn.arg_size());
7376 for (unsigned u = 0; u < MinArgsParams; ++u) {
7377 Value *CSArgOp = ACS.getCallArgOperand(u);
7378 if (CSArgOp && Fn.getArg(u)->getType() != CSArgOp->getType()) {
7379 LLVM_DEBUG(
7380 dbgs() << "[Attributor] Call site / callee argument type mismatch ["
7381 << u << "@" << Fn.getName() << ": "
7382 << *Fn.getArg(u)->getType() << " vs. "
7383 << *ACS.getCallArgOperand(u)->getType() << "\n");
7384 return false;
7385 }
7386 }
7387
Johannes Doerfert661db042019-10-07 23:14:58 +00007388 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00007389 continue;
7390
Johannes Doerfert5304b722019-08-14 22:04:28 +00007391 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00007392 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00007393 return false;
7394 }
7395
7396 return true;
7397}
7398
Johannes Doerfert14a04932019-08-07 22:27:24 +00007399bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00007400 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00007401 &Pred,
7402 const AbstractAttribute &QueryingAA) {
7403
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007404 const IRPosition &IRP = QueryingAA.getIRPosition();
7405 // Since we need to provide return instructions we have to have an exact
7406 // definition.
7407 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00007408 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00007409 return false;
7410
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007411 // If this is a call site query we use the call site specific return values
7412 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00007413 // TODO: use the function scope once we have call site AAReturnedValues.
7414 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007415 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007416 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007417 return false;
7418
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007419 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00007420}
7421
7422bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007423 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00007424 const AbstractAttribute &QueryingAA) {
7425
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007426 const IRPosition &IRP = QueryingAA.getIRPosition();
7427 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00007428 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00007429 return false;
7430
Johannes Doerfert07a5c122019-08-28 14:09:14 +00007431 // TODO: use the function scope once we have call site AAReturnedValues.
7432 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007433 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007434 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007435 return false;
7436
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007437 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00007438 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00007439 return Pred(RV);
7440 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00007441}
7442
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007443static bool checkForAllInstructionsImpl(
7444 Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap,
7445 const function_ref<bool(Instruction &)> &Pred,
7446 const AbstractAttribute *QueryingAA, const AAIsDead *LivenessAA,
7447 const ArrayRef<unsigned> &Opcodes, bool CheckBBLivenessOnly = false) {
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007448 for (unsigned Opcode : Opcodes) {
7449 for (Instruction *I : OpcodeInstMap[Opcode]) {
7450 // Skip dead instructions.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007451 if (A && A->isAssumedDead(IRPosition::value(*I), QueryingAA, LivenessAA,
7452 CheckBBLivenessOnly))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007453 continue;
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007454
7455 if (!Pred(*I))
7456 return false;
7457 }
7458 }
7459 return true;
7460}
7461
Johannes Doerfertd0f64002019-08-06 00:32:43 +00007462bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007463 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007464 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes,
7465 bool CheckBBLivenessOnly) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00007466
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007467 const IRPosition &IRP = QueryingAA.getIRPosition();
7468 // Since we need to provide instructions we have to have an exact definition.
7469 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00007470 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007471 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00007472
Johannes Doerfert07a5c122019-08-28 14:09:14 +00007473 // TODO: use the function scope once we have call site AAReturnedValues.
7474 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00007475 const auto &LivenessAA =
7476 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007477
7478 auto &OpcodeInstMap =
7479 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007480 if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, &QueryingAA,
7481 &LivenessAA, Opcodes, CheckBBLivenessOnly))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007482 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00007483
7484 return true;
7485}
7486
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007487bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007488 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00007489 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007490
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007491 const Function *AssociatedFunction =
7492 QueryingAA.getIRPosition().getAssociatedFunction();
7493 if (!AssociatedFunction)
7494 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007495
Johannes Doerfert07a5c122019-08-28 14:09:14 +00007496 // TODO: use the function scope once we have call site AAReturnedValues.
7497 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
7498 const auto &LivenessAA =
7499 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007500
7501 for (Instruction *I :
7502 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007503 // Skip dead instructions.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007504 if (isAssumedDead(IRPosition::value(*I), &QueryingAA, &LivenessAA))
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007505 continue;
7506
7507 if (!Pred(*I))
7508 return false;
7509 }
7510
7511 return true;
7512}
7513
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007514ChangeStatus Attributor::run() {
Johannes Doerfertaade7822019-06-05 03:02:24 +00007515 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
7516 << AllAbstractAttributes.size()
7517 << " abstract attributes.\n");
7518
Stefan Stipanovic53605892019-06-27 11:27:54 +00007519 // Now that all abstract attributes are collected and initialized we start
7520 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00007521
7522 unsigned IterationCounter = 1;
7523
7524 SmallVector<AbstractAttribute *, 64> ChangedAAs;
Johannes Doerfert680f6382019-11-02 02:48:05 -05007525 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007526 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
7527
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00007528 bool RecomputeDependences = false;
7529
Johannes Doerfertaade7822019-06-05 03:02:24 +00007530 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007531 // Remember the size to determine new attributes.
7532 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00007533 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
7534 << ", Worklist size: " << Worklist.size() << "\n");
7535
Johannes Doerfert680f6382019-11-02 02:48:05 -05007536 // For invalid AAs we can fix dependent AAs that have a required dependence,
7537 // thereby folding long dependence chains in a single step without the need
7538 // to run updates.
7539 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
7540 AbstractAttribute *InvalidAA = InvalidAAs[u];
7541 auto &QuerriedAAs = QueryMap[InvalidAA];
7542 LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
7543 << QuerriedAAs.RequiredAAs.size() << "/"
7544 << QuerriedAAs.OptionalAAs.size()
7545 << " required/optional dependences\n");
7546 for (AbstractAttribute *DepOnInvalidAA : QuerriedAAs.RequiredAAs) {
7547 AbstractState &DOIAAState = DepOnInvalidAA->getState();
7548 DOIAAState.indicatePessimisticFixpoint();
7549 ++NumAttributesFixedDueToRequiredDependences;
7550 assert(DOIAAState.isAtFixpoint() && "Expected fixpoint state!");
7551 if (!DOIAAState.isValidState())
7552 InvalidAAs.insert(DepOnInvalidAA);
Johannes Doerfert22408542020-01-28 09:38:07 -06007553 else
7554 ChangedAAs.push_back(DepOnInvalidAA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05007555 }
7556 if (!RecomputeDependences)
7557 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
7558 QuerriedAAs.OptionalAAs.end());
7559 }
7560
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00007561 // If dependences (=QueryMap) are recomputed we have to look at all abstract
7562 // attributes again, regardless of what changed in the last iteration.
7563 if (RecomputeDependences) {
7564 LLVM_DEBUG(
7565 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
7566 QueryMap.clear();
7567 ChangedAAs.clear();
7568 Worklist.insert(AllAbstractAttributes.begin(),
7569 AllAbstractAttributes.end());
7570 }
7571
Johannes Doerfertaade7822019-06-05 03:02:24 +00007572 // Add all abstract attributes that are potentially dependent on one that
7573 // changed to the work list.
7574 for (AbstractAttribute *ChangedAA : ChangedAAs) {
7575 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05007576 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
7577 QuerriedAAs.OptionalAAs.end());
7578 Worklist.insert(QuerriedAAs.RequiredAAs.begin(),
7579 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00007580 }
7581
Johannes Doerfertb504eb82019-08-26 18:55:47 +00007582 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
7583 << ", Worklist+Dependent size: " << Worklist.size()
7584 << "\n");
7585
Johannes Doerfert680f6382019-11-02 02:48:05 -05007586 // Reset the changed and invalid set.
Johannes Doerfertaade7822019-06-05 03:02:24 +00007587 ChangedAAs.clear();
Johannes Doerfert680f6382019-11-02 02:48:05 -05007588 InvalidAAs.clear();
Johannes Doerfertaade7822019-06-05 03:02:24 +00007589
7590 // Update all abstract attribute in the work list and record the ones that
7591 // changed.
7592 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007593 if (!AA->getState().isAtFixpoint() &&
7594 !isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true)) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05007595 QueriedNonFixAA = false;
7596 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007597 ChangedAAs.push_back(AA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05007598 if (!AA->getState().isValidState())
7599 InvalidAAs.insert(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05007600 } else if (!QueriedNonFixAA) {
7601 // If the attribute did not query any non-fix information, the state
7602 // will not change and we can indicate that right away.
7603 AA->getState().indicateOptimisticFixpoint();
7604 }
7605 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00007606
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00007607 // Check if we recompute the dependences in the next iteration.
7608 RecomputeDependences = (DepRecomputeInterval > 0 &&
7609 IterationCounter % DepRecomputeInterval == 0);
7610
Johannes Doerfert9543f142019-08-23 15:24:57 +00007611 // Add attributes to the changed set if they have been created in the last
7612 // iteration.
7613 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
7614 AllAbstractAttributes.end());
7615
Johannes Doerfertaade7822019-06-05 03:02:24 +00007616 // Reset the work list and repopulate with the changed abstract attributes.
7617 // Note that dependent ones are added above.
7618 Worklist.clear();
7619 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
7620
Johannes Doerfertbf112132019-08-29 01:29:44 +00007621 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
7622 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00007623
Johannes Doerfertaade7822019-06-05 03:02:24 +00007624 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
7625 << IterationCounter << "/" << MaxFixpointIterations
7626 << " iterations\n");
7627
Johannes Doerfertbf112132019-08-29 01:29:44 +00007628 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00007629
Johannes Doerfertaade7822019-06-05 03:02:24 +00007630 // Reset abstract arguments not settled in a sound fixpoint by now. This
7631 // happens when we stopped the fixpoint iteration early. Note that only the
7632 // ones marked as "changed" *and* the ones transitively depending on them
7633 // need to be reverted to a pessimistic state. Others might not be in a
7634 // fixpoint state but we can use the optimistic results for them anyway.
7635 SmallPtrSet<AbstractAttribute *, 32> Visited;
7636 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
7637 AbstractAttribute *ChangedAA = ChangedAAs[u];
7638 if (!Visited.insert(ChangedAA).second)
7639 continue;
7640
7641 AbstractState &State = ChangedAA->getState();
7642 if (!State.isAtFixpoint()) {
7643 State.indicatePessimisticFixpoint();
7644
7645 NumAttributesTimedOut++;
7646 }
7647
7648 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05007649 ChangedAAs.append(QuerriedAAs.OptionalAAs.begin(),
7650 QuerriedAAs.OptionalAAs.end());
7651 ChangedAAs.append(QuerriedAAs.RequiredAAs.begin(),
7652 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00007653 }
7654
7655 LLVM_DEBUG({
7656 if (!Visited.empty())
7657 dbgs() << "\n[Attributor] Finalized " << Visited.size()
7658 << " abstract attributes.\n";
7659 });
7660
7661 unsigned NumManifested = 0;
7662 unsigned NumAtFixpoint = 0;
7663 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
7664 for (AbstractAttribute *AA : AllAbstractAttributes) {
7665 AbstractState &State = AA->getState();
7666
7667 // If there is not already a fixpoint reached, we can now take the
7668 // optimistic state. This is correct because we enforced a pessimistic one
7669 // on abstract attributes that were transitively dependent on a changed one
7670 // already above.
7671 if (!State.isAtFixpoint())
7672 State.indicateOptimisticFixpoint();
7673
7674 // If the state is invalid, we do not try to manifest it.
7675 if (!State.isValidState())
7676 continue;
7677
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007678 // Skip dead code.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007679 if (isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007680 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007681 // Manifest the state and record if we changed the IR.
7682 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00007683 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
7684 AA->trackStatistics();
Johannes Doerfert8e76fec2020-02-16 17:37:50 -06007685 LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA
7686 << "\n");
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00007687
Johannes Doerfertaade7822019-06-05 03:02:24 +00007688 ManifestChange = ManifestChange | LocalChange;
7689
7690 NumAtFixpoint++;
7691 NumManifested += (LocalChange == ChangeStatus::CHANGED);
7692 }
7693
7694 (void)NumManifested;
7695 (void)NumAtFixpoint;
7696 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
7697 << " arguments while " << NumAtFixpoint
7698 << " were in a valid fixpoint state\n");
7699
Johannes Doerfertaade7822019-06-05 03:02:24 +00007700 NumAttributesManifested += NumManifested;
7701 NumAttributesValidFixpoint += NumAtFixpoint;
7702
Fangrui Songf1826172019-08-20 07:21:43 +00007703 (void)NumFinalAAs;
Johannes Doerfertb70297a2020-02-14 10:34:31 -06007704 if (NumFinalAAs != AllAbstractAttributes.size()) {
7705 for (unsigned u = NumFinalAAs; u < AllAbstractAttributes.size(); ++u)
7706 errs() << "Unexpected abstract attribute: " << *AllAbstractAttributes[u]
7707 << " :: "
7708 << AllAbstractAttributes[u]->getIRPosition().getAssociatedValue()
7709 << "\n";
7710 llvm_unreachable("Expected the final number of abstract attributes to "
7711 "remain unchanged!");
7712 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00007713
7714 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00007715 {
7716 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
7717 << ToBeDeletedFunctions.size() << " functions and "
7718 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007719 << ToBeDeletedInsts.size() << " instructions and "
7720 << ToBeChangedUses.size() << " uses\n");
7721
Alina Sbirlea9e66c4e2020-01-23 14:21:08 -08007722 SmallVector<WeakTrackingVH, 32> DeadInsts;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007723 SmallVector<Instruction *, 32> TerminatorsToFold;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007724
7725 for (auto &It : ToBeChangedUses) {
7726 Use *U = It.first;
7727 Value *NewV = It.second;
7728 Value *OldV = U->get();
7729 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
7730 << " instead of " << *OldV << "\n");
7731 U->set(NewV);
Johannes Doerfert137c99a2020-02-14 20:06:34 -06007732 // Do not modify call instructions outside the SCC.
7733 if (auto *CB = dyn_cast<CallBase>(OldV))
7734 if (!Functions.count(CB->getCaller()))
7735 continue;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007736 if (Instruction *I = dyn_cast<Instruction>(OldV)) {
7737 CGModifiedFunctions.insert(I->getFunction());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007738 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007739 isInstructionTriviallyDead(I))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007740 DeadInsts.push_back(I);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007741 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007742 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
7743 Instruction *UserI = cast<Instruction>(U->getUser());
7744 if (isa<UndefValue>(NewV)) {
Hideto Uenocb5eb132019-12-27 02:39:37 +09007745 ToBeChangedToUnreachableInsts.insert(UserI);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007746 } else {
7747 TerminatorsToFold.push_back(UserI);
7748 }
7749 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00007750 }
Johannes Doerferta4088c72020-01-07 16:01:57 -06007751 for (auto &V : InvokeWithDeadSuccessor)
7752 if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
7753 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
7754 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
7755 bool Invoke2CallAllowed =
7756 !AAIsDeadFunction::mayCatchAsynchronousExceptions(
7757 *II->getFunction());
7758 assert((UnwindBBIsDead || NormalBBIsDead) &&
7759 "Invoke does not have dead successors!");
7760 BasicBlock *BB = II->getParent();
7761 BasicBlock *NormalDestBB = II->getNormalDest();
7762 if (UnwindBBIsDead) {
7763 Instruction *NormalNextIP = &NormalDestBB->front();
7764 if (Invoke2CallAllowed) {
7765 changeToCall(II);
7766 NormalNextIP = BB->getTerminator();
7767 }
7768 if (NormalBBIsDead)
7769 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
7770 } else {
7771 assert(NormalBBIsDead && "Broken invariant!");
7772 if (!NormalDestBB->getUniquePredecessor())
7773 NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
7774 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
7775 }
7776 }
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06007777 for (auto &V : ToBeChangedToUnreachableInsts)
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007778 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
7779 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06007780 changeToUnreachable(I, /* UseLLVMTrap */ false);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007781 }
7782 for (Instruction *I : TerminatorsToFold) {
7783 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007784 ConstantFoldTerminator(I->getParent());
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007785 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007786
Johannes Doerfert5429c822020-01-11 23:30:36 -06007787 for (auto &V : ToBeDeletedInsts) {
7788 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007789 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfertb4352e42020-02-13 20:10:59 -06007790 if (!I->getType()->isVoidTy())
7791 I->replaceAllUsesWith(UndefValue::get(I->getType()));
Johannes Doerfert5429c822020-01-11 23:30:36 -06007792 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
7793 DeadInsts.push_back(I);
7794 else
7795 I->eraseFromParent();
7796 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007797 }
7798
7799 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00007800
Johannes Doerfert2f622062019-09-04 16:35:20 +00007801 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
7802 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
7803 ToBeDeletedBBs.reserve(NumDeadBlocks);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007804 for (BasicBlock *BB : ToBeDeletedBlocks) {
7805 CGModifiedFunctions.insert(BB->getParent());
7806 ToBeDeletedBBs.push_back(BB);
7807 }
Johannes Doerfert5e442a52019-10-30 17:34:59 -05007808 // Actually we do not delete the blocks but squash them into a single
7809 // unreachable but untangling branches that jump here is something we need
7810 // to do in a more generic way.
7811 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
7812 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
7813 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00007814 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00007815
Johannes Doerfert2f622062019-09-04 16:35:20 +00007816 // Identify dead internal functions and delete them. This happens outside
7817 // the other fixpoint analysis as we might treat potentially dead functions
7818 // as live to lower the number of iterations. If they happen to be dead, the
7819 // below fixpoint loop will identify and eliminate them.
7820 SmallVector<Function *, 8> InternalFns;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007821 for (Function *F : Functions)
7822 if (F->hasLocalLinkage())
7823 InternalFns.push_back(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00007824
7825 bool FoundDeadFn = true;
7826 while (FoundDeadFn) {
7827 FoundDeadFn = false;
7828 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
7829 Function *F = InternalFns[u];
7830 if (!F)
7831 continue;
7832
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007833 bool AllCallSitesKnown;
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06007834 if (!checkForAllCallSites(
7835 [this](AbstractCallSite ACS) {
7836 return ToBeDeletedFunctions.count(
7837 ACS.getInstruction()->getFunction());
7838 },
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007839 *F, true, nullptr, AllCallSitesKnown))
Johannes Doerfert2f622062019-09-04 16:35:20 +00007840 continue;
7841
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007842 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00007843 InternalFns[u] = nullptr;
7844 FoundDeadFn = true;
7845 }
7846 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00007847 }
7848
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007849 // Rewrite the functions as requested during manifest.
7850 ManifestChange =
7851 ManifestChange | rewriteFunctionSignatures(CGModifiedFunctions);
7852
7853 for (Function *Fn : CGModifiedFunctions)
7854 CGUpdater.reanalyzeFunction(*Fn);
7855
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007856 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
7857 BUILD_STAT_NAME(AAIsDead, Function) += ToBeDeletedFunctions.size();
7858
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007859 for (Function *Fn : ToBeDeletedFunctions)
7860 CGUpdater.removeFunction(*Fn);
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06007861
Johannes Doerfertbf112132019-08-29 01:29:44 +00007862 if (VerifyMaxFixpointIterations &&
7863 IterationCounter != MaxFixpointIterations) {
7864 errs() << "\n[Attributor] Fixpoint iteration done after: "
7865 << IterationCounter << "/" << MaxFixpointIterations
7866 << " iterations\n";
7867 llvm_unreachable("The fixpoint was not reached with exactly the number of "
7868 "specified iterations!");
7869 }
7870
Johannes Doerfertaade7822019-06-05 03:02:24 +00007871 return ManifestChange;
7872}
7873
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007874bool Attributor::isValidFunctionSignatureRewrite(
7875 Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007876
7877 auto CallSiteCanBeChanged = [](AbstractCallSite ACS) {
7878 // Forbid must-tail calls for now.
7879 return !ACS.isCallbackCall() && !ACS.getCallSite().isMustTailCall();
7880 };
7881
7882 Function *Fn = Arg.getParent();
7883 // Avoid var-arg functions for now.
7884 if (Fn->isVarArg()) {
7885 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
7886 return false;
7887 }
7888
7889 // Avoid functions with complicated argument passing semantics.
7890 AttributeList FnAttributeList = Fn->getAttributes();
7891 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
7892 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
7893 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca)) {
7894 LLVM_DEBUG(
7895 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
7896 return false;
7897 }
7898
7899 // Avoid callbacks for now.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007900 bool AllCallSitesKnown;
7901 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,
7902 AllCallSitesKnown)) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007903 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
7904 return false;
7905 }
7906
7907 auto InstPred = [](Instruction &I) {
7908 if (auto *CI = dyn_cast<CallInst>(&I))
7909 return !CI->isMustTailCall();
7910 return true;
7911 };
7912
7913 // Forbid must-tail calls for now.
7914 // TODO:
Johannes Doerfert75133632019-10-10 01:39:16 -05007915 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007916 if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
7917 nullptr, {Instruction::Call})) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007918 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
7919 return false;
7920 }
7921
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007922 return true;
7923}
7924
7925bool Attributor::registerFunctionSignatureRewrite(
7926 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
7927 ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,
7928 ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {
7929 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
7930 << Arg.getParent()->getName() << " with "
7931 << ReplacementTypes.size() << " replacements\n");
7932 assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&
7933 "Cannot register an invalid rewrite");
7934
7935 Function *Fn = Arg.getParent();
Johannes Doerfert75133632019-10-10 01:39:16 -05007936 SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = ArgumentReplacementMap[Fn];
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007937 if (ARIs.empty())
Johannes Doerfert75133632019-10-10 01:39:16 -05007938 ARIs.resize(Fn->arg_size());
7939
7940 // If we have a replacement already with less than or equal new arguments,
7941 // ignore this request.
7942 ArgumentReplacementInfo *&ARI = ARIs[Arg.getArgNo()];
7943 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
7944 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
7945 return false;
7946 }
7947
7948 // If we have a replacement already but we like the new one better, delete
7949 // the old.
7950 if (ARI)
7951 delete ARI;
7952
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007953 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
7954 << Arg.getParent()->getName() << " with "
7955 << ReplacementTypes.size() << " replacements\n");
7956
Johannes Doerfert75133632019-10-10 01:39:16 -05007957 // Remember the replacement.
7958 ARI = new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
7959 std::move(CalleeRepairCB),
7960 std::move(ACSRepairCB));
7961
7962 return true;
7963}
7964
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007965ChangeStatus Attributor::rewriteFunctionSignatures(
7966 SmallPtrSetImpl<Function *> &ModifiedFns) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007967 ChangeStatus Changed = ChangeStatus::UNCHANGED;
7968
7969 for (auto &It : ArgumentReplacementMap) {
7970 Function *OldFn = It.getFirst();
7971
7972 // Deleted functions do not require rewrites.
7973 if (ToBeDeletedFunctions.count(OldFn))
7974 continue;
7975
7976 const SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = It.getSecond();
7977 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
7978
7979 SmallVector<Type *, 16> NewArgumentTypes;
7980 SmallVector<AttributeSet, 16> NewArgumentAttributes;
7981
7982 // Collect replacement argument types and copy over existing attributes.
7983 AttributeList OldFnAttributeList = OldFn->getAttributes();
7984 for (Argument &Arg : OldFn->args()) {
7985 if (ArgumentReplacementInfo *ARI = ARIs[Arg.getArgNo()]) {
7986 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
7987 ARI->ReplacementTypes.end());
7988 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
7989 AttributeSet());
7990 } else {
7991 NewArgumentTypes.push_back(Arg.getType());
7992 NewArgumentAttributes.push_back(
7993 OldFnAttributeList.getParamAttributes(Arg.getArgNo()));
7994 }
7995 }
7996
7997 FunctionType *OldFnTy = OldFn->getFunctionType();
7998 Type *RetTy = OldFnTy->getReturnType();
7999
8000 // Construct the new function type using the new arguments types.
8001 FunctionType *NewFnTy =
8002 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
8003
8004 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
8005 << "' from " << *OldFn->getFunctionType() << " to "
8006 << *NewFnTy << "\n");
8007
8008 // Create the new function body and insert it into the module.
8009 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
8010 OldFn->getAddressSpace(), "");
8011 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
8012 NewFn->takeName(OldFn);
8013 NewFn->copyAttributesFrom(OldFn);
8014
8015 // Patch the pointer to LLVM function in debug info descriptor.
8016 NewFn->setSubprogram(OldFn->getSubprogram());
8017 OldFn->setSubprogram(nullptr);
8018
8019 // Recompute the parameter attributes list based on the new arguments for
8020 // the function.
8021 LLVMContext &Ctx = OldFn->getContext();
8022 NewFn->setAttributes(AttributeList::get(
8023 Ctx, OldFnAttributeList.getFnAttributes(),
8024 OldFnAttributeList.getRetAttributes(), NewArgumentAttributes));
8025
8026 // Since we have now created the new function, splice the body of the old
8027 // function right into the new function, leaving the old rotting hulk of the
8028 // function empty.
8029 NewFn->getBasicBlockList().splice(NewFn->begin(),
8030 OldFn->getBasicBlockList());
8031
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008032 // Set of all "call-like" instructions that invoke the old function mapped
8033 // to their new replacements.
8034 SmallVector<std::pair<CallBase *, CallBase *>, 8> CallSitePairs;
Johannes Doerfert75133632019-10-10 01:39:16 -05008035
8036 // Callback to create a new "call-like" instruction for a given one.
8037 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
8038 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
8039 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
8040
8041 // Collect the new argument operands for the replacement call site.
8042 SmallVector<Value *, 16> NewArgOperands;
8043 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
8044 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
8045 unsigned NewFirstArgNum = NewArgOperands.size();
Ilya Biryukov4f82af82019-12-31 10:21:52 +01008046 (void)NewFirstArgNum; // only used inside assert.
Johannes Doerfert75133632019-10-10 01:39:16 -05008047 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
8048 if (ARI->ACSRepairCB)
8049 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
8050 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
8051 NewArgOperands.size() &&
8052 "ACS repair callback did not provide as many operand as new "
8053 "types were registered!");
8054 // TODO: Exose the attribute set to the ACS repair callback
8055 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
8056 AttributeSet());
8057 } else {
8058 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
8059 NewArgOperandAttributes.push_back(
8060 OldCallAttributeList.getParamAttributes(OldArgNum));
8061 }
8062 }
8063
8064 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
8065 "Mismatch # argument operands vs. # argument operand attributes!");
8066 assert(NewArgOperands.size() == NewFn->arg_size() &&
8067 "Mismatch # argument operands vs. # function arguments!");
8068
8069 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
8070 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
8071
8072 // Create a new call or invoke instruction to replace the old one.
8073 CallBase *NewCB;
8074 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
8075 NewCB =
8076 InvokeInst::Create(NewFn, II->getNormalDest(), II->getUnwindDest(),
8077 NewArgOperands, OperandBundleDefs, "", OldCB);
8078 } else {
8079 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
8080 "", OldCB);
8081 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
8082 NewCB = NewCI;
8083 }
8084
8085 // Copy over various properties and the new attributes.
Johannes Doerfert75133632019-10-10 01:39:16 -05008086 uint64_t W;
8087 if (OldCB->extractProfTotalWeight(W))
8088 NewCB->setProfWeight(W);
8089 NewCB->setCallingConv(OldCB->getCallingConv());
8090 NewCB->setDebugLoc(OldCB->getDebugLoc());
8091 NewCB->takeName(OldCB);
8092 NewCB->setAttributes(AttributeList::get(
8093 Ctx, OldCallAttributeList.getFnAttributes(),
8094 OldCallAttributeList.getRetAttributes(), NewArgOperandAttributes));
8095
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008096 CallSitePairs.push_back({OldCB, NewCB});
Johannes Doerfert75133632019-10-10 01:39:16 -05008097 return true;
8098 };
8099
8100 // Use the CallSiteReplacementCreator to create replacement call sites.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06008101 bool AllCallSitesKnown;
8102 bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,
8103 true, nullptr, AllCallSitesKnown);
Ilya Biryukov4f82af82019-12-31 10:21:52 +01008104 (void)Success;
Johannes Doerfert75133632019-10-10 01:39:16 -05008105 assert(Success && "Assumed call site replacement to succeed!");
8106
8107 // Rewire the arguments.
8108 auto OldFnArgIt = OldFn->arg_begin();
8109 auto NewFnArgIt = NewFn->arg_begin();
8110 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
8111 ++OldArgNum, ++OldFnArgIt) {
8112 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
8113 if (ARI->CalleeRepairCB)
8114 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
8115 NewFnArgIt += ARI->ReplacementTypes.size();
8116 } else {
8117 NewFnArgIt->takeName(&*OldFnArgIt);
8118 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
8119 ++NewFnArgIt;
8120 }
8121 }
8122
8123 // Eliminate the instructions *after* we visited all of them.
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008124 for (auto &CallSitePair : CallSitePairs) {
8125 CallBase &OldCB = *CallSitePair.first;
8126 CallBase &NewCB = *CallSitePair.second;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008127 // We do not modify the call graph here but simply reanalyze the old
8128 // function. This should be revisited once the old PM is gone.
8129 ModifiedFns.insert(OldCB.getFunction());
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008130 OldCB.replaceAllUsesWith(&NewCB);
8131 OldCB.eraseFromParent();
8132 }
Johannes Doerfert75133632019-10-10 01:39:16 -05008133
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008134 // Replace the function in the call graph (if any).
8135 CGUpdater.replaceFunctionWith(*OldFn, *NewFn);
8136
8137 // If the old function was modified and needed to be reanalyzed, the new one
8138 // does now.
8139 if (ModifiedFns.erase(OldFn))
8140 ModifiedFns.insert(NewFn);
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008141
Johannes Doerfert75133632019-10-10 01:39:16 -05008142 Changed = ChangeStatus::CHANGED;
8143 }
8144
8145 return Changed;
8146}
8147
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008148void Attributor::initializeInformationCache(Function &F) {
8149
8150 // Walk all instructions to find interesting instructions that might be
8151 // queried by abstract attributes during their initialization or update.
8152 // This has to happen before we create attributes.
8153 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
8154 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
8155
8156 for (Instruction &I : instructions(&F)) {
8157 bool IsInterestingOpcode = false;
8158
8159 // To allow easy access to all instructions in a function with a given
8160 // opcode we store them in the InfoCache. As not all opcodes are interesting
8161 // to concrete attributes we only cache the ones that are as identified in
8162 // the following switch.
8163 // Note: There are no concrete attributes now so this is initially empty.
8164 switch (I.getOpcode()) {
8165 default:
8166 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
8167 "New call site/base instruction type needs to be known int the "
8168 "Attributor.");
8169 break;
8170 case Instruction::Load:
8171 // The alignment of a pointer is interesting for loads.
8172 case Instruction::Store:
8173 // The alignment of a pointer is interesting for stores.
8174 case Instruction::Call:
8175 case Instruction::CallBr:
8176 case Instruction::Invoke:
8177 case Instruction::CleanupRet:
8178 case Instruction::CatchSwitch:
Johannes Doerfert5732f562019-12-24 19:25:08 -06008179 case Instruction::AtomicRMW:
8180 case Instruction::AtomicCmpXchg:
Hideto Uenoef4febd2019-12-29 17:34:08 +09008181 case Instruction::Br:
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008182 case Instruction::Resume:
8183 case Instruction::Ret:
8184 IsInterestingOpcode = true;
8185 }
8186 if (IsInterestingOpcode)
8187 InstOpcodeMap[I.getOpcode()].push_back(&I);
8188 if (I.mayReadOrWriteMemory())
8189 ReadOrWriteInsts.push_back(&I);
8190 }
8191}
8192
Johannes Doerfert12173e62019-10-13 20:25:25 -05008193void Attributor::recordDependence(const AbstractAttribute &FromAA,
Johannes Doerfert680f6382019-11-02 02:48:05 -05008194 const AbstractAttribute &ToAA,
8195 DepClassTy DepClass) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05008196 if (FromAA.getState().isAtFixpoint())
8197 return;
8198
Johannes Doerfert680f6382019-11-02 02:48:05 -05008199 if (DepClass == DepClassTy::REQUIRED)
8200 QueryMap[&FromAA].RequiredAAs.insert(
8201 const_cast<AbstractAttribute *>(&ToAA));
8202 else
8203 QueryMap[&FromAA].OptionalAAs.insert(
8204 const_cast<AbstractAttribute *>(&ToAA));
Johannes Doerfert2dad7292019-10-13 21:10:31 -05008205 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05008206}
8207
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00008208void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00008209 if (!VisitedFunctions.insert(&F).second)
8210 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05008211 if (F.isDeclaration())
8212 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00008213
Johannes Doerfert710ebb02019-08-14 21:18:01 +00008214 IRPosition FPos = IRPosition::function(F);
8215
Johannes Doerfert305b9612019-08-04 18:40:01 +00008216 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00008217 // We need dead instruction detection because we do not want to deal with
8218 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008219 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00008220
8221 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008222 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00008223
Johannes Doerfert58f324a2019-12-24 18:48:50 -06008224 // Every function might contain instructions that cause "undefined behavior".
8225 getOrCreateAAFor<AAUndefinedBehavior>(FPos);
8226
Stefan Stipanovic53605892019-06-27 11:27:54 +00008227 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008228 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00008229
Stefan Stipanovic06263672019-07-11 21:37:40 +00008230 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008231 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00008232
Hideto Ueno65bbaf92019-07-12 17:38:51 +00008233 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008234 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00008235
Johannes Doerferte83f3032019-08-05 23:22:05 +00008236 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008237 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00008238
Hideto Ueno63f60662019-09-21 15:13:19 +00008239 // Every function might be "no-recurse".
8240 getOrCreateAAFor<AANoRecurse>(FPos);
8241
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008242 // Every function might be "readnone/readonly/writeonly/...".
8243 getOrCreateAAFor<AAMemoryBehavior>(FPos);
8244
Johannes Doerfert282f5d72020-01-26 02:51:57 -06008245 // Every function can be "readnone/argmemonly/inaccessiblememonly/...".
8246 getOrCreateAAFor<AAMemoryLocation>(FPos);
8247
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008248 // Every function might be applicable for Heap-To-Stack conversion.
8249 if (EnableHeapToStack)
8250 getOrCreateAAFor<AAHeapToStack>(FPos);
8251
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00008252 // Return attributes are only appropriate if the return type is non void.
8253 Type *ReturnType = F.getReturnType();
8254 if (!ReturnType->isVoidTy()) {
8255 // Argument attribute "returned" --- Create only one per function even
8256 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008257 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00008258
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008259 IRPosition RetPos = IRPosition::returned(F);
8260
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008261 // Every returned value might be dead.
8262 getOrCreateAAFor<AAIsDead>(RetPos);
8263
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008264 // Every function might be simplified.
8265 getOrCreateAAFor<AAValueSimplify>(RetPos);
8266
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00008267 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00008268
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00008269 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008270 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00008271
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00008272 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008273 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00008274
8275 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008276 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00008277
8278 // Every function with pointer return type might be marked
8279 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008280 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00008281 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00008282 }
8283
Hideto Ueno54869ec2019-07-15 06:49:04 +00008284 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008285 IRPosition ArgPos = IRPosition::argument(Arg);
8286
8287 // Every argument might be simplified.
8288 getOrCreateAAFor<AAValueSimplify>(ArgPos);
8289
Johannes Doerfert1e99fc92020-02-16 16:42:47 -06008290 // Every argument might be dead.
8291 getOrCreateAAFor<AAIsDead>(ArgPos);
8292
Hideto Ueno19c07af2019-07-23 08:16:17 +00008293 if (Arg.getType()->isPointerTy()) {
8294 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008295 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00008296
Hideto Uenocbab3342019-08-29 05:52:00 +00008297 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008298 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00008299
Hideto Ueno19c07af2019-07-23 08:16:17 +00008300 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008301 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00008302
8303 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008304 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00008305
8306 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008307 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008308
8309 // Every argument with pointer type might be marked
8310 // "readnone/readonly/writeonly/..."
8311 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01008312
8313 // Every argument with pointer type might be marked nofree.
8314 getOrCreateAAFor<AANoFree>(ArgPos);
Johannes Doerfert89c2e732019-10-30 17:20:20 -05008315
8316 // Every argument with pointer type might be privatizable (or promotable)
8317 getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00008318 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00008319 }
8320
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008321 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00008322 CallSite CS(&I);
Johannes Doerfert86509e82020-01-12 00:34:38 -06008323 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
8324
8325 // Call sites might be dead if they do not have side effects and no live
8326 // users. The return value might be dead if there are no live users.
8327 getOrCreateAAFor<AAIsDead>(CSRetPos);
8328
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008329 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05008330 // Skip declerations except if annotations on their call sites were
8331 // explicitly requested.
Johannes Doerfert139c9ef2019-12-13 23:41:02 -06008332 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
8333 !Callee->hasMetadata(LLVMContext::MD_callback))
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05008334 return true;
8335
8336 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09008337
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008338 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
8339
Hideto Ueno188f9a32020-01-15 15:25:52 +09008340 // Call site return integer values might be limited by a constant range.
Johannes Doerfert86509e82020-01-12 00:34:38 -06008341 if (Callee->getReturnType()->isIntegerTy())
Hideto Ueno188f9a32020-01-15 15:25:52 +09008342 getOrCreateAAFor<AAValueConstantRange>(CSRetPos);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008343 }
8344
Johannes Doerfert28880192019-12-31 00:57:00 -06008345 for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008346
8347 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
8348
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008349 // Every call site argument might be dead.
8350 getOrCreateAAFor<AAIsDead>(CSArgPos);
8351
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008352 // Call site argument might be simplified.
8353 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
8354
Hideto Ueno54869ec2019-07-15 06:49:04 +00008355 if (!CS.getArgument(i)->getType()->isPointerTy())
8356 continue;
8357
8358 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008359 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00008360
Hideto Uenocbab3342019-08-29 05:52:00 +00008361 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008362 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00008363
Hideto Ueno19c07af2019-07-23 08:16:17 +00008364 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008365 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00008366
8367 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008368 getOrCreateAAFor<AAAlign>(CSArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01008369
Johannes Doerfert28880192019-12-31 00:57:00 -06008370 // Call site argument attribute
8371 // "readnone/readonly/writeonly/..."
8372 getOrCreateAAFor<AAMemoryBehavior>(CSArgPos);
8373
Hideto Ueno4ecf2552019-12-12 13:42:40 +00008374 // Call site argument attribute "nofree".
8375 getOrCreateAAFor<AANoFree>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00008376 }
8377 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008378 return true;
8379 };
8380
8381 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008382 bool Success;
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008383 Success = checkForAllInstructionsImpl(
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008384 nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008385 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
8386 (unsigned)Instruction::Call});
8387 (void)Success;
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008388 assert(Success && "Expected the check call to be successful!");
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008389
8390 auto LoadStorePred = [&](Instruction &I) -> bool {
8391 if (isa<LoadInst>(I))
8392 getOrCreateAAFor<AAAlign>(
8393 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
8394 else
8395 getOrCreateAAFor<AAAlign>(
8396 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
8397 return true;
8398 };
8399 Success = checkForAllInstructionsImpl(
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008400 nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008401 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
8402 (void)Success;
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008403 assert(Success && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00008404}
8405
8406/// Helpers to ease debugging through output streams and print calls.
8407///
8408///{
8409raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
8410 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
8411}
8412
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008413raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00008414 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00008415 case IRPosition::IRP_INVALID:
8416 return OS << "inv";
8417 case IRPosition::IRP_FLOAT:
8418 return OS << "flt";
8419 case IRPosition::IRP_RETURNED:
8420 return OS << "fn_ret";
8421 case IRPosition::IRP_CALL_SITE_RETURNED:
8422 return OS << "cs_ret";
8423 case IRPosition::IRP_FUNCTION:
8424 return OS << "fn";
8425 case IRPosition::IRP_CALL_SITE:
8426 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008427 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00008428 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008429 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00008430 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00008431 }
8432 llvm_unreachable("Unknown attribute position!");
8433}
8434
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008435raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00008436 const Value &AV = Pos.getAssociatedValue();
8437 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008438 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
8439}
8440
Johannes Doerfert1a746452019-10-20 22:28:49 -05008441template <typename base_ty, base_ty BestState, base_ty WorstState>
Hideto Ueno188f9a32020-01-15 15:25:52 +09008442raw_ostream &
8443llvm::operator<<(raw_ostream &OS,
8444 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00008445 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
8446 << static_cast<const AbstractState &>(S);
8447}
8448
Hideto Ueno188f9a32020-01-15 15:25:52 +09008449raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {
8450 OS << "range-state(" << S.getBitWidth() << ")<";
8451 S.getKnown().print(OS);
8452 OS << " / ";
8453 S.getAssumed().print(OS);
8454 OS << ">";
8455
8456 return OS << static_cast<const AbstractState &>(S);
8457}
8458
Johannes Doerfertaade7822019-06-05 03:02:24 +00008459raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
8460 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
8461}
8462
8463raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
8464 AA.print(OS);
8465 return OS;
8466}
8467
8468void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008469 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
8470 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00008471}
8472///}
8473
8474/// ----------------------------------------------------------------------------
8475/// Pass (Manager) Boilerplate
8476/// ----------------------------------------------------------------------------
8477
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008478static bool runAttributorOnFunctions(InformationCache &InfoCache,
8479 SetVector<Function *> &Functions,
8480 AnalysisGetter &AG,
8481 CallGraphUpdater &CGUpdater) {
8482 if (DisableAttributor || Functions.empty())
Johannes Doerfertaade7822019-06-05 03:02:24 +00008483 return false;
8484
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008485 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << Functions.size()
Johannes Doerfertaade7822019-06-05 03:02:24 +00008486 << " functions.\n");
8487
8488 // Create an Attributor and initially empty information cache that is filled
8489 // while we identify default attribute opportunities.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008490 Attributor A(Functions, InfoCache, CGUpdater, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00008491
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008492 for (Function *F : Functions)
8493 A.initializeInformationCache(*F);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008494
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008495 for (Function *F : Functions) {
8496 if (F->hasExactDefinition())
Johannes Doerfertb0412e42019-09-04 16:16:13 +00008497 NumFnWithExactDefinition++;
8498 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00008499 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00008500
Johannes Doerfert2f622062019-09-04 16:35:20 +00008501 // We look at internal functions only on-demand but if any use is not a
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008502 // direct call or outside the current set of analyzed functions, we have to
8503 // do it eagerly.
8504 if (F->hasLocalLinkage()) {
8505 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
8506 ImmutableCallSite ICS(U.getUser());
8507 return ICS && ICS.isCallee(&U) &&
8508 Functions.count(const_cast<Function *>(ICS.getCaller()));
Johannes Doerfert2f622062019-09-04 16:35:20 +00008509 }))
8510 continue;
8511 }
8512
Johannes Doerfertaade7822019-06-05 03:02:24 +00008513 // Populate the Attributor with abstract attribute opportunities in the
8514 // function and the information cache with IR information.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008515 A.identifyDefaultAbstractAttributes(*F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00008516 }
8517
Johannes Doerfert77a9e612020-01-11 23:36:17 -06008518 ChangeStatus Changed = A.run();
Fangrui Songfd5665a2020-02-14 21:47:19 -08008519 assert(!verifyModule(*Functions.front()->getParent(), &errs()) &&
8520 "Module verification failed!");
Johannes Doerfert77a9e612020-01-11 23:36:17 -06008521 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
8522 << " functions, result: " << Changed << ".\n");
8523 return Changed == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00008524}
8525
8526PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008527 FunctionAnalysisManager &FAM =
8528 AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
8529 AnalysisGetter AG(FAM);
8530
8531 SetVector<Function *> Functions;
8532 for (Function &F : M)
8533 Functions.insert(&F);
8534
8535 CallGraphUpdater CGUpdater;
8536 InformationCache InfoCache(M, AG, /* CGSCC */ nullptr);
8537 if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
8538 // FIXME: Think about passes we will preserve and add them here.
8539 return PreservedAnalyses::none();
8540 }
8541 return PreservedAnalyses::all();
8542}
8543
8544PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C,
8545 CGSCCAnalysisManager &AM,
8546 LazyCallGraph &CG,
8547 CGSCCUpdateResult &UR) {
8548 FunctionAnalysisManager &FAM =
8549 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
8550 AnalysisGetter AG(FAM);
8551
8552 SetVector<Function *> Functions;
8553 for (LazyCallGraph::Node &N : C)
8554 Functions.insert(&N.getFunction());
8555
8556 if (Functions.empty())
8557 return PreservedAnalyses::all();
8558
8559 Module &M = *Functions.back()->getParent();
8560 CallGraphUpdater CGUpdater;
8561 CGUpdater.initialize(CG, C, AM, UR);
8562 InformationCache InfoCache(M, AG, /* CGSCC */ &Functions);
8563 if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00008564 // FIXME: Think about passes we will preserve and add them here.
8565 return PreservedAnalyses::none();
8566 }
8567 return PreservedAnalyses::all();
8568}
8569
8570namespace {
8571
8572struct AttributorLegacyPass : public ModulePass {
8573 static char ID;
8574
8575 AttributorLegacyPass() : ModulePass(ID) {
8576 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
8577 }
8578
8579 bool runOnModule(Module &M) override {
8580 if (skipModule(M))
8581 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008582
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00008583 AnalysisGetter AG;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008584 SetVector<Function *> Functions;
8585 for (Function &F : M)
8586 Functions.insert(&F);
8587
8588 CallGraphUpdater CGUpdater;
8589 InformationCache InfoCache(M, AG, /* CGSCC */ nullptr);
8590 return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater);
Johannes Doerfertaade7822019-06-05 03:02:24 +00008591 }
8592
8593 void getAnalysisUsage(AnalysisUsage &AU) const override {
8594 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008595 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00008596 }
8597};
8598
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008599struct AttributorCGSCCLegacyPass : public CallGraphSCCPass {
8600 CallGraphUpdater CGUpdater;
8601 static char ID;
8602
8603 AttributorCGSCCLegacyPass() : CallGraphSCCPass(ID) {
8604 initializeAttributorCGSCCLegacyPassPass(*PassRegistry::getPassRegistry());
8605 }
8606
8607 bool runOnSCC(CallGraphSCC &SCC) override {
8608 if (skipSCC(SCC))
8609 return false;
8610
8611 SetVector<Function *> Functions;
8612 for (CallGraphNode *CGN : SCC)
8613 if (Function *Fn = CGN->getFunction())
8614 if (!Fn->isDeclaration())
8615 Functions.insert(Fn);
8616
8617 if (Functions.empty())
8618 return false;
8619
8620 AnalysisGetter AG;
8621 CallGraph &CG = const_cast<CallGraph &>(SCC.getCallGraph());
8622 CGUpdater.initialize(CG, SCC);
8623 Module &M = *Functions.back()->getParent();
8624 InformationCache InfoCache(M, AG, /* CGSCC */ &Functions);
8625 return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater);
8626 }
8627
8628 bool doFinalization(CallGraph &CG) override { return CGUpdater.finalize(); }
8629
8630 void getAnalysisUsage(AnalysisUsage &AU) const override {
8631 // FIXME: Think about passes we will preserve and add them here.
8632 AU.addRequired<TargetLibraryInfoWrapperPass>();
8633 CallGraphSCCPass::getAnalysisUsage(AU);
8634 }
8635};
8636
Johannes Doerfertaade7822019-06-05 03:02:24 +00008637} // end anonymous namespace
8638
8639Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008640Pass *llvm::createAttributorCGSCCLegacyPass() {
8641 return new AttributorCGSCCLegacyPass();
8642}
Johannes Doerfertaade7822019-06-05 03:02:24 +00008643
8644char AttributorLegacyPass::ID = 0;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008645char AttributorCGSCCLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008646
8647const char AAReturnedValues::ID = 0;
8648const char AANoUnwind::ID = 0;
8649const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00008650const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008651const char AANonNull::ID = 0;
8652const char AANoRecurse::ID = 0;
8653const char AAWillReturn::ID = 0;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06008654const char AAUndefinedBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008655const char AANoAlias::ID = 0;
Pankaj Gode04945c92019-11-22 18:40:47 +05308656const char AAReachability::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008657const char AANoReturn::ID = 0;
8658const char AAIsDead::ID = 0;
8659const char AADereferenceable::ID = 0;
8660const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00008661const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008662const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008663const char AAHeapToStack::ID = 0;
Johannes Doerfert89c2e732019-10-30 17:20:20 -05008664const char AAPrivatizablePtr::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008665const char AAMemoryBehavior::ID = 0;
Johannes Doerfert282f5d72020-01-26 02:51:57 -06008666const char AAMemoryLocation::ID = 0;
Hideto Ueno188f9a32020-01-15 15:25:52 +09008667const char AAValueConstantRange::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008668
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008669// Macro magic to create the static generator function for attributes that
8670// follow the naming scheme.
8671
8672#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
8673 case IRPosition::PK: \
8674 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
8675
8676#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
8677 case IRPosition::PK: \
8678 AA = new CLASS##SUFFIX(IRP); \
8679 break;
8680
8681#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
8682 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
8683 CLASS *AA = nullptr; \
8684 switch (IRP.getPositionKind()) { \
8685 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
8686 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
8687 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
8688 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
8689 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
8690 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
8691 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
8692 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
8693 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008694 return *AA; \
8695 }
8696
8697#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
8698 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
8699 CLASS *AA = nullptr; \
8700 switch (IRP.getPositionKind()) { \
8701 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
8702 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
8703 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
8704 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
8705 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
8706 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
8707 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
8708 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
8709 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008710 return *AA; \
8711 }
8712
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008713#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
8714 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
8715 CLASS *AA = nullptr; \
8716 switch (IRP.getPositionKind()) { \
8717 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
8718 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
8719 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
8720 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
8721 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
8722 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
8723 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
8724 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
8725 } \
8726 return *AA; \
8727 }
8728
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008729#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
8730 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
8731 CLASS *AA = nullptr; \
8732 switch (IRP.getPositionKind()) { \
8733 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
8734 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
8735 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
8736 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
8737 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
8738 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
8739 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
8740 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
8741 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008742 return *AA; \
8743 }
8744
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008745#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
8746 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
8747 CLASS *AA = nullptr; \
8748 switch (IRP.getPositionKind()) { \
8749 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
8750 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
8751 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
8752 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
8753 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
8754 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
8755 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
8756 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
8757 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008758 return *AA; \
8759 }
8760
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008761CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
8762CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008763CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
8764CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
8765CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008766CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
Johannes Doerfert282f5d72020-01-26 02:51:57 -06008767CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008768
8769CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
8770CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
Johannes Doerfert89c2e732019-10-30 17:20:20 -05008771CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008772CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
8773CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00008774CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Hideto Ueno188f9a32020-01-15 15:25:52 +09008775CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008776
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008777CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008778CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01008779CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008780
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008781CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
Pankaj Gode04945c92019-11-22 18:40:47 +05308782CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06008783CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008784
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008785CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
8786
Johannes Doerfertd4bea882019-10-07 23:28:54 +00008787#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008788#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00008789#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008790#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008791#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008792#undef SWITCH_PK_CREATE
8793#undef SWITCH_PK_INV
8794
Johannes Doerfertaade7822019-06-05 03:02:24 +00008795INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
8796 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008797INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00008798INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
8799 "Deduce and propagate attributes", false, false)
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008800INITIALIZE_PASS_BEGIN(AttributorCGSCCLegacyPass, "attributor-cgscc",
8801 "Deduce and propagate attributes (CGSCC pass)", false,
8802 false)
8803INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
8804INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
8805INITIALIZE_PASS_END(AttributorCGSCCLegacyPass, "attributor-cgscc",
8806 "Deduce and propagate attributes (CGSCC pass)", false,
8807 false)