blob: aeae4c08773f2c3e0cb50134e9166ff72d66d64b [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 {
Johannes Doerfert6185fb12020-02-20 02:02:57 -0600681 SmallVector<Attribute, 4> Attrs;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000682 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000683 for (Attribute::AttrKind AK : AKs)
Johannes Doerfert6185fb12020-02-20 02:02:57 -0600684 if (EquivIRP.getAttrsFromIRAttr(AK, Attrs))
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000685 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000686 // The first position returned by the SubsumingPositionIterator is
687 // always the position itself. If we ignore subsuming positions we
688 // are done after the first iteration.
689 if (IgnoreSubsumingPositions)
690 break;
691 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000692 return false;
693}
694
695void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600696 SmallVectorImpl<Attribute> &Attrs,
697 bool IgnoreSubsumingPositions) const {
698 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert6185fb12020-02-20 02:02:57 -0600699 for (Attribute::AttrKind AK : AKs)
700 EquivIRP.getAttrsFromIRAttr(AK, Attrs);
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600701 // The first position returned by the SubsumingPositionIterator is
702 // always the position itself. If we ignore subsuming positions we
703 // are done after the first iteration.
704 if (IgnoreSubsumingPositions)
705 break;
706 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000707}
708
Johannes Doerfert6185fb12020-02-20 02:02:57 -0600709bool IRPosition::getAttrsFromIRAttr(Attribute::AttrKind AK,
710 SmallVectorImpl<Attribute> &Attrs) const {
711 if (getPositionKind() == IRP_INVALID || getPositionKind() == IRP_FLOAT)
712 return false;
713
714 AttributeList AttrList;
715 if (ImmutableCallSite ICS = ImmutableCallSite(&getAnchorValue()))
716 AttrList = ICS.getAttributes();
717 else
718 AttrList = getAssociatedFunction()->getAttributes();
719
720 bool HasAttr = AttrList.hasAttribute(getAttrIdx(), AK);
721 if (HasAttr)
722 Attrs.push_back(AttrList.getAttribute(getAttrIdx(), AK));
723 return HasAttr;
724}
725
726
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000727void IRPosition::verify() {
728 switch (KindOrArgNo) {
729 default:
730 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
731 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
732 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000733 if (isa<Argument>(AnchorVal)) {
734 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000735 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000736 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
737 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000738 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000739 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000740 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000741 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
742 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000743 "Associated value mismatch!");
744 }
745 break;
746 case IRP_INVALID:
747 assert(!AnchorVal && "Expected no value for an invalid position!");
748 break;
749 case IRP_FLOAT:
750 assert((!isa<CallBase>(&getAssociatedValue()) &&
751 !isa<Argument>(&getAssociatedValue())) &&
752 "Expected specialized kind for call base and argument values!");
753 break;
754 case IRP_RETURNED:
755 assert(isa<Function>(AnchorVal) &&
756 "Expected function for a 'returned' position!");
757 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
758 break;
759 case IRP_CALL_SITE_RETURNED:
760 assert((isa<CallBase>(AnchorVal)) &&
761 "Expected call base for 'call site returned' position!");
762 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
763 break;
764 case IRP_CALL_SITE:
765 assert((isa<CallBase>(AnchorVal)) &&
766 "Expected call base for 'call site function' position!");
767 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
768 break;
769 case IRP_FUNCTION:
770 assert(isa<Function>(AnchorVal) &&
771 "Expected function for a 'function' position!");
772 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
773 break;
774 }
775}
776
Benjamin Kramer564a9de2020-02-17 17:55:03 +0100777namespace {
778
Johannes Doerfert1a746452019-10-20 22:28:49 -0500779/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000780/// information in \p R and indicate/return if \p S did change (as-in update is
781/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000782template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500783ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000784 auto Assumed = S.getAssumed();
785 S ^= R;
786 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
787 : ChangeStatus::CHANGED;
788}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000789
Johannes Doerfert234eda52019-08-16 19:51:23 +0000790/// Clamp the information known for all returned values of a function
791/// (identified by \p QueryingAA) into \p S.
792template <typename AAType, typename StateType = typename AAType::StateType>
793static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
794 StateType &S) {
795 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600796 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000797
798 assert((QueryingAA.getIRPosition().getPositionKind() ==
799 IRPosition::IRP_RETURNED ||
800 QueryingAA.getIRPosition().getPositionKind() ==
801 IRPosition::IRP_CALL_SITE_RETURNED) &&
802 "Can only clamp returned value states for a function returned or call "
803 "site returned position!");
804
805 // Use an optional state as there might not be any return values and we want
806 // to join (IntegerState::operator&) the state of all there are.
807 Optional<StateType> T;
808
809 // Callback for each possibly returned value.
810 auto CheckReturnValue = [&](Value &RV) -> bool {
811 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000812 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
813 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
814 << " @ " << RVPos << "\n");
815 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000816 if (T.hasValue())
817 *T &= AAS;
818 else
819 T = AAS;
820 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
821 << "\n");
822 return T->isValidState();
823 };
824
825 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
826 S.indicatePessimisticFixpoint();
827 else if (T.hasValue())
828 S ^= *T;
829}
830
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000831/// Helper class to compose two generic deduction
832template <typename AAType, typename Base, typename StateType,
833 template <typename...> class F, template <typename...> class G>
834struct AAComposeTwoGenericDeduction
835 : public F<AAType, G<AAType, Base, StateType>, StateType> {
836 AAComposeTwoGenericDeduction(const IRPosition &IRP)
837 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
838
839 /// See AbstractAttribute::updateImpl(...).
840 ChangeStatus updateImpl(Attributor &A) override {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100841 ChangeStatus ChangedF =
842 F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000843 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
844 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000845 }
846};
847
Johannes Doerfert234eda52019-08-16 19:51:23 +0000848/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000849template <typename AAType, typename Base,
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600850 typename StateType = typename Base::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000851struct AAReturnedFromReturnedValues : public Base {
852 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000853
854 /// See AbstractAttribute::updateImpl(...).
855 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600856 StateType S(StateType::getBestState(this->getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000857 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000858 // TODO: If we know we visited all returned values, thus no are assumed
859 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000860 return clampStateAndIndicateChange<StateType>(this->getState(), S);
861 }
862};
863
864/// Clamp the information known at all call sites for a given argument
865/// (identified by \p QueryingAA) into \p S.
866template <typename AAType, typename StateType = typename AAType::StateType>
867static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
868 StateType &S) {
869 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600870 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000871
872 assert(QueryingAA.getIRPosition().getPositionKind() ==
873 IRPosition::IRP_ARGUMENT &&
874 "Can only clamp call site argument states for an argument position!");
875
876 // Use an optional state as there might not be any return values and we want
877 // to join (IntegerState::operator&) the state of all there are.
878 Optional<StateType> T;
879
880 // The argument number which is also the call site argument number.
881 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
882
Johannes Doerfert661db042019-10-07 23:14:58 +0000883 auto CallSiteCheck = [&](AbstractCallSite ACS) {
884 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
885 // Check if a coresponding argument was found or if it is on not associated
886 // (which can happen for callback calls).
887 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
888 return false;
889
890 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
891 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
892 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000893 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000894 if (T.hasValue())
895 *T &= AAS;
896 else
897 T = AAS;
898 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
899 << "\n");
900 return T->isValidState();
901 };
902
Johannes Doerfert368f7ee2019-12-30 16:12:36 -0600903 bool AllCallSitesKnown;
904 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
905 AllCallSitesKnown))
Johannes Doerfert234eda52019-08-16 19:51:23 +0000906 S.indicatePessimisticFixpoint();
907 else if (T.hasValue())
908 S ^= *T;
909}
910
911/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000912template <typename AAType, typename Base,
913 typename StateType = typename AAType::StateType>
914struct AAArgumentFromCallSiteArguments : public Base {
915 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000916
917 /// See AbstractAttribute::updateImpl(...).
918 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertea5fabe2020-01-28 09:46:15 -0600919 StateType S(StateType::getBestState(this->getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000920 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000921 // TODO: If we know we visited all incoming values, thus no are assumed
922 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000923 return clampStateAndIndicateChange<StateType>(this->getState(), S);
924 }
925};
926
927/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000928template <typename AAType, typename Base,
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600929 typename StateType = typename Base::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000930struct AACallSiteReturnedFromReturned : public Base {
931 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000932
933 /// See AbstractAttribute::updateImpl(...).
934 ChangeStatus updateImpl(Attributor &A) override {
935 assert(this->getIRPosition().getPositionKind() ==
936 IRPosition::IRP_CALL_SITE_RETURNED &&
937 "Can only wrap function returned positions for call site returned "
938 "positions!");
939 auto &S = this->getState();
940
941 const Function *AssociatedFunction =
942 this->getIRPosition().getAssociatedFunction();
943 if (!AssociatedFunction)
944 return S.indicatePessimisticFixpoint();
945
946 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000947 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000948 return clampStateAndIndicateChange(
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600949 S, static_cast<const StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000950 }
951};
952
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000953/// Helper class for generic deduction using must-be-executed-context
954/// Base class is required to have `followUse` method.
955
956/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000957/// U - Underlying use.
958/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000959/// `followUse` returns true if the value should be tracked transitively.
960
961template <typename AAType, typename Base,
962 typename StateType = typename AAType::StateType>
963struct AAFromMustBeExecutedContext : public Base {
964 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
965
966 void initialize(Attributor &A) override {
967 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500968 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000969 Instruction *CtxI = IRP.getCtxI();
970
971 if (!CtxI)
972 return;
973
974 for (const Use &U : IRP.getAssociatedValue().uses())
975 Uses.insert(&U);
976 }
977
978 /// See AbstractAttribute::updateImpl(...).
979 ChangeStatus updateImpl(Attributor &A) override {
980 auto BeforeState = this->getState();
981 auto &S = this->getState();
982 Instruction *CtxI = this->getIRPosition().getCtxI();
983 if (!CtxI)
984 return ChangeStatus::UNCHANGED;
985
986 MustBeExecutedContextExplorer &Explorer =
987 A.getInfoCache().getMustBeExecutedContextExplorer();
988
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500989 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100990 for (unsigned u = 0; u < Uses.size(); ++u) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500991 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000992 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500993 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000994 if (Found && Base::followUse(A, U, UserI))
995 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500996 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000997 }
998 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000999
1000 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
1001 }
1002
1003private:
1004 /// Container for (transitive) uses of the associated value.
1005 SetVector<const Use *> Uses;
1006};
1007
1008template <typename AAType, typename Base,
1009 typename StateType = typename AAType::StateType>
1010using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
1011 AAComposeTwoGenericDeduction<AAType, Base, StateType,
1012 AAFromMustBeExecutedContext,
1013 AAArgumentFromCallSiteArguments>;
1014
1015template <typename AAType, typename Base,
1016 typename StateType = typename AAType::StateType>
1017using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
1018 AAComposeTwoGenericDeduction<AAType, Base, StateType,
1019 AAFromMustBeExecutedContext,
1020 AACallSiteReturnedFromReturned>;
1021
Stefan Stipanovic53605892019-06-27 11:27:54 +00001022/// -----------------------NoUnwind Function Attribute--------------------------
1023
Johannes Doerfert344d0382019-08-07 22:34:26 +00001024struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001025 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +00001026
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001027 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +00001028 return getAssumed() ? "nounwind" : "may-unwind";
1029 }
1030
1031 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001032 ChangeStatus updateImpl(Attributor &A) override {
1033 auto Opcodes = {
1034 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
1035 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
1036 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
1037
1038 auto CheckForNoUnwind = [&](Instruction &I) {
1039 if (!I.mayThrow())
1040 return true;
1041
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001042 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1043 const auto &NoUnwindAA =
1044 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
1045 return NoUnwindAA.isAssumedNoUnwind();
1046 }
1047 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001048 };
1049
1050 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
1051 return indicatePessimisticFixpoint();
1052
1053 return ChangeStatus::UNCHANGED;
1054 }
Stefan Stipanovic53605892019-06-27 11:27:54 +00001055};
1056
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001057struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001058 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001059
1060 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001061 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001062};
1063
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001064/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001065struct AANoUnwindCallSite final : AANoUnwindImpl {
1066 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
1067
1068 /// See AbstractAttribute::initialize(...).
1069 void initialize(Attributor &A) override {
1070 AANoUnwindImpl::initialize(A);
1071 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001072 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001073 indicatePessimisticFixpoint();
1074 }
1075
1076 /// See AbstractAttribute::updateImpl(...).
1077 ChangeStatus updateImpl(Attributor &A) override {
1078 // TODO: Once we have call site specific value information we can provide
1079 // call site specific liveness information and then it makes
1080 // sense to specialize attributes for call sites arguments instead of
1081 // redirecting requests to the callee argument.
1082 Function *F = getAssociatedFunction();
1083 const IRPosition &FnPos = IRPosition::function(*F);
1084 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
1085 return clampStateAndIndicateChange(
1086 getState(),
1087 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
1088 }
1089
1090 /// See AbstractAttribute::trackStatistics()
1091 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
1092};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001093
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001094/// --------------------- Function Return Values -------------------------------
1095
1096/// "Attribute" that collects all potential returned values and the return
1097/// instructions that they arise from.
1098///
1099/// If there is a unique returned value R, the manifest method will:
1100/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +00001101class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001102
1103 /// Mapping of values potentially returned by the associated function to the
1104 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +00001105 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001106
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001107 /// Mapping to remember the number of returned values for a call site such
1108 /// that we can avoid updates if nothing changed.
1109 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
1110
1111 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001112 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001113
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001114 /// State flags
1115 ///
1116 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001117 bool IsFixed = false;
1118 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001119 ///}
1120
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001121public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001122 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001123
1124 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001125 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001126 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001127 IsFixed = false;
1128 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001129 ReturnedValues.clear();
1130
Johannes Doerfertdef99282019-08-14 21:29:37 +00001131 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001132 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001133 indicatePessimisticFixpoint();
1134 return;
1135 }
Johannes Doerferte273ac42020-01-12 00:13:03 -06001136 assert(!F->getReturnType()->isVoidTy() &&
1137 "Did not expect a void return type!");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001138
1139 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001140 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001141
1142 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001143 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001144 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001145 auto &ReturnInstSet = ReturnedValues[&Arg];
1146 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
1147 ReturnInstSet.insert(cast<ReturnInst>(RI));
1148
1149 indicateOptimisticFixpoint();
1150 return;
1151 }
1152 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001153
1154 if (!F->hasExactDefinition())
1155 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001156 }
1157
1158 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001159 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001160
1161 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001162 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001163
1164 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001165 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001166
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001167 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00001168 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001169
Johannes Doerfertdef99282019-08-14 21:29:37 +00001170 llvm::iterator_range<iterator> returned_values() override {
1171 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1172 }
1173
1174 llvm::iterator_range<const_iterator> returned_values() const override {
1175 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1176 }
1177
Johannes Doerfert695089e2019-08-23 15:23:49 +00001178 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001179 return UnresolvedCalls;
1180 }
1181
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001182 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001183 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001184 return isValidState() ? ReturnedValues.size() : -1;
1185 }
1186
1187 /// Return an assumed unique return value if a single candidate is found. If
1188 /// there cannot be one, return a nullptr. If it is not clear yet, return the
1189 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001190 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001191
Johannes Doerfert14a04932019-08-07 22:27:24 +00001192 /// See AbstractState::checkForAllReturnedValues(...).
1193 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001194 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001195 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001196
1197 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001198 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001199
1200 /// See AbstractState::isAtFixpoint().
1201 bool isAtFixpoint() const override { return IsFixed; }
1202
1203 /// See AbstractState::isValidState().
1204 bool isValidState() const override { return IsValidState; }
1205
1206 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001207 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001208 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001209 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001210 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001211
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001212 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001213 IsFixed = true;
1214 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001215 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001216 }
1217};
1218
1219ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
1220 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1221
1222 // Bookkeeping.
1223 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001224 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
1225 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001226
1227 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001228 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001229
1230 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
1231 return Changed;
1232
1233 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001234 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
1235 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001236
Johannes Doerfert23400e612019-08-23 17:41:37 +00001237 // Callback to replace the uses of CB with the constant C.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06001238 auto ReplaceCallSiteUsersWith = [&A](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +00001239 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +00001240 return ChangeStatus::UNCHANGED;
Johannes Doerfert4c62a352020-01-12 00:17:08 -06001241 if (A.changeValueAfterManifest(CB, C))
1242 return ChangeStatus::CHANGED;
1243 return ChangeStatus::UNCHANGED;
Johannes Doerfert23400e612019-08-23 17:41:37 +00001244 };
1245
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001246 // If the assumed unique return value is an argument, annotate it.
1247 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05001248 // TODO: This should be handled differently!
1249 this->AnchorVal = UniqueRVArg;
1250 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +00001251 Changed = IRAttribute::manifest(A);
1252 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
1253 // We can replace the returned value with the unique returned constant.
1254 Value &AnchorValue = getAnchorValue();
1255 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1256 for (const Use &U : F->uses())
1257 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001258 if (CB->isCallee(&U)) {
1259 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001260 CB->getType() == RVC->getType()
1261 ? RVC
1262 : ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001263 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1264 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001265 } else {
1266 assert(isa<CallBase>(AnchorValue) &&
1267 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001268 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001269 AnchorValue.getType() == RVC->getType()
1270 ? RVC
1271 : ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001272 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001273 }
1274 if (Changed == ChangeStatus::CHANGED)
1275 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1276 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001277 }
1278
1279 return Changed;
1280}
1281
1282const std::string AAReturnedValuesImpl::getAsStr() const {
1283 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001284 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001285 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001286}
1287
Johannes Doerfert14a04932019-08-07 22:27:24 +00001288Optional<Value *>
1289AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1290 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001291 // undef values that can also be present, it is assumed to be the actual
1292 // return value and forwarded to the caller of this method. If there are
1293 // multiple, a nullptr is returned indicating there cannot be a unique
1294 // returned value.
1295 Optional<Value *> UniqueRV;
1296
Johannes Doerfert14a04932019-08-07 22:27:24 +00001297 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001298 // If we found a second returned value and neither the current nor the saved
1299 // one is an undef, there is no unique returned value. Undefs are special
1300 // since we can pretend they have any value.
1301 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1302 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1303 UniqueRV = nullptr;
1304 return false;
1305 }
1306
1307 // Do not overwrite a value with an undef.
1308 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1309 UniqueRV = &RV;
1310
1311 return true;
1312 };
1313
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001314 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001315 UniqueRV = nullptr;
1316
1317 return UniqueRV;
1318}
1319
Johannes Doerfert14a04932019-08-07 22:27:24 +00001320bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001321 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001322 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001323 if (!isValidState())
1324 return false;
1325
1326 // Check all returned values but ignore call sites as long as we have not
1327 // encountered an overdefined one during an update.
1328 for (auto &It : ReturnedValues) {
1329 Value *RV = It.first;
1330
Johannes Doerfertdef99282019-08-14 21:29:37 +00001331 CallBase *CB = dyn_cast<CallBase>(RV);
1332 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001333 continue;
1334
Johannes Doerfert695089e2019-08-23 15:23:49 +00001335 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001336 return false;
1337 }
1338
1339 return true;
1340}
1341
Johannes Doerfertece81902019-08-12 22:05:53 +00001342ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001343 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1344 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001345
Johannes Doerfertdef99282019-08-14 21:29:37 +00001346 // State used in the value traversals starting in returned values.
1347 struct RVState {
1348 // The map in which we collect return values -> return instrs.
1349 decltype(ReturnedValues) &RetValsMap;
1350 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001351 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001352 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001353 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001354 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001355
Johannes Doerfertdef99282019-08-14 21:29:37 +00001356 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001357 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001358 auto Size = RVS.RetValsMap[&Val].size();
1359 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1360 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1361 RVS.Changed |= Inserted;
1362 LLVM_DEBUG({
1363 if (Inserted)
1364 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1365 << " => " << RVS.RetInsts.size() << "\n";
1366 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001367 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001368 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001369
Johannes Doerfertdef99282019-08-14 21:29:37 +00001370 // Helper method to invoke the generic value traversal.
1371 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1372 IRPosition RetValPos = IRPosition::value(RV);
1373 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1374 RVS, VisitValueCB);
1375 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001376
Johannes Doerfertdef99282019-08-14 21:29:37 +00001377 // Callback for all "return intructions" live in the associated function.
1378 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1379 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001380 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001381 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001382 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1383 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001384
Johannes Doerfertdef99282019-08-14 21:29:37 +00001385 // Start by discovering returned values from all live returned instructions in
1386 // the associated function.
1387 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1388 return indicatePessimisticFixpoint();
1389
1390 // Once returned values "directly" present in the code are handled we try to
1391 // resolve returned calls.
1392 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001393 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001394 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1395 << " by #" << It.second.size() << " RIs\n");
1396 CallBase *CB = dyn_cast<CallBase>(It.first);
1397 if (!CB || UnresolvedCalls.count(CB))
1398 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001399
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001400 if (!CB->getCalledFunction()) {
1401 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1402 << "\n");
1403 UnresolvedCalls.insert(CB);
1404 continue;
1405 }
1406
1407 // TODO: use the function scope once we have call site AAReturnedValues.
1408 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1409 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001410 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06001411 << RetValAA << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001412
1413 // Skip dead ends, thus if we do not know anything about the returned
1414 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001415 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001416 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1417 << "\n");
1418 UnresolvedCalls.insert(CB);
1419 continue;
1420 }
1421
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001422 // Do not try to learn partial information. If the callee has unresolved
1423 // return values we will treat the call as unresolved/opaque.
1424 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1425 if (!RetValAAUnresolvedCalls.empty()) {
1426 UnresolvedCalls.insert(CB);
1427 continue;
1428 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001429
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001430 // Now check if we can track transitively returned values. If possible, thus
1431 // if all return value can be represented in the current scope, do so.
1432 bool Unresolved = false;
1433 for (auto &RetValAAIt : RetValAA.returned_values()) {
1434 Value *RetVal = RetValAAIt.first;
1435 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1436 isa<Constant>(RetVal))
1437 continue;
1438 // Anything that did not fit in the above categories cannot be resolved,
1439 // mark the call as unresolved.
1440 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1441 "cannot be translated: "
1442 << *RetVal << "\n");
1443 UnresolvedCalls.insert(CB);
1444 Unresolved = true;
1445 break;
1446 }
1447
1448 if (Unresolved)
1449 continue;
1450
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001451 // Now track transitively returned values.
1452 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1453 if (NumRetAA == RetValAA.getNumReturnValues()) {
1454 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1455 "changed since it was seen last\n");
1456 continue;
1457 }
1458 NumRetAA = RetValAA.getNumReturnValues();
1459
Johannes Doerfertdef99282019-08-14 21:29:37 +00001460 for (auto &RetValAAIt : RetValAA.returned_values()) {
1461 Value *RetVal = RetValAAIt.first;
1462 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1463 // Arguments are mapped to call site operands and we begin the traversal
1464 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001465 bool Unused = false;
1466 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001467 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1468 continue;
1469 } else if (isa<CallBase>(RetVal)) {
1470 // Call sites are resolved by the callee attribute over time, no need to
1471 // do anything for us.
1472 continue;
1473 } else if (isa<Constant>(RetVal)) {
1474 // Constants are valid everywhere, we can simply take them.
1475 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1476 continue;
1477 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001478 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001479 }
1480
Johannes Doerfertdef99282019-08-14 21:29:37 +00001481 // To avoid modifications to the ReturnedValues map while we iterate over it
1482 // we kept record of potential new entries in a copy map, NewRVsMap.
1483 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001484 assert(!It.second.empty() && "Entry does not add anything.");
1485 auto &ReturnInsts = ReturnedValues[It.first];
1486 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001487 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001488 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1489 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001490 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001491 }
1492 }
1493
Johannes Doerfertdef99282019-08-14 21:29:37 +00001494 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1495 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001496}
1497
Johannes Doerfertdef99282019-08-14 21:29:37 +00001498struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1499 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1500
1501 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001502 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001503};
1504
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001505/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001506struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1507 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1508
1509 /// See AbstractAttribute::initialize(...).
1510 void initialize(Attributor &A) override {
1511 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001512 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001513 // sense to specialize attributes for call sites instead of
1514 // redirecting requests to the callee.
1515 llvm_unreachable("Abstract attributes for returned values are not "
1516 "supported for call sites yet!");
1517 }
1518
1519 /// See AbstractAttribute::updateImpl(...).
1520 ChangeStatus updateImpl(Attributor &A) override {
1521 return indicatePessimisticFixpoint();
1522 }
1523
1524 /// See AbstractAttribute::trackStatistics()
1525 void trackStatistics() const override {}
1526};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001527
Stefan Stipanovic06263672019-07-11 21:37:40 +00001528/// ------------------------ NoSync Function Attribute -------------------------
1529
Johannes Doerfert344d0382019-08-07 22:34:26 +00001530struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001531 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001532
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001533 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001534 return getAssumed() ? "nosync" : "may-sync";
1535 }
1536
1537 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001538 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001539
Stefan Stipanovic06263672019-07-11 21:37:40 +00001540 /// Helper function used to determine whether an instruction is non-relaxed
1541 /// atomic. In other words, if an atomic instruction does not have unordered
1542 /// or monotonic ordering
1543 static bool isNonRelaxedAtomic(Instruction *I);
1544
1545 /// Helper function used to determine whether an instruction is volatile.
1546 static bool isVolatile(Instruction *I);
1547
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001548 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1549 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001550 static bool isNoSyncIntrinsic(Instruction *I);
1551};
1552
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001553bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001554 if (!I->isAtomic())
1555 return false;
1556
1557 AtomicOrdering Ordering;
1558 switch (I->getOpcode()) {
1559 case Instruction::AtomicRMW:
1560 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1561 break;
1562 case Instruction::Store:
1563 Ordering = cast<StoreInst>(I)->getOrdering();
1564 break;
1565 case Instruction::Load:
1566 Ordering = cast<LoadInst>(I)->getOrdering();
1567 break;
1568 case Instruction::Fence: {
1569 auto *FI = cast<FenceInst>(I);
1570 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1571 return false;
1572 Ordering = FI->getOrdering();
1573 break;
1574 }
1575 case Instruction::AtomicCmpXchg: {
1576 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1577 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1578 // Only if both are relaxed, than it can be treated as relaxed.
1579 // Otherwise it is non-relaxed.
1580 if (Success != AtomicOrdering::Unordered &&
1581 Success != AtomicOrdering::Monotonic)
1582 return true;
1583 if (Failure != AtomicOrdering::Unordered &&
1584 Failure != AtomicOrdering::Monotonic)
1585 return true;
1586 return false;
1587 }
1588 default:
1589 llvm_unreachable(
1590 "New atomic operations need to be known in the attributor.");
1591 }
1592
1593 // Relaxed.
1594 if (Ordering == AtomicOrdering::Unordered ||
1595 Ordering == AtomicOrdering::Monotonic)
1596 return false;
1597 return true;
1598}
1599
1600/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1601/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001602bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001603 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1604 switch (II->getIntrinsicID()) {
1605 /// Element wise atomic memory intrinsics are can only be unordered,
1606 /// therefore nosync.
1607 case Intrinsic::memset_element_unordered_atomic:
1608 case Intrinsic::memmove_element_unordered_atomic:
1609 case Intrinsic::memcpy_element_unordered_atomic:
1610 return true;
1611 case Intrinsic::memset:
1612 case Intrinsic::memmove:
1613 case Intrinsic::memcpy:
1614 if (!cast<MemIntrinsic>(II)->isVolatile())
1615 return true;
1616 return false;
1617 default:
1618 return false;
1619 }
1620 }
1621 return false;
1622}
1623
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001624bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001625 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1626 "Calls should not be checked here");
1627
1628 switch (I->getOpcode()) {
1629 case Instruction::AtomicRMW:
1630 return cast<AtomicRMWInst>(I)->isVolatile();
1631 case Instruction::Store:
1632 return cast<StoreInst>(I)->isVolatile();
1633 case Instruction::Load:
1634 return cast<LoadInst>(I)->isVolatile();
1635 case Instruction::AtomicCmpXchg:
1636 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1637 default:
1638 return false;
1639 }
1640}
1641
Johannes Doerfertece81902019-08-12 22:05:53 +00001642ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001643
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001644 auto CheckRWInstForNoSync = [&](Instruction &I) {
1645 /// We are looking for volatile instructions or Non-Relaxed atomics.
Pankaj Godeb9a26a82019-11-22 14:46:43 +05301646 /// FIXME: We should improve the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001647
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001648 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1649 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001650
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001651 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1652 if (ICS.hasFnAttr(Attribute::NoSync))
1653 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001654
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001655 const auto &NoSyncAA =
1656 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1657 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001658 return true;
1659 return false;
1660 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001661
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001662 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1663 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001664
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001665 return false;
1666 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001667
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001668 auto CheckForNoSync = [&](Instruction &I) {
1669 // At this point we handled all read/write effects and they are all
1670 // nosync, so they can be skipped.
1671 if (I.mayReadOrWriteMemory())
1672 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001673
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001674 // non-convergent and readnone imply nosync.
1675 return !ImmutableCallSite(&I).isConvergent();
1676 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001677
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001678 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1679 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001680 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001681
Stefan Stipanovic06263672019-07-11 21:37:40 +00001682 return ChangeStatus::UNCHANGED;
1683}
1684
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001685struct AANoSyncFunction final : public AANoSyncImpl {
1686 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1687
1688 /// See AbstractAttribute::trackStatistics()
1689 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1690};
1691
1692/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001693struct AANoSyncCallSite final : AANoSyncImpl {
1694 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1695
1696 /// See AbstractAttribute::initialize(...).
1697 void initialize(Attributor &A) override {
1698 AANoSyncImpl::initialize(A);
1699 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001700 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001701 indicatePessimisticFixpoint();
1702 }
1703
1704 /// See AbstractAttribute::updateImpl(...).
1705 ChangeStatus updateImpl(Attributor &A) override {
1706 // TODO: Once we have call site specific value information we can provide
1707 // call site specific liveness information and then it makes
1708 // sense to specialize attributes for call sites arguments instead of
1709 // redirecting requests to the callee argument.
1710 Function *F = getAssociatedFunction();
1711 const IRPosition &FnPos = IRPosition::function(*F);
1712 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1713 return clampStateAndIndicateChange(
1714 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1715 }
1716
1717 /// See AbstractAttribute::trackStatistics()
1718 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1719};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001720
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001721/// ------------------------ No-Free Attributes ----------------------------
1722
Johannes Doerfert344d0382019-08-07 22:34:26 +00001723struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001724 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001725
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001726 /// See AbstractAttribute::updateImpl(...).
1727 ChangeStatus updateImpl(Attributor &A) override {
1728 auto CheckForNoFree = [&](Instruction &I) {
1729 ImmutableCallSite ICS(&I);
1730 if (ICS.hasFnAttr(Attribute::NoFree))
1731 return true;
1732
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001733 const auto &NoFreeAA =
1734 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1735 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001736 };
1737
1738 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1739 return indicatePessimisticFixpoint();
1740 return ChangeStatus::UNCHANGED;
1741 }
1742
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001743 /// See AbstractAttribute::getAsStr().
1744 const std::string getAsStr() const override {
1745 return getAssumed() ? "nofree" : "may-free";
1746 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001747};
1748
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001749struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001750 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001751
1752 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001753 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001754};
1755
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001756/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001757struct AANoFreeCallSite final : AANoFreeImpl {
1758 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1759
1760 /// See AbstractAttribute::initialize(...).
1761 void initialize(Attributor &A) override {
1762 AANoFreeImpl::initialize(A);
1763 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001764 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001765 indicatePessimisticFixpoint();
1766 }
1767
1768 /// See AbstractAttribute::updateImpl(...).
1769 ChangeStatus updateImpl(Attributor &A) override {
1770 // TODO: Once we have call site specific value information we can provide
1771 // call site specific liveness information and then it makes
1772 // sense to specialize attributes for call sites arguments instead of
1773 // redirecting requests to the callee argument.
1774 Function *F = getAssociatedFunction();
1775 const IRPosition &FnPos = IRPosition::function(*F);
1776 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1777 return clampStateAndIndicateChange(
1778 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1779 }
1780
1781 /// See AbstractAttribute::trackStatistics()
1782 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1783};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001784
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001785/// NoFree attribute for floating values.
1786struct AANoFreeFloating : AANoFreeImpl {
1787 AANoFreeFloating(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1788
1789 /// See AbstractAttribute::trackStatistics()
1790 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
1791
1792 /// See Abstract Attribute::updateImpl(...).
1793 ChangeStatus updateImpl(Attributor &A) override {
1794 const IRPosition &IRP = getIRPosition();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001795
1796 const auto &NoFreeAA =
1797 A.getAAFor<AANoFree>(*this, IRPosition::function_scope(IRP));
1798 if (NoFreeAA.isAssumedNoFree())
1799 return ChangeStatus::UNCHANGED;
1800
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001801 Value &AssociatedValue = getIRPosition().getAssociatedValue();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001802 auto Pred = [&](const Use &U, bool &Follow) -> bool {
1803 Instruction *UserI = cast<Instruction>(U.getUser());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001804 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001805 if (CB->isBundleOperand(&U))
1806 return false;
1807 if (!CB->isArgOperand(&U))
1808 return true;
1809 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001810
1811 const auto &NoFreeArg = A.getAAFor<AANoFree>(
1812 *this, IRPosition::callsite_argument(*CB, ArgNo));
Hideto Ueno63599bd2019-12-12 12:26:09 +00001813 return NoFreeArg.isAssumedNoFree();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001814 }
1815
1816 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
1817 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001818 Follow = true;
1819 return true;
Hideto Ueno4ecf2552019-12-12 13:42:40 +00001820 }
Johannes Doerfertf9555392020-01-10 14:49:45 -06001821 if (isa<ReturnInst>(UserI))
1822 return true;
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001823
1824 // Unknown user.
Hideto Ueno63599bd2019-12-12 12:26:09 +00001825 return false;
1826 };
1827 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001828 return indicatePessimisticFixpoint();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001829
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001830 return ChangeStatus::UNCHANGED;
1831 }
1832};
1833
1834/// NoFree attribute for a call site argument.
1835struct AANoFreeArgument final : AANoFreeFloating {
1836 AANoFreeArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1837
1838 /// See AbstractAttribute::trackStatistics()
1839 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
1840};
1841
1842/// NoFree attribute for call site arguments.
1843struct AANoFreeCallSiteArgument final : AANoFreeFloating {
1844 AANoFreeCallSiteArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1845
1846 /// See AbstractAttribute::updateImpl(...).
1847 ChangeStatus updateImpl(Attributor &A) override {
1848 // TODO: Once we have call site specific value information we can provide
1849 // call site specific liveness information and then it makes
1850 // sense to specialize attributes for call sites arguments instead of
1851 // redirecting requests to the callee argument.
1852 Argument *Arg = getAssociatedArgument();
1853 if (!Arg)
1854 return indicatePessimisticFixpoint();
1855 const IRPosition &ArgPos = IRPosition::argument(*Arg);
1856 auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
1857 return clampStateAndIndicateChange(
1858 getState(), static_cast<const AANoFree::StateType &>(ArgAA.getState()));
1859 }
1860
1861 /// See AbstractAttribute::trackStatistics()
1862 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
1863};
1864
1865/// NoFree attribute for function return value.
1866struct AANoFreeReturned final : AANoFreeFloating {
1867 AANoFreeReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {
1868 llvm_unreachable("NoFree is not applicable to function returns!");
1869 }
1870
1871 /// See AbstractAttribute::initialize(...).
1872 void initialize(Attributor &A) override {
1873 llvm_unreachable("NoFree is not applicable to function returns!");
1874 }
1875
1876 /// See AbstractAttribute::updateImpl(...).
1877 ChangeStatus updateImpl(Attributor &A) override {
1878 llvm_unreachable("NoFree is not applicable to function returns!");
1879 }
1880
1881 /// See AbstractAttribute::trackStatistics()
1882 void trackStatistics() const override {}
1883};
1884
1885/// NoFree attribute deduction for a call site return value.
1886struct AANoFreeCallSiteReturned final : AANoFreeFloating {
1887 AANoFreeCallSiteReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1888
1889 ChangeStatus manifest(Attributor &A) override {
1890 return ChangeStatus::UNCHANGED;
1891 }
1892 /// See AbstractAttribute::trackStatistics()
1893 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
1894};
1895
Hideto Ueno54869ec2019-07-15 06:49:04 +00001896/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001897static int64_t getKnownNonNullAndDerefBytesForUse(
1898 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1899 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001900 TrackUse = false;
1901
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001902 const Value *UseV = U->get();
1903 if (!UseV->getType()->isPointerTy())
1904 return 0;
1905
1906 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001907 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001908 bool NullPointerIsDefined =
1909 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001910 const DataLayout &DL = A.getInfoCache().getDL();
1911 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1912 if (ICS.isBundleOperand(U))
1913 return 0;
1914
1915 if (ICS.isCallee(U)) {
1916 IsNonNull |= !NullPointerIsDefined;
1917 return 0;
1918 }
1919
1920 unsigned ArgNo = ICS.getArgumentNo(U);
1921 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001922 // As long as we only use known information there is no need to track
1923 // dependences here.
1924 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP,
1925 /* TrackDependence */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001926 IsNonNull |= DerefAA.isKnownNonNull();
1927 return DerefAA.getKnownDereferenceableBytes();
1928 }
1929
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001930 // We need to follow common pointer manipulation uses to the accesses they
1931 // feed into. We can try to be smart to avoid looking through things we do not
1932 // like for now, e.g., non-inbounds GEPs.
1933 if (isa<CastInst>(I)) {
1934 TrackUse = true;
1935 return 0;
1936 }
1937 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001938 if (GEP->hasAllConstantIndices()) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001939 TrackUse = true;
1940 return 0;
1941 }
1942
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001943 int64_t Offset;
1944 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09001945 if (Base == &AssociatedValue &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06001946 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001947 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001948 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001949
1950 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001951 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001952 }
1953 }
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001954
1955 /// Corner case when an offset is 0.
1956 if (const Value *Base = getBasePointerOfAccessPointerOperand(
1957 I, Offset, DL, /*AllowNonInbounds*/ true)) {
1958 if (Offset == 0 && Base == &AssociatedValue &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06001959 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001960 int64_t DerefBytes =
1961 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType());
1962 IsNonNull |= !NullPointerIsDefined;
1963 return std::max(int64_t(0), DerefBytes);
1964 }
1965 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001966
1967 return 0;
1968}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001969
Johannes Doerfert344d0382019-08-07 22:34:26 +00001970struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001971 AANonNullImpl(const IRPosition &IRP)
1972 : AANonNull(IRP),
1973 NullIsDefined(NullPointerIsDefined(
1974 getAnchorScope(),
1975 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001976
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001977 /// See AbstractAttribute::initialize(...).
1978 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001979 if (!NullIsDefined &&
1980 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001981 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001982 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1983 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001984 else
1985 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001986 }
1987
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001988 /// See AAFromMustBeExecutedContext
1989 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1990 bool IsNonNull = false;
1991 bool TrackUse = false;
1992 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1993 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001994 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001995 return TrackUse;
1996 }
1997
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001998 /// See AbstractAttribute::getAsStr().
1999 const std::string getAsStr() const override {
2000 return getAssumed() ? "nonnull" : "may-null";
2001 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00002002
2003 /// Flag to determine if the underlying value can be null and still allow
2004 /// valid accesses.
2005 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00002006};
2007
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002008/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002009struct AANonNullFloating
2010 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
2011 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
2012 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00002013
Hideto Ueno54869ec2019-07-15 06:49:04 +00002014 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002015 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002016 ChangeStatus Change = Base::updateImpl(A);
2017 if (isKnownNonNull())
2018 return Change;
2019
Johannes Doerfertd82385b2019-10-13 20:48:26 +00002020 if (!NullIsDefined) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01002021 const auto &DerefAA =
2022 A.getAAFor<AADereferenceable>(*this, getIRPosition());
Johannes Doerfertd82385b2019-10-13 20:48:26 +00002023 if (DerefAA.getAssumedDereferenceableBytes())
2024 return Change;
2025 }
2026
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002027 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002028
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05002029 DominatorTree *DT = nullptr;
2030 InformationCache &InfoCache = A.getInfoCache();
2031 if (const Function *Fn = getAnchorScope())
2032 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
2033
Johannes Doerfert1a746452019-10-20 22:28:49 -05002034 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002035 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002036 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
2037 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05002038 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002039 T.indicatePessimisticFixpoint();
2040 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002041 // Use abstract attribute information.
2042 const AANonNull::StateType &NS =
2043 static_cast<const AANonNull::StateType &>(AA.getState());
2044 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002045 }
2046 return T.isValidState();
2047 };
2048
2049 StateType T;
2050 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
2051 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002052 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002053
2054 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002055 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002056
2057 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002058 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002059};
2060
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002061/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002062struct AANonNullReturned final
2063 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002064 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002065 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002066
2067 /// See AbstractAttribute::trackStatistics()
2068 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2069};
2070
Hideto Ueno54869ec2019-07-15 06:49:04 +00002071/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002072struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002073 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
2074 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002075 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002076 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
2077 AANonNullImpl>(
2078 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002079
2080 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002081 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002082};
2083
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002084struct AANonNullCallSiteArgument final : AANonNullFloating {
2085 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002086
2087 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00002088 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002089};
Johannes Doerfert007153e2019-08-05 23:26:06 +00002090
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002091/// NonNull attribute for a call site return position.
2092struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002093 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
2094 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002095 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002096 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
2097 AANonNullImpl>(
2098 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002099
2100 /// See AbstractAttribute::trackStatistics()
2101 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2102};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002103
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002104/// ------------------------ No-Recurse Attributes ----------------------------
2105
2106struct AANoRecurseImpl : public AANoRecurse {
2107 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
2108
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002109 /// See AbstractAttribute::getAsStr()
2110 const std::string getAsStr() const override {
2111 return getAssumed() ? "norecurse" : "may-recurse";
2112 }
2113};
2114
2115struct AANoRecurseFunction final : AANoRecurseImpl {
2116 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2117
Hideto Ueno63f60662019-09-21 15:13:19 +00002118 /// See AbstractAttribute::initialize(...).
2119 void initialize(Attributor &A) override {
2120 AANoRecurseImpl::initialize(A);
2121 if (const Function *F = getAnchorScope())
Johannes Doerfert26d02b02019-12-30 16:15:38 -06002122 if (A.getInfoCache().getSccSize(*F) != 1)
2123 indicatePessimisticFixpoint();
Hideto Ueno63f60662019-09-21 15:13:19 +00002124 }
2125
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002126 /// See AbstractAttribute::updateImpl(...).
2127 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00002128
Johannes Doerfert26d02b02019-12-30 16:15:38 -06002129 // If all live call sites are known to be no-recurse, we are as well.
2130 auto CallSitePred = [&](AbstractCallSite ACS) {
2131 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(
2132 *this, IRPosition::function(*ACS.getInstruction()->getFunction()),
2133 /* TrackDependence */ false, DepClassTy::OPTIONAL);
2134 return NoRecurseAA.isKnownNoRecurse();
2135 };
2136 bool AllCallSitesKnown;
2137 if (A.checkForAllCallSites(CallSitePred, *this, true, AllCallSitesKnown)) {
2138 // If we know all call sites and all are known no-recurse, we are done.
2139 // If all known call sites, which might not be all that exist, are known
2140 // to be no-recurse, we are not done but we can continue to assume
2141 // no-recurse. If one of the call sites we have not visited will become
2142 // live, another update is triggered.
2143 if (AllCallSitesKnown)
2144 indicateOptimisticFixpoint();
2145 return ChangeStatus::UNCHANGED;
2146 }
2147
2148 // If the above check does not hold anymore we look at the calls.
Hideto Ueno63f60662019-09-21 15:13:19 +00002149 auto CheckForNoRecurse = [&](Instruction &I) {
2150 ImmutableCallSite ICS(&I);
2151 if (ICS.hasFnAttr(Attribute::NoRecurse))
2152 return true;
2153
2154 const auto &NoRecurseAA =
2155 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
2156 if (!NoRecurseAA.isAssumedNoRecurse())
2157 return false;
2158
2159 // Recursion to the same function
2160 if (ICS.getCalledFunction() == getAnchorScope())
2161 return false;
2162
2163 return true;
2164 };
2165
2166 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
2167 return indicatePessimisticFixpoint();
2168 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002169 }
2170
2171 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2172};
2173
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002174/// NoRecurse attribute deduction for a call sites.
2175struct AANoRecurseCallSite final : AANoRecurseImpl {
2176 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2177
2178 /// See AbstractAttribute::initialize(...).
2179 void initialize(Attributor &A) override {
2180 AANoRecurseImpl::initialize(A);
2181 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002182 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002183 indicatePessimisticFixpoint();
2184 }
2185
2186 /// See AbstractAttribute::updateImpl(...).
2187 ChangeStatus updateImpl(Attributor &A) override {
2188 // TODO: Once we have call site specific value information we can provide
2189 // call site specific liveness information and then it makes
2190 // sense to specialize attributes for call sites arguments instead of
2191 // redirecting requests to the callee argument.
2192 Function *F = getAssociatedFunction();
2193 const IRPosition &FnPos = IRPosition::function(*F);
2194 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
2195 return clampStateAndIndicateChange(
2196 getState(),
2197 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
2198 }
2199
2200 /// See AbstractAttribute::trackStatistics()
2201 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2202};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002203
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002204/// -------------------- Undefined-Behavior Attributes ------------------------
2205
2206struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2207 AAUndefinedBehaviorImpl(const IRPosition &IRP) : AAUndefinedBehavior(IRP) {}
2208
2209 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert5732f562019-12-24 19:25:08 -06002210 // through a pointer (i.e. also branches etc.)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002211 ChangeStatus updateImpl(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002212 const size_t UBPrevSize = KnownUBInsts.size();
2213 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002214
Johannes Doerfert5732f562019-12-24 19:25:08 -06002215 auto InspectMemAccessInstForUB = [&](Instruction &I) {
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002216 // Skip instructions that are already saved.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002217 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002218 return true;
2219
Hideto Uenoef4febd2019-12-29 17:34:08 +09002220 // If we reach here, we know we have an instruction
2221 // that accesses memory through a pointer operand,
2222 // for which getPointerOperand() should give it to us.
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06002223 const Value *PtrOp = getPointerOperand(&I, /* AllowVolatile */ true);
Hideto Uenoef4febd2019-12-29 17:34:08 +09002224 assert(PtrOp &&
2225 "Expected pointer operand of memory accessing instruction");
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002226
Johannes Doerfert5732f562019-12-24 19:25:08 -06002227 // A memory access through a pointer is considered UB
2228 // only if the pointer has constant null value.
2229 // TODO: Expand it to not only check constant values.
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002230 if (!isa<ConstantPointerNull>(PtrOp)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002231 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002232 return true;
2233 }
Johannes Doerfert5732f562019-12-24 19:25:08 -06002234 const Type *PtrTy = PtrOp->getType();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002235
Johannes Doerfert5732f562019-12-24 19:25:08 -06002236 // Because we only consider instructions inside functions,
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002237 // assume that a parent function exists.
2238 const Function *F = I.getFunction();
2239
Johannes Doerfert5732f562019-12-24 19:25:08 -06002240 // A memory access using constant null pointer is only considered UB
2241 // if null pointer is _not_ defined for the target platform.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002242 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()))
2243 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002244 else
Hideto Uenoef4febd2019-12-29 17:34:08 +09002245 KnownUBInsts.insert(&I);
2246 return true;
2247 };
2248
2249 auto InspectBrInstForUB = [&](Instruction &I) {
2250 // A conditional branch instruction is considered UB if it has `undef`
2251 // condition.
2252
2253 // Skip instructions that are already saved.
2254 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2255 return true;
2256
2257 // We know we have a branch instruction.
2258 auto BrInst = cast<BranchInst>(&I);
2259
2260 // Unconditional branches are never considered UB.
2261 if (BrInst->isUnconditional())
2262 return true;
2263
2264 // Either we stopped and the appropriate action was taken,
2265 // or we got back a simplified value to continue.
2266 Optional<Value *> SimplifiedCond =
2267 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2268 if (!SimplifiedCond.hasValue())
2269 return true;
2270 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002271 return true;
2272 };
2273
Johannes Doerfert5732f562019-12-24 19:25:08 -06002274 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
2275 {Instruction::Load, Instruction::Store,
2276 Instruction::AtomicCmpXchg,
Johannes Doerfert23f41f12020-01-12 01:09:22 -06002277 Instruction::AtomicRMW},
2278 /* CheckBBLivenessOnly */ true);
2279 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br},
2280 /* CheckBBLivenessOnly */ true);
Hideto Uenoef4febd2019-12-29 17:34:08 +09002281 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
2282 UBPrevSize != KnownUBInsts.size())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002283 return ChangeStatus::CHANGED;
2284 return ChangeStatus::UNCHANGED;
2285 }
2286
Hideto Uenoef4febd2019-12-29 17:34:08 +09002287 bool isKnownToCauseUB(Instruction *I) const override {
2288 return KnownUBInsts.count(I);
2289 }
2290
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002291 bool isAssumedToCauseUB(Instruction *I) const override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002292 // In simple words, if an instruction is not in the assumed to _not_
2293 // cause UB, then it is assumed UB (that includes those
2294 // in the KnownUBInsts set). The rest is boilerplate
2295 // is to ensure that it is one of the instructions we test
2296 // for UB.
2297
2298 switch (I->getOpcode()) {
2299 case Instruction::Load:
2300 case Instruction::Store:
2301 case Instruction::AtomicCmpXchg:
2302 case Instruction::AtomicRMW:
2303 return !AssumedNoUBInsts.count(I);
2304 case Instruction::Br: {
2305 auto BrInst = cast<BranchInst>(I);
2306 if (BrInst->isUnconditional())
2307 return false;
2308 return !AssumedNoUBInsts.count(I);
2309 } break;
2310 default:
2311 return false;
2312 }
2313 return false;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002314 }
2315
2316 ChangeStatus manifest(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002317 if (KnownUBInsts.empty())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002318 return ChangeStatus::UNCHANGED;
Hideto Uenoef4febd2019-12-29 17:34:08 +09002319 for (Instruction *I : KnownUBInsts)
Hideto Uenocb5eb132019-12-27 02:39:37 +09002320 A.changeToUnreachableAfterManifest(I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002321 return ChangeStatus::CHANGED;
2322 }
2323
2324 /// See AbstractAttribute::getAsStr()
2325 const std::string getAsStr() const override {
2326 return getAssumed() ? "undefined-behavior" : "no-ub";
2327 }
2328
Hideto Uenoef4febd2019-12-29 17:34:08 +09002329 /// Note: The correctness of this analysis depends on the fact that the
2330 /// following 2 sets will stop changing after some point.
2331 /// "Change" here means that their size changes.
2332 /// The size of each set is monotonically increasing
2333 /// (we only add items to them) and it is upper bounded by the number of
2334 /// instructions in the processed function (we can never save more
2335 /// elements in either set than this number). Hence, at some point,
2336 /// they will stop increasing.
2337 /// Consequently, at some point, both sets will have stopped
2338 /// changing, effectively making the analysis reach a fixpoint.
2339
2340 /// Note: These 2 sets are disjoint and an instruction can be considered
2341 /// one of 3 things:
2342 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
2343 /// the KnownUBInsts set.
2344 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
2345 /// has a reason to assume it).
2346 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
2347 /// could not find a reason to assume or prove that it can cause UB,
2348 /// hence it assumes it doesn't. We have a set for these instructions
2349 /// so that we don't reprocess them in every update.
2350 /// Note however that instructions in this set may cause UB.
2351
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002352protected:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002353 /// A set of all live instructions _known_ to cause UB.
2354 SmallPtrSet<Instruction *, 8> KnownUBInsts;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002355
2356private:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002357 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
2358 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
2359
2360 // Should be called on updates in which if we're processing an instruction
2361 // \p I that depends on a value \p V, one of the following has to happen:
2362 // - If the value is assumed, then stop.
2363 // - If the value is known but undef, then consider it UB.
2364 // - Otherwise, do specific processing with the simplified value.
2365 // We return None in the first 2 cases to signify that an appropriate
2366 // action was taken and the caller should stop.
2367 // Otherwise, we return the simplified value that the caller should
2368 // use for specific processing.
2369 Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
2370 Instruction *I) {
2371 const auto &ValueSimplifyAA =
2372 A.getAAFor<AAValueSimplify>(*this, IRPosition::value(*V));
2373 Optional<Value *> SimplifiedV =
2374 ValueSimplifyAA.getAssumedSimplifiedValue(A);
2375 if (!ValueSimplifyAA.isKnown()) {
2376 // Don't depend on assumed values.
2377 return llvm::None;
2378 }
2379 if (!SimplifiedV.hasValue()) {
2380 // If it is known (which we tested above) but it doesn't have a value,
2381 // then we can assume `undef` and hence the instruction is UB.
2382 KnownUBInsts.insert(I);
2383 return llvm::None;
2384 }
2385 Value *Val = SimplifiedV.getValue();
2386 if (isa<UndefValue>(Val)) {
2387 KnownUBInsts.insert(I);
2388 return llvm::None;
2389 }
2390 return Val;
2391 }
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002392};
2393
2394struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
2395 AAUndefinedBehaviorFunction(const IRPosition &IRP)
2396 : AAUndefinedBehaviorImpl(IRP) {}
2397
2398 /// See AbstractAttribute::trackStatistics()
2399 void trackStatistics() const override {
2400 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
2401 "Number of instructions known to have UB");
2402 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
Hideto Uenoef4febd2019-12-29 17:34:08 +09002403 KnownUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002404 }
2405};
2406
Hideto Ueno11d37102019-07-17 15:15:43 +00002407/// ------------------------ Will-Return Attributes ----------------------------
2408
Hideto Ueno11d37102019-07-17 15:15:43 +00002409// Helper function that checks whether a function has any cycle.
2410// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002411static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00002412 SmallPtrSet<BasicBlock *, 32> Visited;
2413
2414 // Traverse BB by dfs and check whether successor is already visited.
2415 for (BasicBlock *BB : depth_first(&F)) {
2416 Visited.insert(BB);
2417 for (auto *SuccBB : successors(BB)) {
2418 if (Visited.count(SuccBB))
2419 return true;
2420 }
2421 }
2422 return false;
2423}
2424
2425// Helper function that checks the function have a loop which might become an
2426// endless loop
2427// FIXME: Any cycle is regarded as endless loop for now.
2428// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002429static bool containsPossiblyEndlessLoop(Function *F) {
2430 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00002431}
2432
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002433struct AAWillReturnImpl : public AAWillReturn {
2434 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00002435
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002436 /// See AbstractAttribute::initialize(...).
2437 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002438 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00002439
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002440 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002441 if (containsPossiblyEndlessLoop(F))
2442 indicatePessimisticFixpoint();
2443 }
Hideto Ueno11d37102019-07-17 15:15:43 +00002444
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002445 /// See AbstractAttribute::updateImpl(...).
2446 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002447 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002448 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
2449 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
2450 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002451 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002452 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002453 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002454 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
2455 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002456 };
2457
2458 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
2459 return indicatePessimisticFixpoint();
2460
2461 return ChangeStatus::UNCHANGED;
2462 }
2463
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002464 /// See AbstractAttribute::getAsStr()
2465 const std::string getAsStr() const override {
2466 return getAssumed() ? "willreturn" : "may-noreturn";
2467 }
2468};
2469
2470struct AAWillReturnFunction final : AAWillReturnImpl {
2471 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2472
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002473 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002474 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002475};
Hideto Ueno11d37102019-07-17 15:15:43 +00002476
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002477/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002478struct AAWillReturnCallSite final : AAWillReturnImpl {
2479 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2480
2481 /// See AbstractAttribute::initialize(...).
2482 void initialize(Attributor &A) override {
2483 AAWillReturnImpl::initialize(A);
2484 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002485 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002486 indicatePessimisticFixpoint();
2487 }
2488
2489 /// See AbstractAttribute::updateImpl(...).
2490 ChangeStatus updateImpl(Attributor &A) override {
2491 // TODO: Once we have call site specific value information we can provide
2492 // call site specific liveness information and then it makes
2493 // sense to specialize attributes for call sites arguments instead of
2494 // redirecting requests to the callee argument.
2495 Function *F = getAssociatedFunction();
2496 const IRPosition &FnPos = IRPosition::function(*F);
2497 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
2498 return clampStateAndIndicateChange(
2499 getState(),
2500 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
2501 }
2502
2503 /// See AbstractAttribute::trackStatistics()
2504 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
2505};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002506
Pankaj Gode04945c92019-11-22 18:40:47 +05302507/// -------------------AAReachability Attribute--------------------------
2508
2509struct AAReachabilityImpl : AAReachability {
2510 AAReachabilityImpl(const IRPosition &IRP) : AAReachability(IRP) {}
2511
2512 const std::string getAsStr() const override {
2513 // TODO: Return the number of reachable queries.
2514 return "reachable";
2515 }
2516
2517 /// See AbstractAttribute::initialize(...).
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002518 void initialize(Attributor &A) override { indicatePessimisticFixpoint(); }
Pankaj Gode04945c92019-11-22 18:40:47 +05302519
2520 /// See AbstractAttribute::updateImpl(...).
2521 ChangeStatus updateImpl(Attributor &A) override {
2522 return indicatePessimisticFixpoint();
2523 }
2524};
2525
2526struct AAReachabilityFunction final : public AAReachabilityImpl {
2527 AAReachabilityFunction(const IRPosition &IRP) : AAReachabilityImpl(IRP) {}
2528
2529 /// See AbstractAttribute::trackStatistics()
2530 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); }
2531};
2532
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002533/// ------------------------ NoAlias Argument Attribute ------------------------
2534
Johannes Doerfert344d0382019-08-07 22:34:26 +00002535struct AANoAliasImpl : AANoAlias {
Johannes Doerfert32e98a72020-02-14 19:23:21 -06002536 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {
2537 assert(getAssociatedType()->isPointerTy() &&
2538 "Noalias is a pointer attribute");
2539 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002540
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002541 const std::string getAsStr() const override {
2542 return getAssumed() ? "noalias" : "may-alias";
2543 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002544};
2545
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002546/// NoAlias attribute for a floating value.
2547struct AANoAliasFloating final : AANoAliasImpl {
2548 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2549
Hideto Uenocbab3342019-08-29 05:52:00 +00002550 /// See AbstractAttribute::initialize(...).
2551 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002552 AANoAliasImpl::initialize(A);
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002553 Value *Val = &getAssociatedValue();
2554 do {
2555 CastInst *CI = dyn_cast<CastInst>(Val);
2556 if (!CI)
2557 break;
2558 Value *Base = CI->getOperand(0);
2559 if (Base->getNumUses() != 1)
2560 break;
2561 Val = Base;
2562 } while (true);
2563
Johannes Doerfert32e98a72020-02-14 19:23:21 -06002564 if (!Val->getType()->isPointerTy()) {
2565 indicatePessimisticFixpoint();
2566 return;
2567 }
2568
Johannes Doerfert72adda12019-10-10 05:33:21 +00002569 if (isa<AllocaInst>(Val))
2570 indicateOptimisticFixpoint();
Johannes Doerfert24ae77e2020-01-27 22:19:11 -06002571 else if (isa<ConstantPointerNull>(Val) &&
2572 !NullPointerIsDefined(getAnchorScope(),
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002573 Val->getType()->getPointerAddressSpace()))
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002574 indicateOptimisticFixpoint();
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002575 else if (Val != &getAssociatedValue()) {
2576 const auto &ValNoAliasAA =
2577 A.getAAFor<AANoAlias>(*this, IRPosition::value(*Val));
2578 if (ValNoAliasAA.isKnownNoAlias())
2579 indicateOptimisticFixpoint();
2580 }
Hideto Uenocbab3342019-08-29 05:52:00 +00002581 }
2582
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002583 /// See AbstractAttribute::updateImpl(...).
2584 ChangeStatus updateImpl(Attributor &A) override {
2585 // TODO: Implement this.
2586 return indicatePessimisticFixpoint();
2587 }
2588
2589 /// See AbstractAttribute::trackStatistics()
2590 void trackStatistics() const override {
2591 STATS_DECLTRACK_FLOATING_ATTR(noalias)
2592 }
2593};
2594
2595/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00002596struct AANoAliasArgument final
2597 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002598 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
2599 AANoAliasArgument(const IRPosition &IRP) : Base(IRP) {}
2600
Johannes Doerfert2baf0002020-01-12 00:18:07 -06002601 /// See AbstractAttribute::initialize(...).
2602 void initialize(Attributor &A) override {
2603 Base::initialize(A);
2604 // See callsite argument attribute and callee argument attribute.
2605 if (hasAttr({Attribute::ByVal}))
2606 indicateOptimisticFixpoint();
2607 }
2608
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002609 /// See AbstractAttribute::update(...).
2610 ChangeStatus updateImpl(Attributor &A) override {
2611 // We have to make sure no-alias on the argument does not break
2612 // synchronization when this is a callback argument, see also [1] below.
2613 // If synchronization cannot be affected, we delegate to the base updateImpl
2614 // function, otherwise we give up for now.
2615
2616 // If the function is no-sync, no-alias cannot break synchronization.
2617 const auto &NoSyncAA = A.getAAFor<AANoSync>(
2618 *this, IRPosition::function_scope(getIRPosition()));
2619 if (NoSyncAA.isAssumedNoSync())
2620 return Base::updateImpl(A);
2621
2622 // If the argument is read-only, no-alias cannot break synchronization.
2623 const auto &MemBehaviorAA =
2624 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
2625 if (MemBehaviorAA.isAssumedReadOnly())
2626 return Base::updateImpl(A);
2627
2628 // If the argument is never passed through callbacks, no-alias cannot break
2629 // synchronization.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002630 bool AllCallSitesKnown;
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002631 if (A.checkForAllCallSites(
2632 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002633 true, AllCallSitesKnown))
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002634 return Base::updateImpl(A);
2635
2636 // TODO: add no-alias but make sure it doesn't break synchronization by
2637 // introducing fake uses. See:
2638 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
2639 // International Workshop on OpenMP 2018,
2640 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
2641
2642 return indicatePessimisticFixpoint();
2643 }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002644
2645 /// See AbstractAttribute::trackStatistics()
2646 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
2647};
2648
2649struct AANoAliasCallSiteArgument final : AANoAliasImpl {
2650 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2651
Hideto Uenocbab3342019-08-29 05:52:00 +00002652 /// See AbstractAttribute::initialize(...).
2653 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00002654 // See callsite argument attribute and callee argument attribute.
2655 ImmutableCallSite ICS(&getAnchorValue());
2656 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
2657 indicateOptimisticFixpoint();
Johannes Doerfert24ae77e2020-01-27 22:19:11 -06002658 Value &Val = getAssociatedValue();
2659 if (isa<ConstantPointerNull>(Val) &&
2660 !NullPointerIsDefined(getAnchorScope(),
2661 Val.getType()->getPointerAddressSpace()))
2662 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002663 }
2664
Johannes Doerfert53992c72020-01-27 22:24:32 -06002665 /// Determine if the underlying value may alias with the call site argument
2666 /// \p OtherArgNo of \p ICS (= the underlying call site).
2667 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
2668 const AAMemoryBehavior &MemBehaviorAA,
2669 ImmutableCallSite ICS, unsigned OtherArgNo) {
2670 // We do not need to worry about aliasing with the underlying IRP.
2671 if (this->getArgNo() == (int)OtherArgNo)
2672 return false;
2673
2674 // If it is not a pointer or pointer vector we do not alias.
2675 const Value *ArgOp = ICS.getArgOperand(OtherArgNo);
2676 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
2677 return false;
2678
2679 auto &ICSArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
2680 *this, IRPosition::callsite_argument(ICS, OtherArgNo),
2681 /* TrackDependence */ false);
2682
2683 // If the argument is readnone, there is no read-write aliasing.
2684 if (ICSArgMemBehaviorAA.isAssumedReadNone()) {
2685 A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
2686 return false;
2687 }
2688
2689 // If the argument is readonly and the underlying value is readonly, there
2690 // is no read-write aliasing.
2691 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
2692 if (ICSArgMemBehaviorAA.isAssumedReadOnly() && IsReadOnly) {
2693 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
2694 A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
2695 return false;
2696 }
2697
2698 // We have to utilize actual alias analysis queries so we need the object.
2699 if (!AAR)
2700 AAR = A.getInfoCache().getAAResultsForFunction(*getAnchorScope());
2701
2702 // Try to rule it out at the call site.
2703 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
2704 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
2705 "callsite arguments: "
2706 << getAssociatedValue() << " " << *ArgOp << " => "
2707 << (IsAliasing ? "" : "no-") << "alias \n");
2708
2709 return IsAliasing;
2710 }
2711
2712 bool
2713 isKnownNoAliasDueToNoAliasPreservation(Attributor &A, AAResults *&AAR,
2714 const AAMemoryBehavior &MemBehaviorAA,
2715 const AANoAlias &NoAliasAA) {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002716 // We can deduce "noalias" if the following conditions hold.
2717 // (i) Associated value is assumed to be noalias in the definition.
2718 // (ii) Associated value is assumed to be no-capture in all the uses
2719 // possibly executed before this callsite.
2720 // (iii) There is no other pointer argument which could alias with the
2721 // value.
2722
Johannes Doerfert53992c72020-01-27 22:24:32 -06002723 bool AssociatedValueIsNoAliasAtDef = NoAliasAA.isAssumedNoAlias();
2724 if (!AssociatedValueIsNoAliasAtDef) {
2725 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
2726 << " is not no-alias at the definition\n");
2727 return false;
2728 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002729
Johannes Doerfert53992c72020-01-27 22:24:32 -06002730 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
2731 auto &NoCaptureAA =
2732 A.getAAFor<AANoCapture>(*this, VIRP, /* TrackDependence */ false);
2733 // Check whether the value is captured in the scope using AANoCapture.
2734 // FIXME: This is conservative though, it is better to look at CFG and
2735 // check only uses possibly executed before this callsite.
Johannes Doerfert72adda12019-10-10 05:33:21 +00002736 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2737 LLVM_DEBUG(
Johannes Doerfert53992c72020-01-27 22:24:32 -06002738 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
Johannes Doerfert72adda12019-10-10 05:33:21 +00002739 << " cannot be noalias as it is potentially captured\n");
Johannes Doerfert53992c72020-01-27 22:24:32 -06002740 return false;
Johannes Doerfert72adda12019-10-10 05:33:21 +00002741 }
Johannes Doerfert53992c72020-01-27 22:24:32 -06002742 A.recordDependence(NoCaptureAA, *this, DepClassTy::OPTIONAL);
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002743
Johannes Doerfert53992c72020-01-27 22:24:32 -06002744 // Check there is no other pointer argument which could alias with the
2745 // value passed at this call site.
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002746 // TODO: AbstractCallSite
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002747 ImmutableCallSite ICS(&getAnchorValue());
Johannes Doerfert53992c72020-01-27 22:24:32 -06002748 for (unsigned OtherArgNo = 0; OtherArgNo < ICS.getNumArgOperands();
2749 OtherArgNo++)
2750 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, ICS, OtherArgNo))
2751 return false;
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002752
Johannes Doerfert53992c72020-01-27 22:24:32 -06002753 return true;
2754 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002755
Johannes Doerfert53992c72020-01-27 22:24:32 -06002756 /// See AbstractAttribute::updateImpl(...).
2757 ChangeStatus updateImpl(Attributor &A) override {
2758 // If the argument is readnone we are done as there are no accesses via the
2759 // argument.
2760 auto &MemBehaviorAA =
2761 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(),
2762 /* TrackDependence */ false);
2763 if (MemBehaviorAA.isAssumedReadNone()) {
2764 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
2765 return ChangeStatus::UNCHANGED;
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002766 }
2767
Johannes Doerfert53992c72020-01-27 22:24:32 -06002768 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
2769 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, VIRP,
2770 /* TrackDependence */ false);
2771
2772 AAResults *AAR = nullptr;
2773 if (isKnownNoAliasDueToNoAliasPreservation(A, AAR, MemBehaviorAA,
2774 NoAliasAA)) {
2775 LLVM_DEBUG(
2776 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
2777 return ChangeStatus::UNCHANGED;
2778 }
2779
2780 return indicatePessimisticFixpoint();
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002781 }
2782
2783 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002784 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002785};
2786
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002787/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002788struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002789 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002790
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002791 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002792 virtual ChangeStatus updateImpl(Attributor &A) override {
2793
2794 auto CheckReturnValue = [&](Value &RV) -> bool {
2795 if (Constant *C = dyn_cast<Constant>(&RV))
2796 if (C->isNullValue() || isa<UndefValue>(C))
2797 return true;
2798
2799 /// For now, we can only deduce noalias if we have call sites.
2800 /// FIXME: add more support.
2801 ImmutableCallSite ICS(&RV);
2802 if (!ICS)
2803 return false;
2804
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002805 const IRPosition &RVPos = IRPosition::value(RV);
2806 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002807 if (!NoAliasAA.isAssumedNoAlias())
2808 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002809
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002810 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2811 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002812 };
2813
2814 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2815 return indicatePessimisticFixpoint();
2816
2817 return ChangeStatus::UNCHANGED;
2818 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002819
2820 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002821 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002822};
2823
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002824/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002825struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2826 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2827
2828 /// See AbstractAttribute::initialize(...).
2829 void initialize(Attributor &A) override {
2830 AANoAliasImpl::initialize(A);
2831 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002832 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002833 indicatePessimisticFixpoint();
2834 }
2835
2836 /// See AbstractAttribute::updateImpl(...).
2837 ChangeStatus updateImpl(Attributor &A) override {
2838 // TODO: Once we have call site specific value information we can provide
2839 // call site specific liveness information and then it makes
2840 // sense to specialize attributes for call sites arguments instead of
2841 // redirecting requests to the callee argument.
2842 Function *F = getAssociatedFunction();
2843 const IRPosition &FnPos = IRPosition::returned(*F);
2844 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2845 return clampStateAndIndicateChange(
2846 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2847 }
2848
2849 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002850 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002851};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002852
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002853/// -------------------AAIsDead Function Attribute-----------------------
2854
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002855struct AAIsDeadValueImpl : public AAIsDead {
2856 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002857
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002858 /// See AAIsDead::isAssumedDead().
2859 bool isAssumedDead() const override { return getAssumed(); }
2860
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002861 /// See AAIsDead::isKnownDead().
2862 bool isKnownDead() const override { return getKnown(); }
2863
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002864 /// See AAIsDead::isAssumedDead(BasicBlock *).
2865 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2866
2867 /// See AAIsDead::isKnownDead(BasicBlock *).
2868 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2869
2870 /// See AAIsDead::isAssumedDead(Instruction *I).
2871 bool isAssumedDead(const Instruction *I) const override {
2872 return I == getCtxI() && isAssumedDead();
2873 }
2874
2875 /// See AAIsDead::isKnownDead(Instruction *I).
2876 bool isKnownDead(const Instruction *I) const override {
Johannes Doerfert86509e82020-01-12 00:34:38 -06002877 return isAssumedDead(I) && getKnown();
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002878 }
2879
2880 /// See AbstractAttribute::getAsStr().
2881 const std::string getAsStr() const override {
2882 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2883 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002884
Johannes Doerfert86509e82020-01-12 00:34:38 -06002885 /// Check if all uses are assumed dead.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06002886 bool areAllUsesAssumedDead(Attributor &A, Value &V) {
2887 auto UsePred = [&](const Use &U, bool &Follow) { return false; };
2888 // Explicitly set the dependence class to required because we want a long
2889 // chain of N dependent instructions to be considered live as soon as one is
2890 // without going through N update cycles. This is not required for
2891 // correctness.
2892 return A.checkForAllUses(UsePred, *this, V, DepClassTy::REQUIRED);
Johannes Doerfert86509e82020-01-12 00:34:38 -06002893 }
2894
2895 /// Determine if \p I is assumed to be side-effect free.
2896 bool isAssumedSideEffectFree(Attributor &A, Instruction *I) {
2897 if (!I || wouldInstructionBeTriviallyDead(I))
2898 return true;
2899
2900 auto *CB = dyn_cast<CallBase>(I);
2901 if (!CB || isa<IntrinsicInst>(CB))
2902 return false;
2903
2904 const IRPosition &CallIRP = IRPosition::callsite_function(*CB);
2905 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(*this, CallIRP);
2906 if (!NoUnwindAA.isAssumedNoUnwind())
2907 return false;
2908
2909 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, CallIRP);
2910 if (!MemBehaviorAA.isAssumedReadOnly())
2911 return false;
2912
2913 return true;
2914 }
2915};
2916
2917struct AAIsDeadFloating : public AAIsDeadValueImpl {
2918 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2919
2920 /// See AbstractAttribute::initialize(...).
2921 void initialize(Attributor &A) override {
2922 if (isa<UndefValue>(getAssociatedValue())) {
2923 indicatePessimisticFixpoint();
2924 return;
2925 }
2926
2927 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
2928 if (!isAssumedSideEffectFree(A, I))
2929 indicatePessimisticFixpoint();
2930 }
2931
2932 /// See AbstractAttribute::updateImpl(...).
2933 ChangeStatus updateImpl(Attributor &A) override {
2934 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
2935 if (!isAssumedSideEffectFree(A, I))
2936 return indicatePessimisticFixpoint();
2937
Johannes Doerfert23f41f12020-01-12 01:09:22 -06002938 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002939 return indicatePessimisticFixpoint();
2940 return ChangeStatus::UNCHANGED;
2941 }
2942
2943 /// See AbstractAttribute::manifest(...).
2944 ChangeStatus manifest(Attributor &A) override {
2945 Value &V = getAssociatedValue();
Johannes Doerfert86509e82020-01-12 00:34:38 -06002946 if (auto *I = dyn_cast<Instruction>(&V)) {
2947 // If we get here we basically know the users are all dead. We check if
2948 // isAssumedSideEffectFree returns true here again because it might not be
2949 // the case and only the users are dead but the instruction (=call) is
2950 // still needed.
2951 if (isAssumedSideEffectFree(A, I) && !isa<InvokeInst>(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002952 A.deleteAfterManifest(*I);
2953 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002954 }
Johannes Doerfert86509e82020-01-12 00:34:38 -06002955 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002956 if (V.use_empty())
2957 return ChangeStatus::UNCHANGED;
2958
Johannes Doerfertb2c76002020-01-23 17:12:56 -06002959 bool UsedAssumedInformation = false;
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06002960 Optional<Constant *> C =
Johannes Doerfertb2c76002020-01-23 17:12:56 -06002961 getAssumedConstant(A, V, *this, UsedAssumedInformation);
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06002962 if (C.hasValue() && C.getValue())
Johannes Doerfertb2c76002020-01-23 17:12:56 -06002963 return ChangeStatus::UNCHANGED;
2964
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002965 UndefValue &UV = *UndefValue::get(V.getType());
Hideto Ueno34fe8d02019-12-30 17:08:48 +09002966 bool AnyChange = A.changeValueAfterManifest(V, UV);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002967 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2968 }
2969
2970 /// See AbstractAttribute::trackStatistics()
2971 void trackStatistics() const override {
2972 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2973 }
2974};
2975
2976struct AAIsDeadArgument : public AAIsDeadFloating {
2977 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2978
2979 /// See AbstractAttribute::initialize(...).
2980 void initialize(Attributor &A) override {
2981 if (!getAssociatedFunction()->hasExactDefinition())
2982 indicatePessimisticFixpoint();
2983 }
2984
Johannes Doerfert75133632019-10-10 01:39:16 -05002985 /// See AbstractAttribute::manifest(...).
2986 ChangeStatus manifest(Attributor &A) override {
2987 ChangeStatus Changed = AAIsDeadFloating::manifest(A);
2988 Argument &Arg = *getAssociatedArgument();
Johannes Doerfert89c2e732019-10-30 17:20:20 -05002989 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
Johannes Doerfert75133632019-10-10 01:39:16 -05002990 if (A.registerFunctionSignatureRewrite(
2991 Arg, /* ReplacementTypes */ {},
2992 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{},
2993 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{}))
2994 return ChangeStatus::CHANGED;
2995 return Changed;
2996 }
2997
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002998 /// See AbstractAttribute::trackStatistics()
2999 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
3000};
3001
3002struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
3003 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
3004
3005 /// See AbstractAttribute::initialize(...).
3006 void initialize(Attributor &A) override {
3007 if (isa<UndefValue>(getAssociatedValue()))
3008 indicatePessimisticFixpoint();
3009 }
3010
3011 /// See AbstractAttribute::updateImpl(...).
3012 ChangeStatus updateImpl(Attributor &A) override {
3013 // TODO: Once we have call site specific value information we can provide
3014 // call site specific liveness information and then it makes
3015 // sense to specialize attributes for call sites arguments instead of
3016 // redirecting requests to the callee argument.
3017 Argument *Arg = getAssociatedArgument();
3018 if (!Arg)
3019 return indicatePessimisticFixpoint();
3020 const IRPosition &ArgPos = IRPosition::argument(*Arg);
3021 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
3022 return clampStateAndIndicateChange(
3023 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
3024 }
3025
3026 /// See AbstractAttribute::manifest(...).
3027 ChangeStatus manifest(Attributor &A) override {
3028 CallBase &CB = cast<CallBase>(getAnchorValue());
3029 Use &U = CB.getArgOperandUse(getArgNo());
3030 assert(!isa<UndefValue>(U.get()) &&
3031 "Expected undef values to be filtered out!");
3032 UndefValue &UV = *UndefValue::get(U->getType());
3033 if (A.changeUseAfterManifest(U, UV))
3034 return ChangeStatus::CHANGED;
3035 return ChangeStatus::UNCHANGED;
3036 }
3037
3038 /// See AbstractAttribute::trackStatistics()
3039 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
3040};
3041
Johannes Doerfert86509e82020-01-12 00:34:38 -06003042struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
3043 AAIsDeadCallSiteReturned(const IRPosition &IRP)
3044 : AAIsDeadFloating(IRP), IsAssumedSideEffectFree(true) {}
3045
3046 /// See AAIsDead::isAssumedDead().
3047 bool isAssumedDead() const override {
3048 return AAIsDeadFloating::isAssumedDead() && IsAssumedSideEffectFree;
3049 }
3050
Johannes Doerfert86509e82020-01-12 00:34:38 -06003051 /// See AbstractAttribute::initialize(...).
3052 void initialize(Attributor &A) override {
3053 if (isa<UndefValue>(getAssociatedValue())) {
3054 indicatePessimisticFixpoint();
3055 return;
3056 }
3057
3058 // We track this separately as a secondary state.
3059 IsAssumedSideEffectFree = isAssumedSideEffectFree(A, getCtxI());
3060 }
3061
3062 /// See AbstractAttribute::updateImpl(...).
3063 ChangeStatus updateImpl(Attributor &A) override {
3064 ChangeStatus Changed = ChangeStatus::UNCHANGED;
3065 if (IsAssumedSideEffectFree && !isAssumedSideEffectFree(A, getCtxI())) {
3066 IsAssumedSideEffectFree = false;
3067 Changed = ChangeStatus::CHANGED;
3068 }
3069
Johannes Doerfert23f41f12020-01-12 01:09:22 -06003070 if (!areAllUsesAssumedDead(A, getAssociatedValue()))
Johannes Doerfert86509e82020-01-12 00:34:38 -06003071 return indicatePessimisticFixpoint();
3072 return Changed;
3073 }
3074
3075 /// See AbstractAttribute::manifest(...).
3076 ChangeStatus manifest(Attributor &A) override {
3077 if (auto *CI = dyn_cast<CallInst>(&getAssociatedValue()))
3078 if (CI->isMustTailCall())
3079 return ChangeStatus::UNCHANGED;
3080 return AAIsDeadFloating::manifest(A);
3081 }
3082
3083 /// See AbstractAttribute::trackStatistics()
3084 void trackStatistics() const override {
3085 if (IsAssumedSideEffectFree)
3086 STATS_DECLTRACK_CSRET_ATTR(IsDead)
3087 else
3088 STATS_DECLTRACK_CSRET_ATTR(UnusedResult)
3089 }
3090
3091 /// See AbstractAttribute::getAsStr().
3092 const std::string getAsStr() const override {
3093 return isAssumedDead()
3094 ? "assumed-dead"
3095 : (getAssumed() ? "assumed-dead-users" : "assumed-live");
3096 }
3097
3098private:
3099 bool IsAssumedSideEffectFree;
3100};
3101
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003102struct AAIsDeadReturned : public AAIsDeadValueImpl {
3103 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
3104
3105 /// See AbstractAttribute::updateImpl(...).
3106 ChangeStatus updateImpl(Attributor &A) override {
3107
Johannes Doerfertb70297a2020-02-14 10:34:31 -06003108 A.checkForAllInstructions([](Instruction &) { return true; }, *this,
3109 {Instruction::Ret});
3110
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003111 auto PredForCallSite = [&](AbstractCallSite ACS) {
Johannes Doerfert23f41f12020-01-12 01:09:22 -06003112 if (ACS.isCallbackCall() || !ACS.getInstruction())
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003113 return false;
Johannes Doerfert23f41f12020-01-12 01:09:22 -06003114 return areAllUsesAssumedDead(A, *ACS.getInstruction());
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003115 };
3116
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06003117 bool AllCallSitesKnown;
3118 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
3119 AllCallSitesKnown))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003120 return indicatePessimisticFixpoint();
3121
3122 return ChangeStatus::UNCHANGED;
3123 }
3124
3125 /// See AbstractAttribute::manifest(...).
3126 ChangeStatus manifest(Attributor &A) override {
3127 // TODO: Rewrite the signature to return void?
3128 bool AnyChange = false;
3129 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
3130 auto RetInstPred = [&](Instruction &I) {
3131 ReturnInst &RI = cast<ReturnInst>(I);
Johannes Doerfertb2c76002020-01-23 17:12:56 -06003132 if (auto *CI = dyn_cast<CallInst>(RI.getReturnValue()))
3133 if (CI->isMustTailCall())
3134 return true;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003135 if (!isa<UndefValue>(RI.getReturnValue()))
3136 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
3137 return true;
3138 };
3139 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
3140 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
3141 }
3142
3143 /// See AbstractAttribute::trackStatistics()
3144 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
3145};
3146
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003147struct AAIsDeadFunction : public AAIsDead {
3148 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
3149
3150 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003151 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003152 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003153 if (F && !F->isDeclaration()) {
3154 ToBeExploredFrom.insert(&F->getEntryBlock().front());
3155 assumeLive(A, F->getEntryBlock());
3156 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003157 }
3158
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003159 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003160 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003161 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003162 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003163 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
3164 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003165 }
3166
3167 /// See AbstractAttribute::manifest(...).
3168 ChangeStatus manifest(Attributor &A) override {
3169 assert(getState().isValidState() &&
3170 "Attempted to manifest an invalid state!");
3171
3172 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003173 Function &F = *getAssociatedFunction();
3174
3175 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003176 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003177 return ChangeStatus::CHANGED;
3178 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00003179
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003180 // Flag to determine if we can change an invoke to a call assuming the
3181 // callee is nounwind. This is not possible if the personality of the
3182 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00003183 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003184
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003185 KnownDeadEnds.set_union(ToBeExploredFrom);
3186 for (const Instruction *DeadEndI : KnownDeadEnds) {
3187 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003188 if (!CB)
3189 continue;
3190 const auto &NoReturnAA =
3191 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05003192 bool MayReturn = !NoReturnAA.isAssumedNoReturn();
3193 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003194 continue;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003195
Johannes Doerferta4088c72020-01-07 16:01:57 -06003196 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
3197 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
3198 else
3199 A.changeToUnreachableAfterManifest(
3200 const_cast<Instruction *>(DeadEndI->getNextNode()));
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003201 HasChanged = ChangeStatus::CHANGED;
3202 }
3203
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003204 for (BasicBlock &BB : F)
3205 if (!AssumedLiveBlocks.count(&BB))
3206 A.deleteAfterManifest(BB);
3207
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003208 return HasChanged;
3209 }
3210
3211 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003212 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003213
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003214 /// See AbstractAttribute::trackStatistics()
3215 void trackStatistics() const override {}
3216
3217 /// Returns true if the function is assumed dead.
3218 bool isAssumedDead() const override { return false; }
3219
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06003220 /// See AAIsDead::isKnownDead().
3221 bool isKnownDead() const override { return false; }
3222
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003223 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003224 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003225 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003226 "BB must be in the same anchor scope function.");
3227
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003228 if (!getAssumed())
3229 return false;
3230 return !AssumedLiveBlocks.count(BB);
3231 }
3232
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003233 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003234 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003235 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003236 }
3237
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003238 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003239 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003240 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003241 "Instruction must be in the same anchor scope function.");
3242
Stefan Stipanovic7849e412019-08-03 15:27:41 +00003243 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003244 return false;
3245
3246 // If it is not in AssumedLiveBlocks then it for sure dead.
3247 // Otherwise, it can still be after noreturn call in a live block.
3248 if (!AssumedLiveBlocks.count(I->getParent()))
3249 return true;
3250
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003251 // If it is not after a liveness barrier it is live.
3252 const Instruction *PrevI = I->getPrevNode();
3253 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003254 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003255 return true;
3256 PrevI = PrevI->getPrevNode();
3257 }
3258 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003259 }
3260
3261 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003262 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003263 return getKnown() && isAssumedDead(I);
3264 }
3265
Johannes Doerfert924d2132019-08-05 21:34:45 +00003266 /// Determine if \p F might catch asynchronous exceptions.
3267 static bool mayCatchAsynchronousExceptions(const Function &F) {
3268 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
3269 }
3270
Johannes Doerfert2f622062019-09-04 16:35:20 +00003271 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
3272 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003273 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00003274 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003275 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003276
3277 // We assume that all of BB is (probably) live now and if there are calls to
3278 // internal functions we will assume that those are now live as well. This
3279 // is a performance optimization for blocks with calls to a lot of internal
3280 // functions. It can however cause dead functions to be treated as live.
3281 for (const Instruction &I : BB)
3282 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
3283 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00003284 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00003285 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003286 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003287 }
3288
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003289 /// Collection of instructions that need to be explored again, e.g., we
3290 /// did assume they do not transfer control to (one of their) successors.
3291 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003292
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003293 /// Collection of instructions that are known to not transfer control.
3294 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
3295
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003296 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00003297 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003298};
3299
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003300static bool
3301identifyAliveSuccessors(Attributor &A, const CallBase &CB,
3302 AbstractAttribute &AA,
3303 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3304 const IRPosition &IPos = IRPosition::callsite_function(CB);
3305
3306 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
3307 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003308 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003309 if (CB.isTerminator())
3310 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
3311 else
3312 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003313 return false;
3314}
3315
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003316static bool
3317identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
3318 AbstractAttribute &AA,
3319 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3320 bool UsedAssumedInformation =
3321 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00003322
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003323 // First, determine if we can change an invoke to a call assuming the
3324 // callee is nounwind. This is not possible if the personality of the
3325 // function allows to catch asynchronous exceptions.
3326 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
3327 AliveSuccessors.push_back(&II.getUnwindDest()->front());
3328 } else {
3329 const IRPosition &IPos = IRPosition::callsite_function(II);
3330 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003331 if (AANoUnw.isAssumedNoUnwind()) {
3332 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
3333 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003334 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003335 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003336 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003337 return UsedAssumedInformation;
3338}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003339
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003340static bool
3341identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
3342 AbstractAttribute &AA,
3343 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3344 bool UsedAssumedInformation = false;
3345 if (BI.getNumSuccessors() == 1) {
3346 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3347 } else {
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06003348 Optional<ConstantInt *> CI = getAssumedConstantInt(
3349 A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003350 if (!CI.hasValue()) {
3351 // No value yet, assume both edges are dead.
3352 } else if (CI.getValue()) {
3353 const BasicBlock *SuccBB =
3354 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
3355 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003356 } else {
3357 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3358 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003359 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003360 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003361 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003362 return UsedAssumedInformation;
3363}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003364
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003365static bool
3366identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
3367 AbstractAttribute &AA,
3368 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003369 bool UsedAssumedInformation = false;
3370 Optional<ConstantInt *> CI =
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06003371 getAssumedConstantInt(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003372 if (!CI.hasValue()) {
3373 // No value yet, assume all edges are dead.
3374 } else if (CI.getValue()) {
3375 for (auto &CaseIt : SI.cases()) {
3376 if (CaseIt.getCaseValue() == CI.getValue()) {
3377 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003378 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003379 }
3380 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05003381 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003382 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003383 } else {
3384 for (const BasicBlock *SuccBB : successors(SI.getParent()))
3385 AliveSuccessors.push_back(&SuccBB->front());
3386 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003387 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003388}
3389
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003390ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003391 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003392
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003393 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
3394 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003395 << ToBeExploredFrom.size() << " exploration points and "
3396 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003397
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003398 // Copy and clear the list of instructions we need to explore from. It is
3399 // refilled with instructions the next update has to look at.
3400 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
3401 ToBeExploredFrom.end());
3402 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003403
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003404 SmallVector<const Instruction *, 8> AliveSuccessors;
3405 while (!Worklist.empty()) {
3406 const Instruction *I = Worklist.pop_back_val();
3407 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003408
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003409 AliveSuccessors.clear();
3410
3411 bool UsedAssumedInformation = false;
3412 switch (I->getOpcode()) {
3413 // TODO: look for (assumed) UB to backwards propagate "deadness".
3414 default:
3415 if (I->isTerminator()) {
3416 for (const BasicBlock *SuccBB : successors(I->getParent()))
3417 AliveSuccessors.push_back(&SuccBB->front());
3418 } else {
3419 AliveSuccessors.push_back(I->getNextNode());
3420 }
3421 break;
3422 case Instruction::Call:
3423 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
3424 *this, AliveSuccessors);
3425 break;
3426 case Instruction::Invoke:
3427 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
3428 *this, AliveSuccessors);
3429 break;
3430 case Instruction::Br:
3431 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
3432 *this, AliveSuccessors);
3433 break;
3434 case Instruction::Switch:
3435 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
3436 *this, AliveSuccessors);
3437 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00003438 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003439
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003440 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003441 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003442 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003443 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003444 if (AliveSuccessors.empty() ||
3445 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
3446 KnownDeadEnds.insert(I);
3447 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003448
3449 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
3450 << AliveSuccessors.size() << " UsedAssumedInformation: "
3451 << UsedAssumedInformation << "\n");
3452
3453 for (const Instruction *AliveSuccessor : AliveSuccessors) {
3454 if (!I->isTerminator()) {
3455 assert(AliveSuccessors.size() == 1 &&
3456 "Non-terminator expected to have a single successor!");
3457 Worklist.push_back(AliveSuccessor);
3458 } else {
3459 if (assumeLive(A, *AliveSuccessor->getParent()))
3460 Worklist.push_back(AliveSuccessor);
3461 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00003462 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003463 }
3464
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003465 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003466
Johannes Doerfertd6207812019-08-07 22:32:38 +00003467 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003468 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003469 // "invalid" and all queries to be answered conservatively without lookups.
3470 // To be in this state we have to (1) finished the exploration and (3) not
3471 // discovered any non-trivial dead end and (2) not ruled unreachable code
3472 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003473 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003474 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
3475 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
3476 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
3477 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003478 return indicatePessimisticFixpoint();
3479 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003480}
3481
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003482/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003483struct AAIsDeadCallSite final : AAIsDeadFunction {
3484 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003485
3486 /// See AbstractAttribute::initialize(...).
3487 void initialize(Attributor &A) override {
3488 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003489 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003490 // sense to specialize attributes for call sites instead of
3491 // redirecting requests to the callee.
3492 llvm_unreachable("Abstract attributes for liveness are not "
3493 "supported for call sites yet!");
3494 }
3495
3496 /// See AbstractAttribute::updateImpl(...).
3497 ChangeStatus updateImpl(Attributor &A) override {
3498 return indicatePessimisticFixpoint();
3499 }
3500
3501 /// See AbstractAttribute::trackStatistics()
3502 void trackStatistics() const override {}
3503};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003504
Hideto Ueno19c07af2019-07-23 08:16:17 +00003505/// -------------------- Dereferenceable Argument Attribute --------------------
3506
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003507template <>
3508ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
3509 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05003510 ChangeStatus CS0 =
3511 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
3512 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003513 return CS0 | CS1;
3514}
3515
Hideto Ueno70576ca2019-08-22 14:18:29 +00003516struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003517 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003518 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00003519
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003520 void initialize(Attributor &A) override {
3521 SmallVector<Attribute, 4> Attrs;
3522 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
3523 Attrs);
3524 for (const Attribute &Attr : Attrs)
3525 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
3526
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003527 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition(),
3528 /* TrackDependence */ false);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003529
3530 const IRPosition &IRP = this->getIRPosition();
3531 bool IsFnInterface = IRP.isFnInterfaceKind();
3532 const Function *FnScope = IRP.getAnchorScope();
3533 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
3534 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003535 }
3536
Hideto Ueno19c07af2019-07-23 08:16:17 +00003537 /// See AbstractAttribute::getState()
3538 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00003539 StateType &getState() override { return *this; }
3540 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003541 /// }
3542
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003543 /// Helper function for collecting accessed bytes in must-be-executed-context
3544 void addAccessedBytesForUse(Attributor &A, const Use *U,
3545 const Instruction *I) {
3546 const Value *UseV = U->get();
3547 if (!UseV->getType()->isPointerTy())
3548 return;
3549
3550 Type *PtrTy = UseV->getType();
3551 const DataLayout &DL = A.getDataLayout();
3552 int64_t Offset;
3553 if (const Value *Base = getBasePointerOfAccessPointerOperand(
3554 I, Offset, DL, /*AllowNonInbounds*/ true)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09003555 if (Base == &getAssociatedValue() &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06003556 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003557 uint64_t Size = DL.getTypeStoreSize(PtrTy->getPointerElementType());
3558 addAccessedBytes(Offset, Size);
3559 }
3560 }
3561 return;
3562 }
3563
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003564 /// See AAFromMustBeExecutedContext
3565 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3566 bool IsNonNull = false;
3567 bool TrackUse = false;
3568 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
3569 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003570
3571 addAccessedBytesForUse(A, U, I);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003572 takeKnownDerefBytesMaximum(DerefBytes);
3573 return TrackUse;
3574 }
3575
Hideto Uenodfedae52019-11-29 06:45:07 +00003576 /// See AbstractAttribute::manifest(...).
3577 ChangeStatus manifest(Attributor &A) override {
3578 ChangeStatus Change = AADereferenceable::manifest(A);
3579 if (isAssumedNonNull() && hasAttr(Attribute::DereferenceableOrNull)) {
3580 removeAttrs({Attribute::DereferenceableOrNull});
3581 return ChangeStatus::CHANGED;
3582 }
3583 return Change;
3584 }
3585
Johannes Doerferteccdf082019-08-05 23:35:12 +00003586 void getDeducedAttributes(LLVMContext &Ctx,
3587 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00003588 // TODO: Add *_globally support
3589 if (isAssumedNonNull())
3590 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
3591 Ctx, getAssumedDereferenceableBytes()));
3592 else
3593 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
3594 Ctx, getAssumedDereferenceableBytes()));
3595 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003596
3597 /// See AbstractAttribute::getAsStr().
3598 const std::string getAsStr() const override {
3599 if (!getAssumedDereferenceableBytes())
3600 return "unknown-dereferenceable";
3601 return std::string("dereferenceable") +
3602 (isAssumedNonNull() ? "" : "_or_null") +
3603 (isAssumedGlobal() ? "_globally" : "") + "<" +
3604 std::to_string(getKnownDereferenceableBytes()) + "-" +
3605 std::to_string(getAssumedDereferenceableBytes()) + ">";
3606 }
3607};
3608
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003609/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003610struct AADereferenceableFloating
3611 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
3612 using Base =
3613 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
3614 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00003615
3616 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003617 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003618 ChangeStatus Change = Base::updateImpl(A);
3619
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003620 const DataLayout &DL = A.getDataLayout();
3621
3622 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
3623 unsigned IdxWidth =
3624 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
3625 APInt Offset(IdxWidth, 0);
3626 const Value *Base =
3627 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
3628
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003629 const auto &AA =
3630 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003631 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003632 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003633 // Use IR information if we did not strip anything.
3634 // TODO: track globally.
3635 bool CanBeNull;
3636 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
3637 T.GlobalState.indicatePessimisticFixpoint();
3638 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003639 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003640 DerefBytes = DS.DerefBytesState.getAssumed();
3641 T.GlobalState &= DS.GlobalState;
3642 }
3643
Hideto Ueno188f9a32020-01-15 15:25:52 +09003644 // TODO: Use `AAConstantRange` to infer dereferenceable bytes.
3645
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003646 // For now we do not try to "increase" dereferenceability due to negative
3647 // indices as we first have to come up with code to deal with loops and
3648 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00003649 int64_t OffsetSExt = Offset.getSExtValue();
3650 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00003651 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003652
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003653 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00003654 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003655
Johannes Doerfert785fad32019-08-23 17:29:23 +00003656 if (this == &AA) {
3657 if (!Stripped) {
3658 // If nothing was stripped IR information is all we got.
3659 T.takeKnownDerefBytesMaximum(
3660 std::max(int64_t(0), DerefBytes - OffsetSExt));
3661 T.indicatePessimisticFixpoint();
3662 } else if (OffsetSExt > 0) {
3663 // If something was stripped but there is circular reasoning we look
3664 // for the offset. If it is positive we basically decrease the
3665 // dereferenceable bytes in a circluar loop now, which will simply
3666 // drive them down to the known value in a very slow way which we
3667 // can accelerate.
3668 T.indicatePessimisticFixpoint();
3669 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003670 }
3671
3672 return T.isValidState();
3673 };
3674
3675 DerefState T;
3676 if (!genericValueTraversal<AADereferenceable, DerefState>(
3677 A, getIRPosition(), *this, T, VisitValueCB))
3678 return indicatePessimisticFixpoint();
3679
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003680 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003681 }
3682
3683 /// See AbstractAttribute::trackStatistics()
3684 void trackStatistics() const override {
3685 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
3686 }
3687};
3688
3689/// Dereferenceable attribute for a return value.
3690struct AADereferenceableReturned final
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003691 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003692 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003693 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>(
3694 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003695
3696 /// See AbstractAttribute::trackStatistics()
3697 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003698 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003699 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003700};
3701
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003702/// Dereferenceable attribute for an argument
3703struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003704 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003705 AADereferenceable, AADereferenceableImpl> {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003706 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003707 AADereferenceable, AADereferenceableImpl>;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003708 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003709
3710 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003711 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00003712 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
3713 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003714};
3715
Hideto Ueno19c07af2019-07-23 08:16:17 +00003716/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003717struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003718 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003719 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003720
3721 /// See AbstractAttribute::trackStatistics()
3722 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003723 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003724 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003725};
3726
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003727/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003728struct AADereferenceableCallSiteReturned final
3729 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3730 AADereferenceable, AADereferenceableImpl> {
3731 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3732 AADereferenceable, AADereferenceableImpl>;
3733 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003734
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003735 /// See AbstractAttribute::trackStatistics()
3736 void trackStatistics() const override {
3737 STATS_DECLTRACK_CS_ATTR(dereferenceable);
3738 }
3739};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003740
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003741// ------------------------ Align Argument Attribute ------------------------
3742
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003743static unsigned int getKnownAlignForUse(Attributor &A,
3744 AbstractAttribute &QueryingAA,
3745 Value &AssociatedValue, const Use *U,
3746 const Instruction *I, bool &TrackUse) {
Hideto Ueno78a75022019-11-26 07:51:59 +00003747 // We need to follow common pointer manipulation uses to the accesses they
3748 // feed into.
3749 if (isa<CastInst>(I)) {
Johannes Doerfertc90681b2020-01-02 16:41:17 -06003750 // Follow all but ptr2int casts.
3751 TrackUse = !isa<PtrToIntInst>(I);
Hideto Ueno78a75022019-11-26 07:51:59 +00003752 return 0;
3753 }
3754 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
3755 if (GEP->hasAllConstantIndices()) {
3756 TrackUse = true;
3757 return 0;
3758 }
3759 }
3760
3761 unsigned Alignment = 0;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003762 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
3763 if (ICS.isBundleOperand(U) || ICS.isCallee(U))
3764 return 0;
3765
3766 unsigned ArgNo = ICS.getArgumentNo(U);
3767 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
3768 // As long as we only use known information there is no need to track
3769 // dependences here.
3770 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP,
3771 /* TrackDependence */ false);
Hideto Ueno78a75022019-11-26 07:51:59 +00003772 Alignment = AlignAA.getKnownAlign();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003773 }
3774
Hideto Ueno78a75022019-11-26 07:51:59 +00003775 const Value *UseV = U->get();
Johannes Doerfert30ae8592020-01-10 12:13:10 -06003776 if (auto *SI = dyn_cast<StoreInst>(I)) {
3777 if (SI->getPointerOperand() == UseV)
3778 Alignment = SI->getAlignment();
3779 } else if (auto *LI = dyn_cast<LoadInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003780 Alignment = LI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003781
Hideto Ueno78a75022019-11-26 07:51:59 +00003782 if (Alignment <= 1)
3783 return 0;
3784
3785 auto &DL = A.getDataLayout();
3786 int64_t Offset;
3787
3788 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
3789 if (Base == &AssociatedValue) {
3790 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
3791 // So we can say that the maximum power of two which is a divisor of
3792 // gcd(Offset, Alignment) is an alignment.
3793
3794 uint32_t gcd =
3795 greatestCommonDivisor(uint32_t(abs((int32_t)Offset)), Alignment);
3796 Alignment = llvm::PowerOf2Floor(gcd);
3797 }
3798 }
3799
3800 return Alignment;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003801}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003802struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003803 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003804
Johannes Doerfert234eda52019-08-16 19:51:23 +00003805 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003806 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003807 SmallVector<Attribute, 4> Attrs;
3808 getAttrs({Attribute::Alignment}, Attrs);
3809 for (const Attribute &Attr : Attrs)
3810 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003811
3812 if (getIRPosition().isFnInterfaceKind() &&
3813 (!getAssociatedFunction() ||
3814 !getAssociatedFunction()->hasExactDefinition()))
3815 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003816 }
3817
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003818 /// See AbstractAttribute::manifest(...).
3819 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003820 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003821
3822 // Check for users that allow alignment annotations.
Johannes Doerferta801ee82020-02-19 16:52:16 -06003823 Value &AssociatedValue = getAssociatedValue();
3824 for (const Use &U : AssociatedValue.uses()) {
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003825 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
Johannes Doerferta801ee82020-02-19 16:52:16 -06003826 if (SI->getPointerOperand() == &AssociatedValue)
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003827 if (SI->getAlignment() < getAssumedAlign()) {
3828 STATS_DECLTRACK(AAAlign, Store,
James Hendersond68904f2020-01-06 10:15:44 +00003829 "Number of times alignment added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00003830 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert30179d72020-01-12 00:25:45 -06003831 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003832 }
3833 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
Johannes Doerferta801ee82020-02-19 16:52:16 -06003834 if (LI->getPointerOperand() == &AssociatedValue)
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003835 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00003836 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003837 STATS_DECLTRACK(AAAlign, Load,
James Hendersond68904f2020-01-06 10:15:44 +00003838 "Number of times alignment added to a load");
Johannes Doerfert30179d72020-01-12 00:25:45 -06003839 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003840 }
3841 }
3842 }
3843
Johannes Doerfert30179d72020-01-12 00:25:45 -06003844 ChangeStatus Changed = AAAlign::manifest(A);
3845
3846 MaybeAlign InheritAlign =
3847 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3848 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3849 return LoadStoreChanged;
3850 return Changed | LoadStoreChanged;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003851 }
3852
Johannes Doerfert81df4522019-08-30 15:22:28 +00003853 // TODO: Provide a helper to determine the implied ABI alignment and check in
3854 // the existing manifest method and a new one for AAAlignImpl that value
3855 // to avoid making the alignment explicit if it did not improve.
3856
3857 /// See AbstractAttribute::getDeducedAttributes
3858 virtual void
3859 getDeducedAttributes(LLVMContext &Ctx,
3860 SmallVectorImpl<Attribute> &Attrs) const override {
3861 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00003862 Attrs.emplace_back(
3863 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00003864 }
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003865 /// See AAFromMustBeExecutedContext
3866 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3867 bool TrackUse = false;
3868
Hideto Ueno4ecf2552019-12-12 13:42:40 +00003869 unsigned int KnownAlign =
3870 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003871 takeKnownMaximum(KnownAlign);
3872
3873 return TrackUse;
3874 }
Johannes Doerfert81df4522019-08-30 15:22:28 +00003875
3876 /// See AbstractAttribute::getAsStr().
3877 const std::string getAsStr() const override {
3878 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
3879 "-" + std::to_string(getAssumedAlign()) + ">")
3880 : "unknown-align";
3881 }
3882};
3883
3884/// Align attribute for a floating value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003885struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
3886 using Base = AAFromMustBeExecutedContext<AAAlign, AAAlignImpl>;
3887 AAAlignFloating(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert81df4522019-08-30 15:22:28 +00003888
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003889 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00003890 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003891 Base::updateImpl(A);
3892
Johannes Doerfert234eda52019-08-16 19:51:23 +00003893 const DataLayout &DL = A.getDataLayout();
3894
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003895 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3896 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003897 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3898 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003899 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003900 const MaybeAlign PA = V.getPointerAlignment(DL);
3901 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003902 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003903 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003904 // Use abstract attribute information.
3905 const AAAlign::StateType &DS =
3906 static_cast<const AAAlign::StateType &>(AA.getState());
3907 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003908 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003909 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003910 };
3911
3912 StateType T;
3913 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3914 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003915 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003916
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003917 // TODO: If we know we visited all incoming values, thus no are assumed
3918 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003919 return clampStateAndIndicateChange(getState(), T);
3920 }
3921
3922 /// See AbstractAttribute::trackStatistics()
3923 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3924};
3925
3926/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003927struct AAAlignReturned final
3928 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003929 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003930 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003931
3932 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003933 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003934};
3935
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003936/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003937struct AAAlignArgument final
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003938 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3939 AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003940 AAAlignArgument(const IRPosition &IRP)
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003941 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3942 AAAlignImpl>(
3943 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003944
3945 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003946 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003947};
3948
Johannes Doerfert234eda52019-08-16 19:51:23 +00003949struct AAAlignCallSiteArgument final : AAAlignFloating {
3950 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003951
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003952 /// See AbstractAttribute::manifest(...).
3953 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003954 ChangeStatus Changed = AAAlignImpl::manifest(A);
3955 MaybeAlign InheritAlign =
3956 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3957 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3958 Changed = ChangeStatus::UNCHANGED;
3959 return Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003960 }
3961
Johannes Doerfertdada8132019-12-31 01:27:50 -06003962 /// See AbstractAttribute::updateImpl(Attributor &A).
3963 ChangeStatus updateImpl(Attributor &A) override {
3964 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
3965 if (Argument *Arg = getAssociatedArgument()) {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003966 // We only take known information from the argument
3967 // so we do not need to track a dependence.
Johannes Doerfertdada8132019-12-31 01:27:50 -06003968 const auto &ArgAlignAA = A.getAAFor<AAAlign>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003969 *this, IRPosition::argument(*Arg), /* TrackDependence */ false);
Johannes Doerfertdada8132019-12-31 01:27:50 -06003970 takeKnownMaximum(ArgAlignAA.getKnownAlign());
3971 }
3972 return Changed;
3973 }
3974
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003975 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003976 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003977};
3978
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003979/// Align attribute deduction for a call site return value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003980struct AAAlignCallSiteReturned final
3981 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3982 AAAlignImpl> {
3983 using Base =
3984 AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3985 AAAlignImpl>;
3986 AAAlignCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003987
3988 /// See AbstractAttribute::initialize(...).
3989 void initialize(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003990 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003991 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003992 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003993 indicatePessimisticFixpoint();
3994 }
3995
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003996 /// See AbstractAttribute::trackStatistics()
3997 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3998};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003999
Johannes Doerferte83f3032019-08-05 23:22:05 +00004000/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00004001struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004002 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00004003
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00004004 /// See AbstractAttribute::initialize(...).
4005 void initialize(Attributor &A) override {
4006 AANoReturn::initialize(A);
4007 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05004008 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00004009 indicatePessimisticFixpoint();
4010 }
4011
Johannes Doerferte83f3032019-08-05 23:22:05 +00004012 /// See AbstractAttribute::getAsStr().
4013 const std::string getAsStr() const override {
4014 return getAssumed() ? "noreturn" : "may-return";
4015 }
4016
Johannes Doerferte83f3032019-08-05 23:22:05 +00004017 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00004018 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004019 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004020 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00004021 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00004022 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00004023 return ChangeStatus::UNCHANGED;
4024 }
4025};
4026
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004027struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00004028 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00004029
4030 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00004031 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00004032};
4033
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00004034/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00004035struct AANoReturnCallSite final : AANoReturnImpl {
4036 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
4037
Johannes Doerfert3fac6682019-08-30 15:24:52 +00004038 /// See AbstractAttribute::updateImpl(...).
4039 ChangeStatus updateImpl(Attributor &A) override {
4040 // TODO: Once we have call site specific value information we can provide
4041 // call site specific liveness information and then it makes
4042 // sense to specialize attributes for call sites arguments instead of
4043 // redirecting requests to the callee argument.
4044 Function *F = getAssociatedFunction();
4045 const IRPosition &FnPos = IRPosition::function(*F);
4046 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
4047 return clampStateAndIndicateChange(
4048 getState(),
4049 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
4050 }
4051
4052 /// See AbstractAttribute::trackStatistics()
4053 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
4054};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00004055
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004056/// ----------------------- Variable Capturing ---------------------------------
4057
4058/// A class to hold the state of for no-capture attributes.
4059struct AANoCaptureImpl : public AANoCapture {
4060 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
4061
4062 /// See AbstractAttribute::initialize(...).
4063 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05004064 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
4065 indicateOptimisticFixpoint();
4066 return;
4067 }
4068 Function *AnchorScope = getAnchorScope();
4069 if (isFnInterfaceKind() &&
4070 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
4071 indicatePessimisticFixpoint();
4072 return;
4073 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004074
Johannes Doerfert72adda12019-10-10 05:33:21 +00004075 // You cannot "capture" null in the default address space.
4076 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
4077 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
4078 indicateOptimisticFixpoint();
4079 return;
4080 }
4081
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05004082 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004083
4084 // Check what state the associated function can actually capture.
4085 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05004086 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00004087 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004088 indicatePessimisticFixpoint();
4089 }
4090
4091 /// See AbstractAttribute::updateImpl(...).
4092 ChangeStatus updateImpl(Attributor &A) override;
4093
4094 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
4095 virtual void
4096 getDeducedAttributes(LLVMContext &Ctx,
4097 SmallVectorImpl<Attribute> &Attrs) const override {
4098 if (!isAssumedNoCaptureMaybeReturned())
4099 return;
4100
Hideto Ueno37367642019-09-11 06:52:11 +00004101 if (getArgNo() >= 0) {
4102 if (isAssumedNoCapture())
4103 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
4104 else if (ManifestInternal)
4105 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
4106 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004107 }
4108
4109 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
4110 /// depending on the ability of the function associated with \p IRP to capture
4111 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00004112 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
4113 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05004114 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004115 // TODO: Once we have memory behavior attributes we should use them here.
4116
4117 // If we know we cannot communicate or write to memory, we do not care about
4118 // ptr2int anymore.
4119 if (F.onlyReadsMemory() && F.doesNotThrow() &&
4120 F.getReturnType()->isVoidTy()) {
4121 State.addKnownBits(NO_CAPTURE);
4122 return;
4123 }
4124
4125 // A function cannot capture state in memory if it only reads memory, it can
4126 // however return/throw state and the state might be influenced by the
4127 // pointer value, e.g., loading from a returned pointer might reveal a bit.
4128 if (F.onlyReadsMemory())
4129 State.addKnownBits(NOT_CAPTURED_IN_MEM);
4130
4131 // A function cannot communicate state back if it does not through
4132 // exceptions and doesn not return values.
4133 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
4134 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004135
4136 // Check existing "returned" attributes.
4137 int ArgNo = IRP.getArgNo();
4138 if (F.doesNotThrow() && ArgNo >= 0) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01004139 for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
Johannes Doerfert3839b572019-10-21 00:48:42 +00004140 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00004141 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00004142 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
4143 else if (F.onlyReadsMemory())
4144 State.addKnownBits(NO_CAPTURE);
4145 else
4146 State.addKnownBits(NOT_CAPTURED_IN_RET);
4147 break;
4148 }
4149 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004150 }
4151
4152 /// See AbstractState::getAsStr().
4153 const std::string getAsStr() const override {
4154 if (isKnownNoCapture())
4155 return "known not-captured";
4156 if (isAssumedNoCapture())
4157 return "assumed not-captured";
4158 if (isKnownNoCaptureMaybeReturned())
4159 return "known not-captured-maybe-returned";
4160 if (isAssumedNoCaptureMaybeReturned())
4161 return "assumed not-captured-maybe-returned";
4162 return "assumed-captured";
4163 }
4164};
4165
4166/// Attributor-aware capture tracker.
4167struct AACaptureUseTracker final : public CaptureTracker {
4168
4169 /// Create a capture tracker that can lookup in-flight abstract attributes
4170 /// through the Attributor \p A.
4171 ///
4172 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
4173 /// search is stopped. If a use leads to a return instruction,
4174 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
4175 /// If a use leads to a ptr2int which may capture the value,
4176 /// \p CapturedInInteger is set. If a use is found that is currently assumed
4177 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
4178 /// set. All values in \p PotentialCopies are later tracked as well. For every
4179 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
4180 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
4181 /// conservatively set to true.
4182 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05004183 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004184 SmallVectorImpl<const Value *> &PotentialCopies,
4185 unsigned &RemainingUsesToExplore)
4186 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
4187 PotentialCopies(PotentialCopies),
4188 RemainingUsesToExplore(RemainingUsesToExplore) {}
4189
4190 /// Determine if \p V maybe captured. *Also updates the state!*
4191 bool valueMayBeCaptured(const Value *V) {
4192 if (V->getType()->isPointerTy()) {
4193 PointerMayBeCaptured(V, this);
4194 } else {
4195 State.indicatePessimisticFixpoint();
4196 }
4197 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4198 }
4199
4200 /// See CaptureTracker::tooManyUses().
4201 void tooManyUses() override {
4202 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
4203 }
4204
4205 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
4206 if (CaptureTracker::isDereferenceableOrNull(O, DL))
4207 return true;
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004208 const auto &DerefAA = A.getAAFor<AADereferenceable>(
4209 NoCaptureAA, IRPosition::value(*O), /* TrackDependence */ true,
4210 DepClassTy::OPTIONAL);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004211 return DerefAA.getAssumedDereferenceableBytes();
4212 }
4213
4214 /// See CaptureTracker::captured(...).
4215 bool captured(const Use *U) override {
4216 Instruction *UInst = cast<Instruction>(U->getUser());
4217 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
4218 << "\n");
4219
4220 // Because we may reuse the tracker multiple times we keep track of the
4221 // number of explored uses ourselves as well.
4222 if (RemainingUsesToExplore-- == 0) {
4223 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
4224 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4225 /* Return */ true);
4226 }
4227
4228 // Deal with ptr2int by following uses.
4229 if (isa<PtrToIntInst>(UInst)) {
4230 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
4231 return valueMayBeCaptured(UInst);
4232 }
4233
4234 // Explicitly catch return instructions.
4235 if (isa<ReturnInst>(UInst))
4236 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4237 /* Return */ true);
4238
4239 // For now we only use special logic for call sites. However, the tracker
4240 // itself knows about a lot of other non-capturing cases already.
4241 CallSite CS(UInst);
4242 if (!CS || !CS.isArgOperand(U))
4243 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4244 /* Return */ true);
4245
4246 unsigned ArgNo = CS.getArgumentNo(U);
4247 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
4248 // If we have a abstract no-capture attribute for the argument we can use
4249 // it to justify a non-capture attribute here. This allows recursion!
4250 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
4251 if (ArgNoCaptureAA.isAssumedNoCapture())
4252 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4253 /* Return */ false);
4254 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4255 addPotentialCopy(CS);
4256 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4257 /* Return */ false);
4258 }
4259
4260 // Lastly, we could not find a reason no-capture can be assumed so we don't.
4261 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4262 /* Return */ true);
4263 }
4264
4265 /// Register \p CS as potential copy of the value we are checking.
4266 void addPotentialCopy(CallSite CS) {
4267 PotentialCopies.push_back(CS.getInstruction());
4268 }
4269
4270 /// See CaptureTracker::shouldExplore(...).
4271 bool shouldExplore(const Use *U) override {
Johannes Doerfert23f41f12020-01-12 01:09:22 -06004272 // Check liveness.
4273 return !A.isAssumedDead(*U, &NoCaptureAA, &IsDeadAA);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004274 }
4275
4276 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
4277 /// \p CapturedInRet, then return the appropriate value for use in the
4278 /// CaptureTracker::captured() interface.
4279 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
4280 bool CapturedInRet) {
4281 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
4282 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
4283 if (CapturedInMem)
4284 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
4285 if (CapturedInInt)
4286 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
4287 if (CapturedInRet)
4288 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
4289 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4290 }
4291
4292private:
4293 /// The attributor providing in-flight abstract attributes.
4294 Attributor &A;
4295
4296 /// The abstract attribute currently updated.
4297 AANoCapture &NoCaptureAA;
4298
4299 /// The abstract liveness state.
4300 const AAIsDead &IsDeadAA;
4301
4302 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05004303 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004304
4305 /// Set of potential copies of the tracked value.
4306 SmallVectorImpl<const Value *> &PotentialCopies;
4307
4308 /// Global counter to limit the number of explored uses.
4309 unsigned &RemainingUsesToExplore;
4310};
4311
4312ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
4313 const IRPosition &IRP = getIRPosition();
4314 const Value *V =
4315 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
4316 if (!V)
4317 return indicatePessimisticFixpoint();
4318
4319 const Function *F =
4320 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
4321 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00004322 const IRPosition &FnPos = IRPosition::function(*F);
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004323 const auto &IsDeadAA =
4324 A.getAAFor<AAIsDead>(*this, FnPos, /* TrackDependence */ false);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004325
4326 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004327
Johannes Doerfert3839b572019-10-21 00:48:42 +00004328 // Readonly means we cannot capture through memory.
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004329 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(
4330 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004331 if (FnMemAA.isAssumedReadOnly()) {
4332 T.addKnownBits(NOT_CAPTURED_IN_MEM);
4333 if (FnMemAA.isKnownReadOnly())
4334 addKnownBits(NOT_CAPTURED_IN_MEM);
4335 }
4336
4337 // Make sure all returned values are different than the underlying value.
4338 // TODO: we could do this in a more sophisticated way inside
4339 // AAReturnedValues, e.g., track all values that escape through returns
4340 // directly somehow.
4341 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
4342 bool SeenConstant = false;
4343 for (auto &It : RVAA.returned_values()) {
4344 if (isa<Constant>(It.first)) {
4345 if (SeenConstant)
4346 return false;
4347 SeenConstant = true;
4348 } else if (!isa<Argument>(It.first) ||
4349 It.first == getAssociatedArgument())
4350 return false;
4351 }
4352 return true;
4353 };
4354
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004355 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(
4356 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004357 if (NoUnwindAA.isAssumedNoUnwind()) {
4358 bool IsVoidTy = F->getReturnType()->isVoidTy();
4359 const AAReturnedValues *RVAA =
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004360 IsVoidTy ? nullptr
4361 : &A.getAAFor<AAReturnedValues>(*this, FnPos,
4362 /* TrackDependence */ true,
4363 DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004364 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
4365 T.addKnownBits(NOT_CAPTURED_IN_RET);
4366 if (T.isKnown(NOT_CAPTURED_IN_MEM))
4367 return ChangeStatus::UNCHANGED;
4368 if (NoUnwindAA.isKnownNoUnwind() &&
4369 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
4370 addKnownBits(NOT_CAPTURED_IN_RET);
4371 if (isKnown(NOT_CAPTURED_IN_MEM))
4372 return indicateOptimisticFixpoint();
4373 }
4374 }
4375 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004376
4377 // Use the CaptureTracker interface and logic with the specialized tracker,
4378 // defined in AACaptureUseTracker, that can look at in-flight abstract
4379 // attributes and directly updates the assumed state.
4380 SmallVector<const Value *, 4> PotentialCopies;
4381 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
4382 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
4383 RemainingUsesToExplore);
4384
4385 // Check all potential copies of the associated value until we can assume
4386 // none will be captured or we have to assume at least one might be.
4387 unsigned Idx = 0;
4388 PotentialCopies.push_back(V);
4389 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
4390 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
4391
Johannes Doerfert1a746452019-10-20 22:28:49 -05004392 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004393 auto Assumed = S.getAssumed();
4394 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05004395 if (!isAssumedNoCaptureMaybeReturned())
4396 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004397 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
4398 : ChangeStatus::CHANGED;
4399}
4400
4401/// NoCapture attribute for function arguments.
4402struct AANoCaptureArgument final : AANoCaptureImpl {
4403 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4404
4405 /// See AbstractAttribute::trackStatistics()
4406 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
4407};
4408
4409/// NoCapture attribute for call site arguments.
4410struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
4411 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4412
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004413 /// See AbstractAttribute::initialize(...).
4414 void initialize(Attributor &A) override {
4415 if (Argument *Arg = getAssociatedArgument())
4416 if (Arg->hasByValAttr())
4417 indicateOptimisticFixpoint();
4418 AANoCaptureImpl::initialize(A);
4419 }
4420
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004421 /// See AbstractAttribute::updateImpl(...).
4422 ChangeStatus updateImpl(Attributor &A) override {
4423 // TODO: Once we have call site specific value information we can provide
4424 // call site specific liveness information and then it makes
4425 // sense to specialize attributes for call sites arguments instead of
4426 // redirecting requests to the callee argument.
4427 Argument *Arg = getAssociatedArgument();
4428 if (!Arg)
4429 return indicatePessimisticFixpoint();
4430 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4431 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
4432 return clampStateAndIndicateChange(
4433 getState(),
4434 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
4435 }
4436
4437 /// See AbstractAttribute::trackStatistics()
4438 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
4439};
4440
4441/// NoCapture attribute for floating values.
4442struct AANoCaptureFloating final : AANoCaptureImpl {
4443 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4444
4445 /// See AbstractAttribute::trackStatistics()
4446 void trackStatistics() const override {
4447 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
4448 }
4449};
4450
4451/// NoCapture attribute for function return value.
4452struct AANoCaptureReturned final : AANoCaptureImpl {
4453 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
4454 llvm_unreachable("NoCapture is not applicable to function returns!");
4455 }
4456
4457 /// See AbstractAttribute::initialize(...).
4458 void initialize(Attributor &A) override {
4459 llvm_unreachable("NoCapture is not applicable to function returns!");
4460 }
4461
4462 /// See AbstractAttribute::updateImpl(...).
4463 ChangeStatus updateImpl(Attributor &A) override {
4464 llvm_unreachable("NoCapture is not applicable to function returns!");
4465 }
4466
4467 /// See AbstractAttribute::trackStatistics()
4468 void trackStatistics() const override {}
4469};
4470
4471/// NoCapture attribute deduction for a call site return value.
4472struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
4473 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4474
4475 /// See AbstractAttribute::trackStatistics()
4476 void trackStatistics() const override {
4477 STATS_DECLTRACK_CSRET_ATTR(nocapture)
4478 }
4479};
4480
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004481/// ------------------ Value Simplify Attribute ----------------------------
4482struct AAValueSimplifyImpl : AAValueSimplify {
4483 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
4484
Johannes Doerfert9dcf8892020-01-11 23:59:36 -06004485 /// See AbstractAttribute::initialize(...).
4486 void initialize(Attributor &A) override {
4487 if (getAssociatedValue().getType()->isVoidTy())
4488 indicatePessimisticFixpoint();
4489 }
4490
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004491 /// See AbstractAttribute::getAsStr().
4492 const std::string getAsStr() const override {
4493 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
4494 : "not-simple";
4495 }
4496
4497 /// See AbstractAttribute::trackStatistics()
4498 void trackStatistics() const override {}
4499
4500 /// See AAValueSimplify::getAssumedSimplifiedValue()
4501 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
4502 if (!getAssumed())
4503 return const_cast<Value *>(&getAssociatedValue());
4504 return SimplifiedAssociatedValue;
4505 }
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004506
4507 /// Helper function for querying AAValueSimplify and updating candicate.
4508 /// \param QueryingValue Value trying to unify with SimplifiedValue
4509 /// \param AccumulatedSimplifiedValue Current simplification result.
4510 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
4511 Value &QueryingValue,
4512 Optional<Value *> &AccumulatedSimplifiedValue) {
4513 // FIXME: Add a typecast support.
4514
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004515 auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004516 QueryingAA, IRPosition::value(QueryingValue));
4517
4518 Optional<Value *> QueryingValueSimplified =
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004519 ValueSimplifyAA.getAssumedSimplifiedValue(A);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004520
4521 if (!QueryingValueSimplified.hasValue())
4522 return true;
4523
4524 if (!QueryingValueSimplified.getValue())
4525 return false;
4526
4527 Value &QueryingValueSimplifiedUnwrapped =
4528 *QueryingValueSimplified.getValue();
4529
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004530 if (AccumulatedSimplifiedValue.hasValue() &&
4531 !isa<UndefValue>(AccumulatedSimplifiedValue.getValue()) &&
4532 !isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004533 return AccumulatedSimplifiedValue == QueryingValueSimplified;
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004534 if (AccumulatedSimplifiedValue.hasValue() &&
4535 isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
4536 return true;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004537
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004538 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << QueryingValue
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004539 << " is assumed to be "
4540 << QueryingValueSimplifiedUnwrapped << "\n");
4541
4542 AccumulatedSimplifiedValue = QueryingValueSimplified;
4543 return true;
4544 }
4545
Hideto Ueno188f9a32020-01-15 15:25:52 +09004546 bool askSimplifiedValueForAAValueConstantRange(Attributor &A) {
4547 if (!getAssociatedValue().getType()->isIntegerTy())
4548 return false;
4549
4550 const auto &ValueConstantRangeAA =
4551 A.getAAFor<AAValueConstantRange>(*this, getIRPosition());
4552
4553 Optional<ConstantInt *> COpt =
4554 ValueConstantRangeAA.getAssumedConstantInt(A);
4555 if (COpt.hasValue()) {
4556 if (auto *C = COpt.getValue())
4557 SimplifiedAssociatedValue = C;
4558 else
4559 return false;
4560 } else {
Johannes Doerfert63adbb92020-02-09 20:21:56 -06004561 SimplifiedAssociatedValue = llvm::None;
Hideto Ueno188f9a32020-01-15 15:25:52 +09004562 }
4563 return true;
4564 }
4565
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004566 /// See AbstractAttribute::manifest(...).
4567 ChangeStatus manifest(Attributor &A) override {
4568 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4569
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004570 if (SimplifiedAssociatedValue.hasValue() &&
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004571 !SimplifiedAssociatedValue.getValue())
4572 return Changed;
4573
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004574 Value &V = getAssociatedValue();
4575 auto *C = SimplifiedAssociatedValue.hasValue()
4576 ? dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())
4577 : UndefValue::get(V.getType());
4578 if (C) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004579 // We can replace the AssociatedValue with the constant.
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004580 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004581 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *C
4582 << " :: " << *this << "\n");
Johannes Doerfert4c62a352020-01-12 00:17:08 -06004583 if (A.changeValueAfterManifest(V, *C))
4584 Changed = ChangeStatus::CHANGED;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004585 }
4586 }
4587
4588 return Changed | AAValueSimplify::manifest(A);
4589 }
4590
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004591 /// See AbstractState::indicatePessimisticFixpoint(...).
4592 ChangeStatus indicatePessimisticFixpoint() override {
4593 // NOTE: Associated value will be returned in a pessimistic fixpoint and is
4594 // regarded as known. That's why`indicateOptimisticFixpoint` is called.
4595 SimplifiedAssociatedValue = &getAssociatedValue();
Johannes Doerferta4b35882019-12-31 13:25:47 -06004596 indicateOptimisticFixpoint();
4597 return ChangeStatus::CHANGED;
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004598 }
4599
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004600protected:
4601 // An assumed simplified value. Initially, it is set to Optional::None, which
4602 // means that the value is not clear under current assumption. If in the
4603 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4604 // returns orignal associated value.
4605 Optional<Value *> SimplifiedAssociatedValue;
4606};
4607
4608struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
4609 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4610
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004611 void initialize(Attributor &A) override {
4612 AAValueSimplifyImpl::initialize(A);
4613 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
4614 indicatePessimisticFixpoint();
4615 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
4616 /* IgnoreSubsumingPositions */ true))
4617 indicatePessimisticFixpoint();
Johannes Doerfert16188f92020-02-16 23:04:25 -06004618
4619 // FIXME: This is a hack to prevent us from propagating function poiner in
4620 // the new pass manager CGSCC pass as it creates call edges the
4621 // CallGraphUpdater cannot handle yet.
4622 Value &V = getAssociatedValue();
4623 if (V.getType()->isPointerTy() &&
4624 V.getType()->getPointerElementType()->isFunctionTy() &&
4625 !A.isModulePass() &&
4626 A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
4627 *getAnchorScope()))
4628 indicatePessimisticFixpoint();
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004629 }
4630
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004631 /// See AbstractAttribute::updateImpl(...).
4632 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004633 // Byval is only replacable if it is readonly otherwise we would write into
4634 // the replaced value and not the copy that byval creates implicitly.
4635 Argument *Arg = getAssociatedArgument();
4636 if (Arg->hasByValAttr()) {
Johannes Doerfert8e76fec2020-02-16 17:37:50 -06004637 // TODO: We probably need to verify synchronization is not an issue, e.g.,
4638 // there is no race by not copying a constant byval.
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004639 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
4640 if (!MemAA.isAssumedReadOnly())
4641 return indicatePessimisticFixpoint();
4642 }
4643
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004644 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4645
Johannes Doerfert661db042019-10-07 23:14:58 +00004646 auto PredForCallSite = [&](AbstractCallSite ACS) {
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004647 const IRPosition &ACSArgPos =
4648 IRPosition::callsite_argument(ACS, getArgNo());
4649 // Check if a coresponding argument was found or if it is on not
4650 // associated (which can happen for callback calls).
4651 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004652 return false;
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004653
Johannes Doerferte360ee62019-11-01 18:45:25 -05004654 // We can only propagate thread independent values through callbacks.
4655 // This is different to direct/indirect call sites because for them we
4656 // know the thread executing the caller and callee is the same. For
4657 // callbacks this is not guaranteed, thus a thread dependent value could
4658 // be different for the caller and callee, making it invalid to propagate.
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004659 Value &ArgOp = ACSArgPos.getAssociatedValue();
Johannes Doerferte360ee62019-11-01 18:45:25 -05004660 if (ACS.isCallbackCall())
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004661 if (auto *C = dyn_cast<Constant>(&ArgOp))
Johannes Doerferte360ee62019-11-01 18:45:25 -05004662 if (C->isThreadDependent())
4663 return false;
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06004664 return checkAndUpdate(A, *this, ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004665 };
4666
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004667 bool AllCallSitesKnown;
4668 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4669 AllCallSitesKnown))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004670 if (!askSimplifiedValueForAAValueConstantRange(A))
4671 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004672
4673 // If a candicate was found in this update, return CHANGED.
4674 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4675 ? ChangeStatus::UNCHANGED
4676 : ChangeStatus ::CHANGED;
4677 }
4678
4679 /// See AbstractAttribute::trackStatistics()
4680 void trackStatistics() const override {
4681 STATS_DECLTRACK_ARG_ATTR(value_simplify)
4682 }
4683};
4684
4685struct AAValueSimplifyReturned : AAValueSimplifyImpl {
4686 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4687
4688 /// See AbstractAttribute::updateImpl(...).
4689 ChangeStatus updateImpl(Attributor &A) override {
4690 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4691
4692 auto PredForReturned = [&](Value &V) {
4693 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4694 };
4695
4696 if (!A.checkForAllReturnedValues(PredForReturned, *this))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004697 if (!askSimplifiedValueForAAValueConstantRange(A))
4698 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004699
4700 // If a candicate was found in this update, return CHANGED.
4701 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4702 ? ChangeStatus::UNCHANGED
4703 : ChangeStatus ::CHANGED;
4704 }
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004705
4706 ChangeStatus manifest(Attributor &A) override {
4707 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4708
4709 if (SimplifiedAssociatedValue.hasValue() &&
4710 !SimplifiedAssociatedValue.getValue())
4711 return Changed;
4712
4713 Value &V = getAssociatedValue();
4714 auto *C = SimplifiedAssociatedValue.hasValue()
4715 ? dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())
4716 : UndefValue::get(V.getType());
4717 if (C) {
4718 auto PredForReturned =
4719 [&](Value &V, const SmallSetVector<ReturnInst *, 4> &RetInsts) {
4720 // We can replace the AssociatedValue with the constant.
4721 if (&V == C || V.getType() != C->getType() || isa<UndefValue>(V))
4722 return true;
4723 if (auto *CI = dyn_cast<CallInst>(&V))
4724 if (CI->isMustTailCall())
4725 return true;
4726
4727 for (ReturnInst *RI : RetInsts) {
4728 if (RI->getFunction() != getAnchorScope())
4729 continue;
4730 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *C
4731 << " in " << *RI << " :: " << *this << "\n");
4732 if (A.changeUseAfterManifest(RI->getOperandUse(0), *C))
4733 Changed = ChangeStatus::CHANGED;
4734 }
4735 return true;
4736 };
4737 A.checkForAllReturnedValuesAndReturnInsts(PredForReturned, *this);
4738 }
4739
4740 return Changed | AAValueSimplify::manifest(A);
4741 }
4742
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004743 /// See AbstractAttribute::trackStatistics()
4744 void trackStatistics() const override {
4745 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
4746 }
4747};
4748
4749struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4750 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4751
4752 /// See AbstractAttribute::initialize(...).
4753 void initialize(Attributor &A) override {
Johannes Doerfert16188f92020-02-16 23:04:25 -06004754 AAValueSimplifyImpl::initialize(A);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004755 Value &V = getAnchorValue();
4756
4757 // TODO: add other stuffs
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004758 if (isa<Constant>(V))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004759 indicatePessimisticFixpoint();
4760 }
4761
4762 /// See AbstractAttribute::updateImpl(...).
4763 ChangeStatus updateImpl(Attributor &A) override {
4764 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4765
Johannes Doerfert76843ba2020-01-28 23:51:25 -06004766 auto VisitValueCB = [&](Value &V, bool &, bool Stripped) -> bool {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004767 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
4768 if (!Stripped && this == &AA) {
4769 // TODO: Look the instruction and check recursively.
Hideto Ueno188f9a32020-01-15 15:25:52 +09004770
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004771 LLVM_DEBUG(dbgs() << "[ValueSimplify] Can't be stripped more : " << V
4772 << "\n");
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004773 return false;
4774 }
4775 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4776 };
4777
Johannes Doerfert76843ba2020-01-28 23:51:25 -06004778 bool Dummy = false;
Johannes Doerfert6626d1b2020-01-28 11:49:59 -06004779 if (!genericValueTraversal<AAValueSimplify, bool>(A, getIRPosition(), *this,
4780 Dummy, VisitValueCB))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004781 if (!askSimplifiedValueForAAValueConstantRange(A))
4782 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004783
4784 // If a candicate was found in this update, return CHANGED.
4785
4786 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4787 ? ChangeStatus::UNCHANGED
4788 : ChangeStatus ::CHANGED;
4789 }
4790
4791 /// See AbstractAttribute::trackStatistics()
4792 void trackStatistics() const override {
4793 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
4794 }
4795};
4796
4797struct AAValueSimplifyFunction : AAValueSimplifyImpl {
4798 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4799
4800 /// See AbstractAttribute::initialize(...).
4801 void initialize(Attributor &A) override {
4802 SimplifiedAssociatedValue = &getAnchorValue();
4803 indicateOptimisticFixpoint();
4804 }
4805 /// See AbstractAttribute::initialize(...).
4806 ChangeStatus updateImpl(Attributor &A) override {
4807 llvm_unreachable(
4808 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
4809 }
4810 /// See AbstractAttribute::trackStatistics()
4811 void trackStatistics() const override {
4812 STATS_DECLTRACK_FN_ATTR(value_simplify)
4813 }
4814};
4815
4816struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
4817 AAValueSimplifyCallSite(const IRPosition &IRP)
4818 : AAValueSimplifyFunction(IRP) {}
4819 /// See AbstractAttribute::trackStatistics()
4820 void trackStatistics() const override {
4821 STATS_DECLTRACK_CS_ATTR(value_simplify)
4822 }
4823};
4824
4825struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
4826 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
4827 : AAValueSimplifyReturned(IRP) {}
4828
Johannes Doerfertb2c76002020-01-23 17:12:56 -06004829 /// See AbstractAttribute::manifest(...).
4830 ChangeStatus manifest(Attributor &A) override {
4831 if (auto *CI = dyn_cast<CallInst>(&getAssociatedValue()))
4832 if (CI->isMustTailCall())
4833 return ChangeStatus::UNCHANGED;
Johannes Doerfertad121ea2020-02-14 20:11:22 -06004834 return AAValueSimplifyImpl::manifest(A);
Johannes Doerfertb2c76002020-01-23 17:12:56 -06004835 }
4836
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004837 void trackStatistics() const override {
4838 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
4839 }
4840};
4841struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
4842 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
4843 : AAValueSimplifyFloating(IRP) {}
4844
4845 void trackStatistics() const override {
4846 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
4847 }
4848};
4849
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004850/// ----------------------- Heap-To-Stack Conversion ---------------------------
4851struct AAHeapToStackImpl : public AAHeapToStack {
4852 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
4853
4854 const std::string getAsStr() const override {
4855 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
4856 }
4857
4858 ChangeStatus manifest(Attributor &A) override {
4859 assert(getState().isValidState() &&
4860 "Attempted to manifest an invalid state!");
4861
4862 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4863 Function *F = getAssociatedFunction();
4864 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4865
4866 for (Instruction *MallocCall : MallocCalls) {
4867 // This malloc cannot be replaced.
4868 if (BadMallocCalls.count(MallocCall))
4869 continue;
4870
4871 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
4872 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
4873 A.deleteAfterManifest(*FreeCall);
4874 HasChanged = ChangeStatus::CHANGED;
4875 }
4876
4877 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
4878 << "\n");
4879
4880 Constant *Size;
4881 if (isCallocLikeFn(MallocCall, TLI)) {
4882 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
4883 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
4884 APInt TotalSize = SizeT->getValue() * Num->getValue();
4885 Size =
4886 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
4887 } else {
4888 Size = cast<ConstantInt>(MallocCall->getOperand(0));
4889 }
4890
4891 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
4892 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
4893 Size, "", MallocCall->getNextNode());
4894
4895 if (AI->getType() != MallocCall->getType())
4896 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
4897 AI->getNextNode());
4898
Johannes Doerfert4c62a352020-01-12 00:17:08 -06004899 A.changeValueAfterManifest(*MallocCall, *AI);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004900
4901 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
4902 auto *NBB = II->getNormalDest();
4903 BranchInst::Create(NBB, MallocCall->getParent());
4904 A.deleteAfterManifest(*MallocCall);
4905 } else {
4906 A.deleteAfterManifest(*MallocCall);
4907 }
4908
4909 if (isCallocLikeFn(MallocCall, TLI)) {
4910 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
4911 AI->getNextNode());
4912 Value *Ops[] = {
4913 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
4914 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
4915
4916 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
4917 Module *M = F->getParent();
4918 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
4919 CallInst::Create(Fn, Ops, "", BI->getNextNode());
4920 }
4921 HasChanged = ChangeStatus::CHANGED;
4922 }
4923
4924 return HasChanged;
4925 }
4926
4927 /// Collection of all malloc calls in a function.
4928 SmallSetVector<Instruction *, 4> MallocCalls;
4929
4930 /// Collection of malloc calls that cannot be converted.
4931 DenseSet<const Instruction *> BadMallocCalls;
4932
4933 /// A map for each malloc call to the set of associated free calls.
4934 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
4935
4936 ChangeStatus updateImpl(Attributor &A) override;
4937};
4938
4939ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4940 const Function *F = getAssociatedFunction();
4941 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4942
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004943 MustBeExecutedContextExplorer &Explorer =
4944 A.getInfoCache().getMustBeExecutedContextExplorer();
4945
4946 auto FreeCheck = [&](Instruction &I) {
4947 const auto &Frees = FreesForMalloc.lookup(&I);
4948 if (Frees.size() != 1)
4949 return false;
4950 Instruction *UniqueFree = *Frees.begin();
4951 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
4952 };
4953
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004954 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004955 bool ValidUsesOnly = true;
4956 bool MustUse = true;
Hideto Ueno827bade2019-12-12 12:26:30 +00004957 auto Pred = [&](const Use &U, bool &Follow) -> bool {
4958 Instruction *UserI = cast<Instruction>(U.getUser());
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004959 if (isa<LoadInst>(UserI))
Hideto Ueno827bade2019-12-12 12:26:30 +00004960 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004961 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004962 if (SI->getValueOperand() == U.get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004963 LLVM_DEBUG(dbgs()
4964 << "[H2S] escaping store to memory: " << *UserI << "\n");
4965 ValidUsesOnly = false;
4966 } else {
4967 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004968 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004969 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004970 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004971 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004972 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
4973 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004974 // Record malloc.
4975 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004976 if (MustUse) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004977 FreesForMalloc[&I].insert(UserI);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004978 } else {
4979 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
4980 << *UserI << "\n");
4981 ValidUsesOnly = false;
4982 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004983 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004984 }
4985
Hideto Ueno827bade2019-12-12 12:26:30 +00004986 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004987
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004988 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
4989 *this, IRPosition::callsite_argument(*CB, ArgNo));
4990
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004991 // If a callsite argument use is nofree, we are fine.
4992 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
4993 *this, IRPosition::callsite_argument(*CB, ArgNo));
4994
Hideto Ueno827bade2019-12-12 12:26:30 +00004995 if (!NoCaptureAA.isAssumedNoCapture() ||
4996 !ArgNoFreeAA.isAssumedNoFree()) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004997 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004998 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004999 }
Hideto Ueno827bade2019-12-12 12:26:30 +00005000 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005001 }
5002
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005003 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
5004 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
5005 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Hideto Ueno827bade2019-12-12 12:26:30 +00005006 Follow = true;
5007 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005008 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005009 // Unknown user for which we can not track uses further (in a way that
5010 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005011 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005012 ValidUsesOnly = false;
Hideto Ueno827bade2019-12-12 12:26:30 +00005013 return true;
5014 };
5015 A.checkForAllUses(Pred, *this, I);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005016 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005017 };
5018
5019 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005020 if (BadMallocCalls.count(&I))
5021 return true;
5022
5023 bool IsMalloc = isMallocLikeFn(&I, TLI);
5024 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
5025 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005026 BadMallocCalls.insert(&I);
5027 return true;
5028 }
5029
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005030 if (IsMalloc) {
5031 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01005032 if (Size->getValue().ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005033 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005034 MallocCalls.insert(&I);
5035 return true;
5036 }
5037 } else if (IsCalloc) {
5038 bool Overflow = false;
5039 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
5040 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
5041 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01005042 .ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005043 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005044 MallocCalls.insert(&I);
5045 return true;
5046 }
5047 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005048
Johannes Doerfertd20f8072019-10-13 03:54:08 +00005049 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005050 return true;
5051 };
5052
5053 size_t NumBadMallocs = BadMallocCalls.size();
5054
5055 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
5056
5057 if (NumBadMallocs != BadMallocCalls.size())
5058 return ChangeStatus::CHANGED;
5059
5060 return ChangeStatus::UNCHANGED;
5061}
5062
5063struct AAHeapToStackFunction final : public AAHeapToStackImpl {
5064 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
5065
5066 /// See AbstractAttribute::trackStatistics()
5067 void trackStatistics() const override {
5068 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05005069 "Number of malloc calls converted to allocas");
5070 for (auto *C : MallocCalls)
5071 if (!BadMallocCalls.count(C))
5072 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00005073 }
5074};
5075
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005076/// ----------------------- Privatizable Pointers ------------------------------
5077struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
5078 AAPrivatizablePtrImpl(const IRPosition &IRP)
5079 : AAPrivatizablePtr(IRP), PrivatizableType(llvm::None) {}
5080
5081 ChangeStatus indicatePessimisticFixpoint() override {
5082 AAPrivatizablePtr::indicatePessimisticFixpoint();
5083 PrivatizableType = nullptr;
5084 return ChangeStatus::CHANGED;
5085 }
5086
5087 /// Identify the type we can chose for a private copy of the underlying
5088 /// argument. None means it is not clear yet, nullptr means there is none.
5089 virtual Optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
5090
5091 /// Return a privatizable type that encloses both T0 and T1.
5092 /// TODO: This is merely a stub for now as we should manage a mapping as well.
5093 Optional<Type *> combineTypes(Optional<Type *> T0, Optional<Type *> T1) {
5094 if (!T0.hasValue())
5095 return T1;
5096 if (!T1.hasValue())
5097 return T0;
5098 if (T0 == T1)
5099 return T0;
5100 return nullptr;
5101 }
5102
5103 Optional<Type *> getPrivatizableType() const override {
5104 return PrivatizableType;
5105 }
5106
5107 const std::string getAsStr() const override {
5108 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
5109 }
5110
5111protected:
5112 Optional<Type *> PrivatizableType;
5113};
5114
5115// TODO: Do this for call site arguments (probably also other values) as well.
5116
5117struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
5118 AAPrivatizablePtrArgument(const IRPosition &IRP)
5119 : AAPrivatizablePtrImpl(IRP) {}
5120
5121 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
5122 Optional<Type *> identifyPrivatizableType(Attributor &A) override {
5123 // If this is a byval argument and we know all the call sites (so we can
5124 // rewrite them), there is no need to check them explicitly.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005125 bool AllCallSitesKnown;
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005126 if (getIRPosition().hasAttr(Attribute::ByVal) &&
5127 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005128 true, AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005129 return getAssociatedValue().getType()->getPointerElementType();
5130
5131 Optional<Type *> Ty;
5132 unsigned ArgNo = getIRPosition().getArgNo();
5133
5134 // Make sure the associated call site argument has the same type at all call
5135 // sites and it is an allocation we know is safe to privatize, for now that
5136 // means we only allow alloca instructions.
5137 // TODO: We can additionally analyze the accesses in the callee to create
5138 // the type from that information instead. That is a little more
5139 // involved and will be done in a follow up patch.
5140 auto CallSiteCheck = [&](AbstractCallSite ACS) {
5141 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
5142 // Check if a coresponding argument was found or if it is one not
5143 // associated (which can happen for callback calls).
5144 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
5145 return false;
5146
5147 // Check that all call sites agree on a type.
5148 auto &PrivCSArgAA = A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos);
5149 Optional<Type *> CSTy = PrivCSArgAA.getPrivatizableType();
5150
5151 LLVM_DEBUG({
5152 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
5153 if (CSTy.hasValue() && CSTy.getValue())
5154 CSTy.getValue()->print(dbgs());
5155 else if (CSTy.hasValue())
5156 dbgs() << "<nullptr>";
5157 else
5158 dbgs() << "<none>";
5159 });
5160
5161 Ty = combineTypes(Ty, CSTy);
5162
5163 LLVM_DEBUG({
5164 dbgs() << " : New Type: ";
5165 if (Ty.hasValue() && Ty.getValue())
5166 Ty.getValue()->print(dbgs());
5167 else if (Ty.hasValue())
5168 dbgs() << "<nullptr>";
5169 else
5170 dbgs() << "<none>";
5171 dbgs() << "\n";
5172 });
5173
5174 return !Ty.hasValue() || Ty.getValue();
5175 };
5176
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005177 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005178 return nullptr;
5179 return Ty;
5180 }
5181
5182 /// See AbstractAttribute::updateImpl(...).
5183 ChangeStatus updateImpl(Attributor &A) override {
5184 PrivatizableType = identifyPrivatizableType(A);
5185 if (!PrivatizableType.hasValue())
5186 return ChangeStatus::UNCHANGED;
5187 if (!PrivatizableType.getValue())
5188 return indicatePessimisticFixpoint();
5189
5190 // Avoid arguments with padding for now.
5191 if (!getIRPosition().hasAttr(Attribute::ByVal) &&
5192 !ArgumentPromotionPass::isDenselyPacked(PrivatizableType.getValue(),
5193 A.getInfoCache().getDL())) {
5194 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
5195 return indicatePessimisticFixpoint();
5196 }
5197
5198 // Verify callee and caller agree on how the promoted argument would be
5199 // passed.
5200 // TODO: The use of the ArgumentPromotion interface here is ugly, we need a
5201 // specialized form of TargetTransformInfo::areFunctionArgsABICompatible
5202 // which doesn't require the arguments ArgumentPromotion wanted to pass.
5203 Function &Fn = *getIRPosition().getAnchorScope();
5204 SmallPtrSet<Argument *, 1> ArgsToPromote, Dummy;
5205 ArgsToPromote.insert(getAssociatedArgument());
5206 const auto *TTI =
5207 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
5208 if (!TTI ||
5209 !ArgumentPromotionPass::areFunctionArgsABICompatible(
5210 Fn, *TTI, ArgsToPromote, Dummy) ||
5211 ArgsToPromote.empty()) {
5212 LLVM_DEBUG(
5213 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
5214 << Fn.getName() << "\n");
5215 return indicatePessimisticFixpoint();
5216 }
5217
5218 // Collect the types that will replace the privatizable type in the function
5219 // signature.
5220 SmallVector<Type *, 16> ReplacementTypes;
5221 identifyReplacementTypes(PrivatizableType.getValue(), ReplacementTypes);
5222
5223 // Register a rewrite of the argument.
5224 Argument *Arg = getAssociatedArgument();
5225 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
5226 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
5227 return indicatePessimisticFixpoint();
5228 }
5229
5230 unsigned ArgNo = Arg->getArgNo();
5231
5232 // Helper to check if for the given call site the associated argument is
5233 // passed to a callback where the privatization would be different.
5234 auto IsCompatiblePrivArgOfCallback = [&](CallSite CS) {
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005235 SmallVector<const Use *, 4> CBUses;
5236 AbstractCallSite::getCallbackUses(CS, CBUses);
5237 for (const Use *U : CBUses) {
5238 AbstractCallSite CBACS(U);
5239 assert(CBACS && CBACS.isCallbackCall());
5240 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
5241 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
5242
5243 LLVM_DEBUG({
5244 dbgs()
5245 << "[AAPrivatizablePtr] Argument " << *Arg
5246 << "check if can be privatized in the context of its parent ("
5247 << Arg->getParent()->getName()
5248 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5249 "callback ("
5250 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
5251 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
Michael Forster676c2962020-01-30 10:20:49 +01005252 << CBACS.getCallArgOperand(CBArg) << " vs "
5253 << CS.getArgOperand(ArgNo) << "\n"
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005254 << "[AAPrivatizablePtr] " << CBArg << " : "
5255 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
5256 });
5257
5258 if (CBArgNo != int(ArgNo))
5259 continue;
5260 const auto &CBArgPrivAA =
5261 A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(CBArg));
5262 if (CBArgPrivAA.isValidState()) {
5263 auto CBArgPrivTy = CBArgPrivAA.getPrivatizableType();
5264 if (!CBArgPrivTy.hasValue())
5265 continue;
5266 if (CBArgPrivTy.getValue() == PrivatizableType)
5267 continue;
5268 }
5269
5270 LLVM_DEBUG({
5271 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5272 << " cannot be privatized in the context of its parent ("
5273 << Arg->getParent()->getName()
5274 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5275 "callback ("
5276 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
5277 << ").\n[AAPrivatizablePtr] for which the argument "
5278 "privatization is not compatible.\n";
5279 });
5280 return false;
5281 }
5282 }
5283 return true;
5284 };
5285
5286 // Helper to check if for the given call site the associated argument is
5287 // passed to a direct call where the privatization would be different.
5288 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
5289 CallBase *DC = cast<CallBase>(ACS.getInstruction());
5290 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
5291 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->getNumArgOperands() &&
5292 "Expected a direct call operand for callback call operand");
5293
5294 LLVM_DEBUG({
5295 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5296 << " check if be privatized in the context of its parent ("
5297 << Arg->getParent()->getName()
5298 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5299 "direct call of ("
5300 << DCArgNo << "@" << DC->getCalledFunction()->getName()
5301 << ").\n";
5302 });
5303
5304 Function *DCCallee = DC->getCalledFunction();
5305 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
5306 const auto &DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
5307 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)));
5308 if (DCArgPrivAA.isValidState()) {
5309 auto DCArgPrivTy = DCArgPrivAA.getPrivatizableType();
5310 if (!DCArgPrivTy.hasValue())
5311 return true;
5312 if (DCArgPrivTy.getValue() == PrivatizableType)
5313 return true;
5314 }
5315 }
5316
5317 LLVM_DEBUG({
5318 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5319 << " cannot be privatized in the context of its parent ("
5320 << Arg->getParent()->getName()
5321 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5322 "direct call of ("
5323 << ACS.getCallSite().getCalledFunction()->getName()
5324 << ").\n[AAPrivatizablePtr] for which the argument "
5325 "privatization is not compatible.\n";
5326 });
5327 return false;
5328 };
5329
5330 // Helper to check if the associated argument is used at the given abstract
5331 // call site in a way that is incompatible with the privatization assumed
5332 // here.
5333 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
5334 if (ACS.isDirectCall())
5335 return IsCompatiblePrivArgOfCallback(ACS.getCallSite());
5336 if (ACS.isCallbackCall())
5337 return IsCompatiblePrivArgOfDirectCS(ACS);
5338 return false;
5339 };
5340
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005341 bool AllCallSitesKnown;
5342 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
5343 AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005344 return indicatePessimisticFixpoint();
5345
5346 return ChangeStatus::UNCHANGED;
5347 }
5348
5349 /// Given a type to private \p PrivType, collect the constituates (which are
5350 /// used) in \p ReplacementTypes.
5351 static void
5352 identifyReplacementTypes(Type *PrivType,
5353 SmallVectorImpl<Type *> &ReplacementTypes) {
5354 // TODO: For now we expand the privatization type to the fullest which can
5355 // lead to dead arguments that need to be removed later.
5356 assert(PrivType && "Expected privatizable type!");
5357
5358 // Traverse the type, extract constituate types on the outermost level.
5359 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5360 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
5361 ReplacementTypes.push_back(PrivStructType->getElementType(u));
5362 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5363 ReplacementTypes.append(PrivArrayType->getNumElements(),
5364 PrivArrayType->getElementType());
5365 } else {
5366 ReplacementTypes.push_back(PrivType);
5367 }
5368 }
5369
5370 /// Initialize \p Base according to the type \p PrivType at position \p IP.
5371 /// The values needed are taken from the arguments of \p F starting at
5372 /// position \p ArgNo.
5373 static void createInitialization(Type *PrivType, Value &Base, Function &F,
5374 unsigned ArgNo, Instruction &IP) {
5375 assert(PrivType && "Expected privatizable type!");
5376
5377 IRBuilder<NoFolder> IRB(&IP);
5378 const DataLayout &DL = F.getParent()->getDataLayout();
5379
5380 // Traverse the type, build GEPs and stores.
5381 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5382 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
5383 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
5384 Type *PointeeTy = PrivStructType->getElementType(u)->getPointerTo();
5385 Value *Ptr = constructPointer(
5386 PointeeTy, &Base, PrivStructLayout->getElementOffset(u), IRB, DL);
5387 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
5388 }
5389 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5390 Type *PointeePtrTy = PrivArrayType->getElementType()->getPointerTo();
5391 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeePtrTy);
5392 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
5393 Value *Ptr =
5394 constructPointer(PointeePtrTy, &Base, u * PointeeTySize, IRB, DL);
5395 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
5396 }
5397 } else {
5398 new StoreInst(F.getArg(ArgNo), &Base, &IP);
5399 }
5400 }
5401
5402 /// Extract values from \p Base according to the type \p PrivType at the
5403 /// call position \p ACS. The values are appended to \p ReplacementValues.
5404 void createReplacementValues(Type *PrivType, AbstractCallSite ACS,
5405 Value *Base,
5406 SmallVectorImpl<Value *> &ReplacementValues) {
5407 assert(Base && "Expected base value!");
5408 assert(PrivType && "Expected privatizable type!");
5409 Instruction *IP = ACS.getInstruction();
5410
5411 IRBuilder<NoFolder> IRB(IP);
5412 const DataLayout &DL = IP->getModule()->getDataLayout();
5413
5414 if (Base->getType()->getPointerElementType() != PrivType)
5415 Base = BitCastInst::CreateBitOrPointerCast(Base, PrivType->getPointerTo(),
5416 "", ACS.getInstruction());
5417
5418 // TODO: Improve the alignment of the loads.
5419 // Traverse the type, build GEPs and loads.
5420 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5421 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
5422 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
5423 Type *PointeeTy = PrivStructType->getElementType(u);
5424 Value *Ptr =
5425 constructPointer(PointeeTy->getPointerTo(), Base,
5426 PrivStructLayout->getElementOffset(u), IRB, DL);
5427 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP);
5428 L->setAlignment(MaybeAlign(1));
5429 ReplacementValues.push_back(L);
5430 }
5431 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5432 Type *PointeeTy = PrivArrayType->getElementType();
5433 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
5434 Type *PointeePtrTy = PointeeTy->getPointerTo();
5435 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
5436 Value *Ptr =
5437 constructPointer(PointeePtrTy, Base, u * PointeeTySize, IRB, DL);
5438 LoadInst *L = new LoadInst(PointeePtrTy, Ptr, "", IP);
5439 L->setAlignment(MaybeAlign(1));
5440 ReplacementValues.push_back(L);
5441 }
5442 } else {
5443 LoadInst *L = new LoadInst(PrivType, Base, "", IP);
5444 L->setAlignment(MaybeAlign(1));
5445 ReplacementValues.push_back(L);
5446 }
5447 }
5448
5449 /// See AbstractAttribute::manifest(...)
5450 ChangeStatus manifest(Attributor &A) override {
5451 if (!PrivatizableType.hasValue())
5452 return ChangeStatus::UNCHANGED;
5453 assert(PrivatizableType.getValue() && "Expected privatizable type!");
5454
5455 // Collect all tail calls in the function as we cannot allow new allocas to
5456 // escape into tail recursion.
5457 // TODO: Be smarter about new allocas escaping into tail calls.
5458 SmallVector<CallInst *, 16> TailCalls;
5459 if (!A.checkForAllInstructions(
5460 [&](Instruction &I) {
5461 CallInst &CI = cast<CallInst>(I);
5462 if (CI.isTailCall())
5463 TailCalls.push_back(&CI);
5464 return true;
5465 },
5466 *this, {Instruction::Call}))
5467 return ChangeStatus::UNCHANGED;
5468
5469 Argument *Arg = getAssociatedArgument();
5470
5471 // Callback to repair the associated function. A new alloca is placed at the
5472 // beginning and initialized with the values passed through arguments. The
5473 // new alloca replaces the use of the old pointer argument.
5474 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB =
5475 [=](const Attributor::ArgumentReplacementInfo &ARI,
5476 Function &ReplacementFn, Function::arg_iterator ArgIt) {
5477 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
5478 Instruction *IP = &*EntryBB.getFirstInsertionPt();
5479 auto *AI = new AllocaInst(PrivatizableType.getValue(), 0,
5480 Arg->getName() + ".priv", IP);
5481 createInitialization(PrivatizableType.getValue(), *AI, ReplacementFn,
5482 ArgIt->getArgNo(), *IP);
5483 Arg->replaceAllUsesWith(AI);
5484
5485 for (CallInst *CI : TailCalls)
5486 CI->setTailCall(false);
5487 };
5488
5489 // Callback to repair a call site of the associated function. The elements
5490 // of the privatizable type are loaded prior to the call and passed to the
5491 // new function version.
5492 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB =
5493 [=](const Attributor::ArgumentReplacementInfo &ARI,
5494 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
5495 createReplacementValues(
5496 PrivatizableType.getValue(), ACS,
5497 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
5498 NewArgOperands);
5499 };
5500
5501 // Collect the types that will replace the privatizable type in the function
5502 // signature.
5503 SmallVector<Type *, 16> ReplacementTypes;
5504 identifyReplacementTypes(PrivatizableType.getValue(), ReplacementTypes);
5505
5506 // Register a rewrite of the argument.
5507 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
5508 std::move(FnRepairCB),
5509 std::move(ACSRepairCB)))
5510 return ChangeStatus::CHANGED;
5511 return ChangeStatus::UNCHANGED;
5512 }
5513
5514 /// See AbstractAttribute::trackStatistics()
5515 void trackStatistics() const override {
5516 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
5517 }
5518};
5519
5520struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
5521 AAPrivatizablePtrFloating(const IRPosition &IRP)
5522 : AAPrivatizablePtrImpl(IRP) {}
5523
5524 /// See AbstractAttribute::initialize(...).
5525 virtual void initialize(Attributor &A) override {
5526 // TODO: We can privatize more than arguments.
5527 indicatePessimisticFixpoint();
5528 }
5529
5530 ChangeStatus updateImpl(Attributor &A) override {
5531 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
5532 "updateImpl will not be called");
5533 }
5534
5535 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
5536 Optional<Type *> identifyPrivatizableType(Attributor &A) override {
5537 Value *Obj =
5538 GetUnderlyingObject(&getAssociatedValue(), A.getInfoCache().getDL());
5539 if (!Obj) {
5540 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
5541 return nullptr;
5542 }
5543
5544 if (auto *AI = dyn_cast<AllocaInst>(Obj))
5545 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
5546 if (CI->isOne())
5547 return Obj->getType()->getPointerElementType();
5548 if (auto *Arg = dyn_cast<Argument>(Obj)) {
5549 auto &PrivArgAA =
5550 A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(*Arg));
5551 if (PrivArgAA.isAssumedPrivatizablePtr())
5552 return Obj->getType()->getPointerElementType();
5553 }
5554
5555 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
5556 "alloca nor privatizable argument: "
5557 << *Obj << "!\n");
5558 return nullptr;
5559 }
5560
5561 /// See AbstractAttribute::trackStatistics()
5562 void trackStatistics() const override {
5563 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
5564 }
5565};
5566
5567struct AAPrivatizablePtrCallSiteArgument final
5568 : public AAPrivatizablePtrFloating {
5569 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP)
5570 : AAPrivatizablePtrFloating(IRP) {}
5571
5572 /// See AbstractAttribute::initialize(...).
5573 void initialize(Attributor &A) override {
5574 if (getIRPosition().hasAttr(Attribute::ByVal))
5575 indicateOptimisticFixpoint();
5576 }
5577
5578 /// See AbstractAttribute::updateImpl(...).
5579 ChangeStatus updateImpl(Attributor &A) override {
5580 PrivatizableType = identifyPrivatizableType(A);
5581 if (!PrivatizableType.hasValue())
5582 return ChangeStatus::UNCHANGED;
5583 if (!PrivatizableType.getValue())
5584 return indicatePessimisticFixpoint();
5585
5586 const IRPosition &IRP = getIRPosition();
5587 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
5588 if (!NoCaptureAA.isAssumedNoCapture()) {
5589 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
5590 return indicatePessimisticFixpoint();
5591 }
5592
5593 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
5594 if (!NoAliasAA.isAssumedNoAlias()) {
5595 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
5596 return indicatePessimisticFixpoint();
5597 }
5598
5599 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, IRP);
5600 if (!MemBehaviorAA.isAssumedReadOnly()) {
5601 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
5602 return indicatePessimisticFixpoint();
5603 }
5604
5605 return ChangeStatus::UNCHANGED;
5606 }
5607
5608 /// See AbstractAttribute::trackStatistics()
5609 void trackStatistics() const override {
5610 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
5611 }
5612};
5613
5614struct AAPrivatizablePtrCallSiteReturned final
5615 : public AAPrivatizablePtrFloating {
5616 AAPrivatizablePtrCallSiteReturned(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_CSRET_ATTR(privatizable_ptr);
5628 }
5629};
5630
5631struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
5632 AAPrivatizablePtrReturned(const IRPosition &IRP)
5633 : AAPrivatizablePtrFloating(IRP) {}
5634
5635 /// See AbstractAttribute::initialize(...).
5636 void initialize(Attributor &A) override {
5637 // TODO: We can privatize more than arguments.
5638 indicatePessimisticFixpoint();
5639 }
5640
5641 /// See AbstractAttribute::trackStatistics()
5642 void trackStatistics() const override {
5643 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
5644 }
5645};
5646
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005647/// -------------------- Memory Behavior Attributes ----------------------------
5648/// Includes read-none, read-only, and write-only.
5649/// ----------------------------------------------------------------------------
5650struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
5651 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
5652
5653 /// See AbstractAttribute::initialize(...).
5654 void initialize(Attributor &A) override {
5655 intersectAssumedBits(BEST_STATE);
5656 getKnownStateFromValue(getIRPosition(), getState());
5657 IRAttribute::initialize(A);
5658 }
5659
5660 /// Return the memory behavior information encoded in the IR for \p IRP.
5661 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005662 BitIntegerState &State,
5663 bool IgnoreSubsumingPositions = false) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005664 SmallVector<Attribute, 2> Attrs;
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005665 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005666 for (const Attribute &Attr : Attrs) {
5667 switch (Attr.getKindAsEnum()) {
5668 case Attribute::ReadNone:
5669 State.addKnownBits(NO_ACCESSES);
5670 break;
5671 case Attribute::ReadOnly:
5672 State.addKnownBits(NO_WRITES);
5673 break;
5674 case Attribute::WriteOnly:
5675 State.addKnownBits(NO_READS);
5676 break;
5677 default:
Johannes Doerfert282f5d72020-01-26 02:51:57 -06005678 llvm_unreachable("Unexpected attribute!");
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005679 }
5680 }
5681
5682 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
5683 if (!I->mayReadFromMemory())
5684 State.addKnownBits(NO_READS);
5685 if (!I->mayWriteToMemory())
5686 State.addKnownBits(NO_WRITES);
5687 }
5688 }
5689
5690 /// See AbstractAttribute::getDeducedAttributes(...).
5691 void getDeducedAttributes(LLVMContext &Ctx,
5692 SmallVectorImpl<Attribute> &Attrs) const override {
5693 assert(Attrs.size() == 0);
5694 if (isAssumedReadNone())
5695 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
5696 else if (isAssumedReadOnly())
5697 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
5698 else if (isAssumedWriteOnly())
5699 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
5700 assert(Attrs.size() <= 1);
5701 }
5702
5703 /// See AbstractAttribute::manifest(...).
5704 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert282f5d72020-01-26 02:51:57 -06005705 if (hasAttr(Attribute::ReadNone, /* IgnoreSubsumingPositions */ true))
5706 return ChangeStatus::UNCHANGED;
5707
Johannes Doerfertb2083c52019-10-20 22:46:48 -05005708 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005709
5710 // Check if we would improve the existing attributes first.
5711 SmallVector<Attribute, 4> DeducedAttrs;
5712 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
5713 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
5714 return IRP.hasAttr(Attr.getKindAsEnum(),
5715 /* IgnoreSubsumingPositions */ true);
5716 }))
5717 return ChangeStatus::UNCHANGED;
5718
5719 // Clear existing attributes.
5720 IRP.removeAttrs(AttrKinds);
5721
5722 // Use the generic manifest method.
5723 return IRAttribute::manifest(A);
5724 }
5725
5726 /// See AbstractState::getAsStr().
5727 const std::string getAsStr() const override {
5728 if (isAssumedReadNone())
5729 return "readnone";
5730 if (isAssumedReadOnly())
5731 return "readonly";
5732 if (isAssumedWriteOnly())
5733 return "writeonly";
5734 return "may-read/write";
5735 }
5736
5737 /// The set of IR attributes AAMemoryBehavior deals with.
5738 static const Attribute::AttrKind AttrKinds[3];
5739};
5740
5741const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
5742 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
5743
5744/// Memory behavior attribute for a floating value.
5745struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
5746 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5747
5748 /// See AbstractAttribute::initialize(...).
5749 void initialize(Attributor &A) override {
5750 AAMemoryBehaviorImpl::initialize(A);
5751 // Initialize the use vector with all direct uses of the associated value.
5752 for (const Use &U : getAssociatedValue().uses())
5753 Uses.insert(&U);
5754 }
5755
5756 /// See AbstractAttribute::updateImpl(...).
5757 ChangeStatus updateImpl(Attributor &A) override;
5758
5759 /// See AbstractAttribute::trackStatistics()
5760 void trackStatistics() const override {
5761 if (isAssumedReadNone())
5762 STATS_DECLTRACK_FLOATING_ATTR(readnone)
5763 else if (isAssumedReadOnly())
5764 STATS_DECLTRACK_FLOATING_ATTR(readonly)
5765 else if (isAssumedWriteOnly())
5766 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
5767 }
5768
5769private:
5770 /// Return true if users of \p UserI might access the underlying
5771 /// variable/location described by \p U and should therefore be analyzed.
5772 bool followUsersOfUseIn(Attributor &A, const Use *U,
5773 const Instruction *UserI);
5774
5775 /// Update the state according to the effect of use \p U in \p UserI.
5776 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
5777
5778protected:
5779 /// Container for (transitive) uses of the associated argument.
5780 SetVector<const Use *> Uses;
5781};
5782
5783/// Memory behavior attribute for function argument.
5784struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
5785 AAMemoryBehaviorArgument(const IRPosition &IRP)
5786 : AAMemoryBehaviorFloating(IRP) {}
5787
5788 /// See AbstractAttribute::initialize(...).
5789 void initialize(Attributor &A) override {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005790 intersectAssumedBits(BEST_STATE);
5791 const IRPosition &IRP = getIRPosition();
5792 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
5793 // can query it when we use has/getAttr. That would allow us to reuse the
5794 // initialize of the base class here.
5795 bool HasByVal =
5796 IRP.hasAttr({Attribute::ByVal}, /* IgnoreSubsumingPositions */ true);
5797 getKnownStateFromValue(IRP, getState(),
5798 /* IgnoreSubsumingPositions */ HasByVal);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005799
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005800 // Initialize the use vector with all direct uses of the associated value.
5801 Argument *Arg = getAssociatedArgument();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005802 if (!Arg || !Arg->getParent()->hasExactDefinition()) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005803 indicatePessimisticFixpoint();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005804 } else {
5805 // Initialize the use vector with all direct uses of the associated value.
5806 for (const Use &U : Arg->uses())
5807 Uses.insert(&U);
5808 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005809 }
5810
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005811 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert282f5d72020-01-26 02:51:57 -06005812 // TODO: Pointer arguments are not supported on vectors of pointers yet.
5813 if (!getAssociatedValue().getType()->isPointerTy())
5814 return ChangeStatus::UNCHANGED;
5815
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005816 // TODO: From readattrs.ll: "inalloca parameters are always
5817 // considered written"
5818 if (hasAttr({Attribute::InAlloca})) {
5819 removeKnownBits(NO_WRITES);
5820 removeAssumedBits(NO_WRITES);
5821 }
5822 return AAMemoryBehaviorFloating::manifest(A);
5823 }
5824
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005825 /// See AbstractAttribute::trackStatistics()
5826 void trackStatistics() const override {
5827 if (isAssumedReadNone())
5828 STATS_DECLTRACK_ARG_ATTR(readnone)
5829 else if (isAssumedReadOnly())
5830 STATS_DECLTRACK_ARG_ATTR(readonly)
5831 else if (isAssumedWriteOnly())
5832 STATS_DECLTRACK_ARG_ATTR(writeonly)
5833 }
5834};
5835
5836struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
5837 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
5838 : AAMemoryBehaviorArgument(IRP) {}
5839
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005840 /// See AbstractAttribute::initialize(...).
5841 void initialize(Attributor &A) override {
5842 if (Argument *Arg = getAssociatedArgument()) {
5843 if (Arg->hasByValAttr()) {
5844 addKnownBits(NO_WRITES);
5845 removeKnownBits(NO_READS);
5846 removeAssumedBits(NO_READS);
5847 }
5848 } else {
5849 }
5850 AAMemoryBehaviorArgument::initialize(A);
5851 }
5852
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005853 /// See AbstractAttribute::updateImpl(...).
5854 ChangeStatus updateImpl(Attributor &A) override {
5855 // TODO: Once we have call site specific value information we can provide
5856 // call site specific liveness liveness information and then it makes
5857 // sense to specialize attributes for call sites arguments instead of
5858 // redirecting requests to the callee argument.
5859 Argument *Arg = getAssociatedArgument();
5860 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5861 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
5862 return clampStateAndIndicateChange(
5863 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05005864 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005865 }
5866
5867 /// See AbstractAttribute::trackStatistics()
5868 void trackStatistics() const override {
5869 if (isAssumedReadNone())
5870 STATS_DECLTRACK_CSARG_ATTR(readnone)
5871 else if (isAssumedReadOnly())
5872 STATS_DECLTRACK_CSARG_ATTR(readonly)
5873 else if (isAssumedWriteOnly())
5874 STATS_DECLTRACK_CSARG_ATTR(writeonly)
5875 }
5876};
5877
5878/// Memory behavior attribute for a call site return position.
5879struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
5880 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
5881 : AAMemoryBehaviorFloating(IRP) {}
5882
5883 /// See AbstractAttribute::manifest(...).
5884 ChangeStatus manifest(Attributor &A) override {
5885 // We do not annotate returned values.
5886 return ChangeStatus::UNCHANGED;
5887 }
5888
5889 /// See AbstractAttribute::trackStatistics()
5890 void trackStatistics() const override {}
5891};
5892
5893/// An AA to represent the memory behavior function attributes.
5894struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
5895 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5896
5897 /// See AbstractAttribute::updateImpl(Attributor &A).
5898 virtual ChangeStatus updateImpl(Attributor &A) override;
5899
5900 /// See AbstractAttribute::manifest(...).
5901 ChangeStatus manifest(Attributor &A) override {
5902 Function &F = cast<Function>(getAnchorValue());
5903 if (isAssumedReadNone()) {
5904 F.removeFnAttr(Attribute::ArgMemOnly);
5905 F.removeFnAttr(Attribute::InaccessibleMemOnly);
5906 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
5907 }
5908 return AAMemoryBehaviorImpl::manifest(A);
5909 }
5910
5911 /// See AbstractAttribute::trackStatistics()
5912 void trackStatistics() const override {
5913 if (isAssumedReadNone())
5914 STATS_DECLTRACK_FN_ATTR(readnone)
5915 else if (isAssumedReadOnly())
5916 STATS_DECLTRACK_FN_ATTR(readonly)
5917 else if (isAssumedWriteOnly())
5918 STATS_DECLTRACK_FN_ATTR(writeonly)
5919 }
5920};
5921
5922/// AAMemoryBehavior attribute for call sites.
5923struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
5924 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5925
5926 /// See AbstractAttribute::initialize(...).
5927 void initialize(Attributor &A) override {
5928 AAMemoryBehaviorImpl::initialize(A);
5929 Function *F = getAssociatedFunction();
5930 if (!F || !F->hasExactDefinition())
5931 indicatePessimisticFixpoint();
5932 }
5933
5934 /// See AbstractAttribute::updateImpl(...).
5935 ChangeStatus updateImpl(Attributor &A) override {
5936 // TODO: Once we have call site specific value information we can provide
5937 // call site specific liveness liveness information and then it makes
5938 // sense to specialize attributes for call sites arguments instead of
5939 // redirecting requests to the callee argument.
5940 Function *F = getAssociatedFunction();
5941 const IRPosition &FnPos = IRPosition::function(*F);
5942 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
5943 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05005944 getState(),
5945 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005946 }
5947
5948 /// See AbstractAttribute::trackStatistics()
5949 void trackStatistics() const override {
5950 if (isAssumedReadNone())
5951 STATS_DECLTRACK_CS_ATTR(readnone)
5952 else if (isAssumedReadOnly())
5953 STATS_DECLTRACK_CS_ATTR(readonly)
5954 else if (isAssumedWriteOnly())
5955 STATS_DECLTRACK_CS_ATTR(writeonly)
5956 }
5957};
5958
5959ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
5960
5961 // The current assumed state used to determine a change.
5962 auto AssumedState = getAssumed();
5963
5964 auto CheckRWInst = [&](Instruction &I) {
5965 // If the instruction has an own memory behavior state, use it to restrict
5966 // the local state. No further analysis is required as the other memory
5967 // state is as optimistic as it gets.
5968 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
5969 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
5970 *this, IRPosition::callsite_function(ICS));
5971 intersectAssumedBits(MemBehaviorAA.getAssumed());
5972 return !isAtFixpoint();
5973 }
5974
5975 // Remove access kind modifiers if necessary.
5976 if (I.mayReadFromMemory())
5977 removeAssumedBits(NO_READS);
5978 if (I.mayWriteToMemory())
5979 removeAssumedBits(NO_WRITES);
5980 return !isAtFixpoint();
5981 };
5982
5983 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
5984 return indicatePessimisticFixpoint();
5985
5986 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5987 : ChangeStatus::UNCHANGED;
5988}
5989
5990ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
5991
5992 const IRPosition &IRP = getIRPosition();
5993 const IRPosition &FnPos = IRPosition::function_scope(IRP);
5994 AAMemoryBehavior::StateType &S = getState();
5995
5996 // First, check the function scope. We take the known information and we avoid
5997 // work if the assumed information implies the current assumed information for
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005998 // this attribute. This is a valid for all but byval arguments.
5999 Argument *Arg = IRP.getAssociatedArgument();
6000 AAMemoryBehavior::base_t FnMemAssumedState =
6001 AAMemoryBehavior::StateType::getWorstState();
6002 if (!Arg || !Arg->hasByValAttr()) {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06006003 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(
6004 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06006005 FnMemAssumedState = FnMemAA.getAssumed();
6006 S.addKnownBits(FnMemAA.getKnown());
6007 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
6008 return ChangeStatus::UNCHANGED;
6009 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006010
6011 // Make sure the value is not captured (except through "return"), if
6012 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00006013 // check the potential aliases introduced by the capture. However, no need
6014 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert28880192019-12-31 00:57:00 -06006015 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
6016 *this, IRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00006017 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06006018 S.intersectAssumedBits(FnMemAssumedState);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00006019 return ChangeStatus::CHANGED;
6020 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006021
6022 // The current assumed state used to determine a change.
6023 auto AssumedState = S.getAssumed();
6024
6025 // Liveness information to exclude dead users.
6026 // TODO: Take the FnPos once we have call site specific liveness information.
6027 const auto &LivenessAA = A.getAAFor<AAIsDead>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06006028 *this, IRPosition::function(*IRP.getAssociatedFunction()),
6029 /* TrackDependence */ false);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006030
6031 // Visit and expand uses until all are analyzed or a fixpoint is reached.
6032 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
6033 const Use *U = Uses[i];
6034 Instruction *UserI = cast<Instruction>(U->getUser());
6035 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
Johannes Doerfert23f41f12020-01-12 01:09:22 -06006036 << " [Dead: " << (A.isAssumedDead(*U, this, &LivenessAA))
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006037 << "]\n");
Johannes Doerfert23f41f12020-01-12 01:09:22 -06006038 if (A.isAssumedDead(*U, this, &LivenessAA))
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006039 continue;
6040
6041 // Check if the users of UserI should also be visited.
6042 if (followUsersOfUseIn(A, U, UserI))
6043 for (const Use &UserIUse : UserI->uses())
6044 Uses.insert(&UserIUse);
6045
6046 // If UserI might touch memory we analyze the use in detail.
6047 if (UserI->mayReadOrWriteMemory())
6048 analyzeUseIn(A, U, UserI);
6049 }
6050
6051 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
6052 : ChangeStatus::UNCHANGED;
6053}
6054
6055bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
6056 const Instruction *UserI) {
6057 // The loaded value is unrelated to the pointer argument, no need to
6058 // follow the users of the load.
6059 if (isa<LoadInst>(UserI))
6060 return false;
6061
6062 // By default we follow all uses assuming UserI might leak information on U,
6063 // we have special handling for call sites operands though.
6064 ImmutableCallSite ICS(UserI);
6065 if (!ICS || !ICS.isArgOperand(U))
6066 return true;
6067
6068 // If the use is a call argument known not to be captured, the users of
6069 // the call do not need to be visited because they have to be unrelated to
6070 // the input. Note that this check is not trivial even though we disallow
6071 // general capturing of the underlying argument. The reason is that the
6072 // call might the argument "through return", which we allow and for which we
6073 // need to check call users.
Johannes Doerfertff6254d2020-01-10 12:32:24 -06006074 if (U->get()->getType()->isPointerTy()) {
6075 unsigned ArgNo = ICS.getArgumentNo(U);
6076 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06006077 *this, IRPosition::callsite_argument(ICS, ArgNo),
6078 /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfertff6254d2020-01-10 12:32:24 -06006079 return !ArgNoCaptureAA.isAssumedNoCapture();
6080 }
6081
6082 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006083}
6084
6085void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
6086 const Instruction *UserI) {
6087 assert(UserI->mayReadOrWriteMemory());
6088
6089 switch (UserI->getOpcode()) {
6090 default:
6091 // TODO: Handle all atomics and other side-effect operations we know of.
6092 break;
6093 case Instruction::Load:
6094 // Loads cause the NO_READS property to disappear.
6095 removeAssumedBits(NO_READS);
6096 return;
6097
6098 case Instruction::Store:
6099 // Stores cause the NO_WRITES property to disappear if the use is the
6100 // pointer operand. Note that we do assume that capturing was taken care of
6101 // somewhere else.
6102 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
6103 removeAssumedBits(NO_WRITES);
6104 return;
6105
6106 case Instruction::Call:
6107 case Instruction::CallBr:
6108 case Instruction::Invoke: {
6109 // For call sites we look at the argument memory behavior attribute (this
6110 // could be recursive!) in order to restrict our own state.
6111 ImmutableCallSite ICS(UserI);
6112
6113 // Give up on operand bundles.
6114 if (ICS.isBundleOperand(U)) {
6115 indicatePessimisticFixpoint();
6116 return;
6117 }
6118
6119 // Calling a function does read the function pointer, maybe write it if the
6120 // function is self-modifying.
6121 if (ICS.isCallee(U)) {
6122 removeAssumedBits(NO_READS);
6123 break;
6124 }
6125
6126 // Adjust the possible access behavior based on the information on the
6127 // argument.
Johannes Doerfertff6254d2020-01-10 12:32:24 -06006128 IRPosition Pos;
6129 if (U->get()->getType()->isPointerTy())
6130 Pos = IRPosition::callsite_argument(ICS, ICS.getArgumentNo(U));
6131 else
6132 Pos = IRPosition::callsite_function(ICS);
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06006133 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
6134 *this, Pos,
6135 /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006136 // "assumed" has at most the same bits as the MemBehaviorAA assumed
6137 // and at least "known".
6138 intersectAssumedBits(MemBehaviorAA.getAssumed());
6139 return;
6140 }
6141 };
6142
6143 // Generally, look at the "may-properties" and adjust the assumed state if we
6144 // did not trigger special handling before.
6145 if (UserI->mayReadFromMemory())
6146 removeAssumedBits(NO_READS);
6147 if (UserI->mayWriteToMemory())
6148 removeAssumedBits(NO_WRITES);
6149}
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006150
Benjamin Kramer564a9de2020-02-17 17:55:03 +01006151} // namespace
6152
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006153/// -------------------- Memory Locations Attributes ---------------------------
6154/// Includes read-none, argmemonly, inaccessiblememonly,
6155/// inaccessiblememorargmemonly
6156/// ----------------------------------------------------------------------------
6157
6158std::string AAMemoryLocation::getMemoryLocationsAsStr(
6159 AAMemoryLocation::MemoryLocationsKind MLK) {
6160 if (0 == (MLK & AAMemoryLocation::NO_LOCATIONS))
6161 return "all memory";
6162 if (MLK == AAMemoryLocation::NO_LOCATIONS)
6163 return "no memory";
6164 std::string S = "memory:";
6165 if (0 == (MLK & AAMemoryLocation::NO_LOCAL_MEM))
6166 S += "stack,";
6167 if (0 == (MLK & AAMemoryLocation::NO_CONST_MEM))
6168 S += "constant,";
6169 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_INTERNAL_MEM))
6170 S += "internal global,";
6171 if (0 == (MLK & AAMemoryLocation::NO_GLOBAL_EXTERNAL_MEM))
6172 S += "external global,";
6173 if (0 == (MLK & AAMemoryLocation::NO_ARGUMENT_MEM))
6174 S += "argument,";
6175 if (0 == (MLK & AAMemoryLocation::NO_INACCESSIBLE_MEM))
6176 S += "inaccessible,";
6177 if (0 == (MLK & AAMemoryLocation::NO_MALLOCED_MEM))
6178 S += "malloced,";
6179 if (0 == (MLK & AAMemoryLocation::NO_UNKOWN_MEM))
6180 S += "unknown,";
6181 S.pop_back();
6182 return S;
6183}
6184
Benjamin Kramer564a9de2020-02-17 17:55:03 +01006185namespace {
6186
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006187struct AAMemoryLocationImpl : public AAMemoryLocation {
6188
6189 AAMemoryLocationImpl(const IRPosition &IRP) : AAMemoryLocation(IRP) {}
6190
6191 /// See AbstractAttribute::initialize(...).
6192 void initialize(Attributor &A) override {
6193 intersectAssumedBits(BEST_STATE);
6194 getKnownStateFromValue(getIRPosition(), getState());
6195 IRAttribute::initialize(A);
6196 }
6197
6198 /// Return the memory behavior information encoded in the IR for \p IRP.
6199 static void getKnownStateFromValue(const IRPosition &IRP,
6200 BitIntegerState &State,
6201 bool IgnoreSubsumingPositions = false) {
6202 SmallVector<Attribute, 2> Attrs;
6203 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
6204 for (const Attribute &Attr : Attrs) {
6205 switch (Attr.getKindAsEnum()) {
6206 case Attribute::ReadNone:
6207 State.addKnownBits(NO_LOCAL_MEM | NO_CONST_MEM);
6208 break;
6209 case Attribute::InaccessibleMemOnly:
6210 State.addKnownBits(inverseLocation(NO_INACCESSIBLE_MEM, true, true));
6211 break;
6212 case Attribute::ArgMemOnly:
6213 State.addKnownBits(inverseLocation(NO_ARGUMENT_MEM, true, true));
6214 break;
6215 case Attribute::InaccessibleMemOrArgMemOnly:
6216 State.addKnownBits(
6217 inverseLocation(NO_INACCESSIBLE_MEM | NO_ARGUMENT_MEM, true, true));
6218 break;
6219 default:
6220 llvm_unreachable("Unexpected attribute!");
6221 }
6222 }
6223 }
6224
6225 /// See AbstractAttribute::getDeducedAttributes(...).
6226 void getDeducedAttributes(LLVMContext &Ctx,
6227 SmallVectorImpl<Attribute> &Attrs) const override {
6228 assert(Attrs.size() == 0);
6229 if (isAssumedReadNone()) {
6230 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
6231 } else if (getIRPosition().getPositionKind() == IRPosition::IRP_FUNCTION) {
6232 if (isAssumedInaccessibleMemOnly())
6233 Attrs.push_back(Attribute::get(Ctx, Attribute::InaccessibleMemOnly));
6234 else if (isAssumedArgMemOnly())
6235 Attrs.push_back(Attribute::get(Ctx, Attribute::ArgMemOnly));
6236 else if (isAssumedInaccessibleOrArgMemOnly())
6237 Attrs.push_back(
6238 Attribute::get(Ctx, Attribute::InaccessibleMemOrArgMemOnly));
6239 }
6240 assert(Attrs.size() <= 1);
6241 }
6242
6243 /// See AbstractAttribute::manifest(...).
6244 ChangeStatus manifest(Attributor &A) override {
6245 const IRPosition &IRP = getIRPosition();
6246
6247 // Check if we would improve the existing attributes first.
6248 SmallVector<Attribute, 4> DeducedAttrs;
6249 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
6250 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
6251 return IRP.hasAttr(Attr.getKindAsEnum(),
6252 /* IgnoreSubsumingPositions */ true);
6253 }))
6254 return ChangeStatus::UNCHANGED;
6255
6256 // Clear existing attributes.
6257 IRP.removeAttrs(AttrKinds);
6258 if (isAssumedReadNone())
6259 IRP.removeAttrs(AAMemoryBehaviorImpl::AttrKinds);
6260
6261 // Use the generic manifest method.
6262 return IRAttribute::manifest(A);
6263 }
6264
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006265 /// See AAMemoryLocation::checkForAllAccessesToMemoryKind(...).
6266 bool checkForAllAccessesToMemoryKind(
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006267 const function_ref<bool(const Instruction *, const Value *, AccessKind,
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006268 MemoryLocationsKind)> &Pred,
6269 MemoryLocationsKind RequestedMLK) const override {
6270 if (!isValidState())
6271 return false;
6272
6273 MemoryLocationsKind AssumedMLK = getAssumedNotAccessedLocation();
6274 if (AssumedMLK == NO_LOCATIONS)
6275 return true;
6276
6277 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
6278 if (CurMLK & RequestedMLK)
6279 continue;
6280
6281 const auto &Accesses = AccessKindAccessesMap.lookup(CurMLK);
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006282 for (const AccessInfo &AI : Accesses) {
6283 if (!Pred(AI.I, AI.Ptr, AI.Kind, CurMLK))
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006284 return false;
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006285 }
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006286 }
6287
6288 return true;
6289 }
6290
6291 ChangeStatus indicatePessimisticFixpoint() override {
6292 // If we give up and indicate a pessimistic fixpoint this instruction will
6293 // become an access for all potential access kinds:
6294 // TODO: Add pointers for argmemonly and globals to improve the results of
6295 // checkForAllAccessesToMemoryKind.
6296 bool Changed = false;
6297 MemoryLocationsKind KnownMLK = getKnown();
6298 Instruction *I = dyn_cast<Instruction>(&getAssociatedValue());
6299 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2)
6300 if (!(CurMLK & KnownMLK))
6301 updateStateAndAccessesMap(getState(), AccessKindAccessesMap, CurMLK, I,
6302 nullptr, Changed);
6303 return AAMemoryLocation::indicatePessimisticFixpoint();
6304 }
6305
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006306protected:
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006307 /// Helper struct to tie together an instruction that has a read or write
6308 /// effect with the pointer it accesses (if any).
6309 struct AccessInfo {
6310
6311 /// The instruction that caused the access.
6312 const Instruction *I;
6313
6314 /// The base pointer that is accessed, or null if unknown.
6315 const Value *Ptr;
6316
6317 /// The kind of access (read/write/read+write).
6318 AccessKind Kind;
6319
6320 bool operator==(const AccessInfo &RHS) const {
Simon Pilgrim8a48c4a2020-02-15 13:53:18 +00006321 return I == RHS.I && Ptr == RHS.Ptr && Kind == RHS.Kind;
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006322 }
6323 bool operator()(const AccessInfo &LHS, const AccessInfo &RHS) const {
6324 if (LHS.I != RHS.I)
6325 return LHS.I < RHS.I;
6326 if (LHS.Ptr != RHS.Ptr)
6327 return LHS.Ptr < RHS.Ptr;
6328 if (LHS.Kind != RHS.Kind)
6329 return LHS.Kind < RHS.Kind;
6330 return false;
6331 }
6332 };
6333
6334 /// Mapping from *single* memory location kinds, e.g., LOCAL_MEM with the
6335 /// value of NO_LOCAL_MEM, to the accesses encountered for this memory kind.
6336 using AccessKindAccessesMapTy =
6337 DenseMap<unsigned, SmallSet<AccessInfo, 8, AccessInfo>>;
6338 AccessKindAccessesMapTy AccessKindAccessesMap;
6339
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006340 /// Return the kind(s) of location that may be accessed by \p V.
6341 AAMemoryLocation::MemoryLocationsKind
6342 categorizeAccessedLocations(Attributor &A, Instruction &I, bool &Changed);
6343
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006344 /// Update the state \p State and the AccessKindAccessesMap given that \p I is
6345 /// an access to a \p MLK memory location with the access pointer \p Ptr.
6346 static void updateStateAndAccessesMap(AAMemoryLocation::StateType &State,
6347 AccessKindAccessesMapTy &AccessMap,
6348 MemoryLocationsKind MLK,
6349 const Instruction *I, const Value *Ptr,
6350 bool &Changed) {
6351 // TODO: The kind should be determined at the call sites based on the
6352 // information we have there.
6353 AccessKind Kind = READ_WRITE;
6354 if (I) {
6355 Kind = I->mayReadFromMemory() ? READ : NONE;
6356 Kind = AccessKind(Kind | (I->mayWriteToMemory() ? WRITE : NONE));
6357 }
6358
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006359 assert(isPowerOf2_32(MLK) && "Expected a single location set!");
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006360 Changed |= AccessMap[MLK].insert(AccessInfo{I, Ptr, Kind}).second;
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006361 State.removeAssumedBits(MLK);
6362 }
6363
6364 /// Determine the underlying locations kinds for \p Ptr, e.g., globals or
6365 /// arguments, and update the state and access map accordingly.
6366 void categorizePtrValue(Attributor &A, const Instruction &I, const Value &Ptr,
6367 AAMemoryLocation::StateType &State, bool &Changed);
6368
6369 /// The set of IR attributes AAMemoryLocation deals with.
6370 static const Attribute::AttrKind AttrKinds[4];
6371};
6372
6373const Attribute::AttrKind AAMemoryLocationImpl::AttrKinds[] = {
6374 Attribute::ReadNone, Attribute::InaccessibleMemOnly, Attribute::ArgMemOnly,
6375 Attribute::InaccessibleMemOrArgMemOnly};
6376
6377void AAMemoryLocationImpl::categorizePtrValue(
6378 Attributor &A, const Instruction &I, const Value &Ptr,
6379 AAMemoryLocation::StateType &State, bool &Changed) {
6380 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize pointer locations for "
6381 << Ptr << " ["
6382 << getMemoryLocationsAsStr(State.getAssumed()) << "]\n");
6383
6384 auto StripGEPCB = [](Value *V) -> Value * {
6385 auto *GEP = dyn_cast<GEPOperator>(V);
6386 while (GEP) {
6387 V = GEP->getPointerOperand();
6388 GEP = dyn_cast<GEPOperator>(V);
6389 }
6390 return V;
6391 };
6392
6393 auto VisitValueCB = [&](Value &V, AAMemoryLocation::StateType &T,
6394 bool Stripped) -> bool {
6395 assert(!isa<GEPOperator>(V) && "GEPs should have been stripped.");
6396 if (isa<UndefValue>(V))
6397 return true;
6398 if (auto *Arg = dyn_cast<Argument>(&V)) {
6399 if (Arg->hasByValAttr())
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006400 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_LOCAL_MEM, &I,
6401 &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006402 else
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006403 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_ARGUMENT_MEM, &I,
6404 &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006405 return true;
6406 }
6407 if (auto *GV = dyn_cast<GlobalValue>(&V)) {
6408 if (GV->hasLocalLinkage())
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006409 updateStateAndAccessesMap(T, AccessKindAccessesMap,
6410 NO_GLOBAL_INTERNAL_MEM, &I, &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006411 else
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006412 updateStateAndAccessesMap(T, AccessKindAccessesMap,
6413 NO_GLOBAL_EXTERNAL_MEM, &I, &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006414 return true;
6415 }
6416 if (isa<AllocaInst>(V)) {
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006417 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_LOCAL_MEM, &I, &V,
6418 Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006419 return true;
6420 }
6421 if (ImmutableCallSite ICS = ImmutableCallSite(&V)) {
6422 const auto &NoAliasAA =
6423 A.getAAFor<AANoAlias>(*this, IRPosition::callsite_returned(ICS));
6424 if (NoAliasAA.isAssumedNoAlias()) {
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006425 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_MALLOCED_MEM, &I,
6426 &V, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006427 return true;
6428 }
6429 }
6430
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006431 updateStateAndAccessesMap(T, AccessKindAccessesMap, NO_UNKOWN_MEM, &I, &V,
6432 Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006433 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Ptr value cannot be categorized: "
6434 << V << " -> " << getMemoryLocationsAsStr(T.getAssumed())
6435 << "\n");
6436 return true;
6437 };
6438
6439 if (!genericValueTraversal<AAMemoryLocation, AAMemoryLocation::StateType>(
6440 A, IRPosition::value(Ptr), *this, State, VisitValueCB,
6441 /* MaxValues */ 32, StripGEPCB)) {
6442 LLVM_DEBUG(
6443 dbgs() << "[AAMemoryLocation] Pointer locations not categorized\n");
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006444 updateStateAndAccessesMap(State, AccessKindAccessesMap, NO_UNKOWN_MEM, &I,
6445 nullptr, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006446 } else {
6447 LLVM_DEBUG(
6448 dbgs()
6449 << "[AAMemoryLocation] Accessed locations with pointer locations: "
6450 << getMemoryLocationsAsStr(State.getAssumed()) << "\n");
6451 }
6452}
6453
6454AAMemoryLocation::MemoryLocationsKind
6455AAMemoryLocationImpl::categorizeAccessedLocations(Attributor &A, Instruction &I,
6456 bool &Changed) {
6457 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize accessed locations for "
6458 << I << "\n");
6459
6460 AAMemoryLocation::StateType AccessedLocs;
6461 AccessedLocs.intersectAssumedBits(NO_LOCATIONS);
6462
6463 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
6464
6465 // First check if we assume any memory is access is visible.
6466 const auto &ICSMemLocationAA =
6467 A.getAAFor<AAMemoryLocation>(*this, IRPosition::callsite_function(ICS));
6468 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Categorize call site: " << I
6469 << " [" << ICSMemLocationAA << "]\n");
6470
6471 if (ICSMemLocationAA.isAssumedReadNone())
6472 return NO_LOCATIONS;
6473
6474 if (ICSMemLocationAA.isAssumedInaccessibleMemOnly()) {
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006475 updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap,
6476 NO_INACCESSIBLE_MEM, &I, nullptr, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006477 return AccessedLocs.getAssumed();
6478 }
6479
6480 uint32_t ICSAssumedNotAccessedLocs =
6481 ICSMemLocationAA.getAssumedNotAccessedLocation();
6482
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006483 // Set the argmemonly and global bit as we handle them separately below.
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006484 uint32_t ICSAssumedNotAccessedLocsNoArgMem =
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006485 ICSAssumedNotAccessedLocs | NO_ARGUMENT_MEM | NO_GLOBAL_MEM;
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006486
6487 for (MemoryLocationsKind CurMLK = 1; CurMLK < NO_LOCATIONS; CurMLK *= 2) {
6488 if (ICSAssumedNotAccessedLocsNoArgMem & CurMLK)
6489 continue;
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006490 updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap, CurMLK, &I,
6491 nullptr, Changed);
6492 }
6493
6494 // Now handle global memory if it might be accessed.
6495 bool HasGlobalAccesses = !(ICSAssumedNotAccessedLocs & NO_GLOBAL_MEM);
6496 if (HasGlobalAccesses) {
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006497 auto AccessPred = [&](const Instruction *, const Value *Ptr,
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006498 AccessKind Kind, MemoryLocationsKind MLK) {
6499 updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap, MLK, &I,
6500 Ptr, Changed);
6501 return true;
6502 };
6503 if (!ICSMemLocationAA.checkForAllAccessesToMemoryKind(
6504 AccessPred, inverseLocation(NO_GLOBAL_MEM, false, false)))
6505 return AccessedLocs.getWorstState();
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006506 }
6507
6508 LLVM_DEBUG(
6509 dbgs() << "[AAMemoryLocation] Accessed state before argument handling: "
6510 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
6511
6512 // Now handle argument memory if it might be accessed.
6513 bool HasArgAccesses = !(ICSAssumedNotAccessedLocs & NO_ARGUMENT_MEM);
6514 if (HasArgAccesses) {
6515 for (unsigned ArgNo = 0, e = ICS.getNumArgOperands(); ArgNo < e;
6516 ++ArgNo) {
6517
6518 // Skip non-pointer arguments.
6519 const Value *ArgOp = ICS.getArgOperand(ArgNo);
6520 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
6521 continue;
6522
6523 // Skip readnone arguments.
6524 const IRPosition &ArgOpIRP = IRPosition::callsite_argument(ICS, ArgNo);
6525 const auto &ArgOpMemLocationAA = A.getAAFor<AAMemoryBehavior>(
6526 *this, ArgOpIRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
6527
6528 if (ArgOpMemLocationAA.isAssumedReadNone())
6529 continue;
6530
6531 // Categorize potentially accessed pointer arguments as if there was an
6532 // access instruction with them as pointer.
6533 categorizePtrValue(A, I, *ArgOp, AccessedLocs, Changed);
6534 }
6535 }
6536
6537 LLVM_DEBUG(
6538 dbgs() << "[AAMemoryLocation] Accessed state after argument handling: "
6539 << getMemoryLocationsAsStr(AccessedLocs.getAssumed()) << "\n");
6540
6541 return AccessedLocs.getAssumed();
6542 }
6543
6544 if (const Value *Ptr = getPointerOperand(&I, /* AllowVolatile */ true)) {
6545 LLVM_DEBUG(
6546 dbgs() << "[AAMemoryLocation] Categorize memory access with pointer: "
6547 << I << " [" << *Ptr << "]\n");
6548 categorizePtrValue(A, I, *Ptr, AccessedLocs, Changed);
6549 return AccessedLocs.getAssumed();
6550 }
6551
6552 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Failed to categorize instruction: "
6553 << I << "\n");
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006554 updateStateAndAccessesMap(AccessedLocs, AccessKindAccessesMap, NO_UNKOWN_MEM,
6555 &I, nullptr, Changed);
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006556 return AccessedLocs.getAssumed();
6557}
6558
6559/// An AA to represent the memory behavior function attributes.
6560struct AAMemoryLocationFunction final : public AAMemoryLocationImpl {
6561 AAMemoryLocationFunction(const IRPosition &IRP) : AAMemoryLocationImpl(IRP) {}
6562
6563 /// See AbstractAttribute::updateImpl(Attributor &A).
6564 virtual ChangeStatus updateImpl(Attributor &A) override {
6565
6566 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
6567 *this, getIRPosition(), /* TrackDependence */ false);
6568 if (MemBehaviorAA.isAssumedReadNone()) {
6569 if (MemBehaviorAA.isKnownReadNone())
6570 return indicateOptimisticFixpoint();
6571 assert(isAssumedReadNone() &&
6572 "AAMemoryLocation was not read-none but AAMemoryBehavior was!");
6573 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
6574 return ChangeStatus::UNCHANGED;
6575 }
6576
6577 // The current assumed state used to determine a change.
6578 auto AssumedState = getAssumed();
6579 bool Changed = false;
6580
6581 auto CheckRWInst = [&](Instruction &I) {
6582 MemoryLocationsKind MLK = categorizeAccessedLocations(A, I, Changed);
6583 LLVM_DEBUG(dbgs() << "[AAMemoryLocation] Accessed locations for " << I
6584 << ": " << getMemoryLocationsAsStr(MLK) << "\n");
6585 removeAssumedBits(inverseLocation(MLK, false, false));
6586 return true;
6587 };
6588
6589 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
6590 return indicatePessimisticFixpoint();
6591
6592 Changed |= AssumedState != getAssumed();
6593 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
6594 }
6595
6596 /// See AbstractAttribute::trackStatistics()
6597 void trackStatistics() const override {
6598 if (isAssumedReadNone())
6599 STATS_DECLTRACK_FN_ATTR(readnone)
6600 else if (isAssumedArgMemOnly())
6601 STATS_DECLTRACK_FN_ATTR(argmemonly)
6602 else if (isAssumedInaccessibleMemOnly())
6603 STATS_DECLTRACK_FN_ATTR(inaccessiblememonly)
6604 else if (isAssumedInaccessibleOrArgMemOnly())
6605 STATS_DECLTRACK_FN_ATTR(inaccessiblememorargmemonly)
6606 }
6607};
6608
6609/// AAMemoryLocation attribute for call sites.
6610struct AAMemoryLocationCallSite final : AAMemoryLocationImpl {
6611 AAMemoryLocationCallSite(const IRPosition &IRP) : AAMemoryLocationImpl(IRP) {}
6612
6613 /// See AbstractAttribute::initialize(...).
6614 void initialize(Attributor &A) override {
6615 AAMemoryLocationImpl::initialize(A);
6616 Function *F = getAssociatedFunction();
6617 if (!F || !F->hasExactDefinition())
6618 indicatePessimisticFixpoint();
6619 }
6620
6621 /// See AbstractAttribute::updateImpl(...).
6622 ChangeStatus updateImpl(Attributor &A) override {
6623 // TODO: Once we have call site specific value information we can provide
6624 // call site specific liveness liveness information and then it makes
6625 // sense to specialize attributes for call sites arguments instead of
6626 // redirecting requests to the callee argument.
6627 Function *F = getAssociatedFunction();
6628 const IRPosition &FnPos = IRPosition::function(*F);
6629 auto &FnAA = A.getAAFor<AAMemoryLocation>(*this, FnPos);
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006630 bool Changed = false;
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006631 auto AccessPred = [&](const Instruction *I, const Value *Ptr,
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006632 AccessKind Kind, MemoryLocationsKind MLK) {
Johannes Doerfert1d5da8c2020-02-15 20:38:49 -06006633 updateStateAndAccessesMap(getState(), AccessKindAccessesMap, MLK, I, Ptr,
Johannes Doerfertef746aa2020-01-27 22:49:36 -06006634 Changed);
6635 return true;
6636 };
6637 if (!FnAA.checkForAllAccessesToMemoryKind(AccessPred, ALL_LOCATIONS))
6638 return indicatePessimisticFixpoint();
6639 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfert282f5d72020-01-26 02:51:57 -06006640 }
6641
6642 /// See AbstractAttribute::trackStatistics()
6643 void trackStatistics() const override {
6644 if (isAssumedReadNone())
6645 STATS_DECLTRACK_CS_ATTR(readnone)
6646 }
6647};
6648
Hideto Ueno188f9a32020-01-15 15:25:52 +09006649/// ------------------ Value Constant Range Attribute -------------------------
Hideto Uenoe9963032020-01-01 15:25:19 +09006650
Hideto Ueno188f9a32020-01-15 15:25:52 +09006651struct AAValueConstantRangeImpl : AAValueConstantRange {
6652 using StateType = IntegerRangeState;
6653 AAValueConstantRangeImpl(const IRPosition &IRP) : AAValueConstantRange(IRP) {}
6654
6655 /// See AbstractAttribute::getAsStr().
6656 const std::string getAsStr() const override {
6657 std::string Str;
6658 llvm::raw_string_ostream OS(Str);
6659 OS << "range(" << getBitWidth() << ")<";
6660 getKnown().print(OS);
6661 OS << " / ";
6662 getAssumed().print(OS);
6663 OS << ">";
6664 return OS.str();
6665 }
6666
6667 /// Helper function to get a SCEV expr for the associated value at program
6668 /// point \p I.
6669 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
6670 if (!getAnchorScope())
6671 return nullptr;
6672
6673 ScalarEvolution *SE =
6674 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
6675 *getAnchorScope());
6676
6677 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
6678 *getAnchorScope());
6679
6680 if (!SE || !LI)
6681 return nullptr;
6682
6683 const SCEV *S = SE->getSCEV(&getAssociatedValue());
6684 if (!I)
6685 return S;
6686
6687 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
6688 }
6689
6690 /// Helper function to get a range from SCEV for the associated value at
6691 /// program point \p I.
6692 ConstantRange getConstantRangeFromSCEV(Attributor &A,
6693 const Instruction *I = nullptr) const {
6694 if (!getAnchorScope())
6695 return getWorstState(getBitWidth());
6696
6697 ScalarEvolution *SE =
6698 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
6699 *getAnchorScope());
6700
6701 const SCEV *S = getSCEV(A, I);
6702 if (!SE || !S)
6703 return getWorstState(getBitWidth());
6704
6705 return SE->getUnsignedRange(S);
6706 }
6707
6708 /// Helper function to get a range from LVI for the associated value at
6709 /// program point \p I.
6710 ConstantRange
6711 getConstantRangeFromLVI(Attributor &A,
6712 const Instruction *CtxI = nullptr) const {
6713 if (!getAnchorScope())
6714 return getWorstState(getBitWidth());
6715
6716 LazyValueInfo *LVI =
6717 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
6718 *getAnchorScope());
6719
6720 if (!LVI || !CtxI)
6721 return getWorstState(getBitWidth());
6722 return LVI->getConstantRange(&getAssociatedValue(),
6723 const_cast<BasicBlock *>(CtxI->getParent()),
6724 const_cast<Instruction *>(CtxI));
6725 }
6726
6727 /// See AAValueConstantRange::getKnownConstantRange(..).
6728 ConstantRange
6729 getKnownConstantRange(Attributor &A,
6730 const Instruction *CtxI = nullptr) const override {
6731 if (!CtxI || CtxI == getCtxI())
6732 return getKnown();
6733
6734 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
6735 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
6736 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
6737 }
6738
6739 /// See AAValueConstantRange::getAssumedConstantRange(..).
6740 ConstantRange
6741 getAssumedConstantRange(Attributor &A,
6742 const Instruction *CtxI = nullptr) const override {
6743 // TODO: Make SCEV use Attributor assumption.
6744 // We may be able to bound a variable range via assumptions in
6745 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
6746 // evolve to x^2 + x, then we can say that y is in [2, 12].
6747
6748 if (!CtxI || CtxI == getCtxI())
6749 return getAssumed();
6750
6751 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
6752 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
6753 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
6754 }
6755
6756 /// See AbstractAttribute::initialize(..).
6757 void initialize(Attributor &A) override {
6758 // Intersect a range given by SCEV.
6759 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
6760
6761 // Intersect a range given by LVI.
6762 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
6763 }
6764
6765 /// Helper function to create MDNode for range metadata.
6766 static MDNode *
6767 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
6768 const ConstantRange &AssumedConstantRange) {
6769 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
6770 Ty, AssumedConstantRange.getLower())),
6771 ConstantAsMetadata::get(ConstantInt::get(
6772 Ty, AssumedConstantRange.getUpper()))};
6773 return MDNode::get(Ctx, LowAndHigh);
6774 }
6775
6776 /// Return true if \p Assumed is included in \p KnownRanges.
6777 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) {
6778
6779 if (Assumed.isFullSet())
6780 return false;
6781
6782 if (!KnownRanges)
6783 return true;
6784
6785 // If multiple ranges are annotated in IR, we give up to annotate assumed
6786 // range for now.
6787
6788 // TODO: If there exists a known range which containts assumed range, we
6789 // can say assumed range is better.
6790 if (KnownRanges->getNumOperands() > 2)
6791 return false;
6792
6793 ConstantInt *Lower =
6794 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
6795 ConstantInt *Upper =
6796 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
6797
6798 ConstantRange Known(Lower->getValue(), Upper->getValue());
6799 return Known.contains(Assumed) && Known != Assumed;
6800 }
6801
6802 /// Helper function to set range metadata.
6803 static bool
6804 setRangeMetadataIfisBetterRange(Instruction *I,
6805 const ConstantRange &AssumedConstantRange) {
6806 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range);
6807 if (isBetterRange(AssumedConstantRange, OldRangeMD)) {
6808 if (!AssumedConstantRange.isEmptySet()) {
6809 I->setMetadata(LLVMContext::MD_range,
6810 getMDNodeForConstantRange(I->getType(), I->getContext(),
6811 AssumedConstantRange));
6812 return true;
6813 }
6814 }
6815 return false;
6816 }
6817
6818 /// See AbstractAttribute::manifest()
6819 ChangeStatus manifest(Attributor &A) override {
6820 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6821 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
6822 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
6823
6824 auto &V = getAssociatedValue();
6825 if (!AssumedConstantRange.isEmptySet() &&
6826 !AssumedConstantRange.isSingleElement()) {
6827 if (Instruction *I = dyn_cast<Instruction>(&V))
6828 if (isa<CallInst>(I) || isa<LoadInst>(I))
6829 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
6830 Changed = ChangeStatus::CHANGED;
6831 }
6832
6833 return Changed;
6834 }
6835};
6836
Johannes Doerfertea5fabe2020-01-28 09:46:15 -06006837struct AAValueConstantRangeArgument final
6838 : AAArgumentFromCallSiteArguments<
6839 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState> {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006840 AAValueConstantRangeArgument(const IRPosition &IRP)
Johannes Doerfertea5fabe2020-01-28 09:46:15 -06006841 : AAArgumentFromCallSiteArguments<
6842 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState>(
6843 IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006844
6845 /// See AbstractAttribute::trackStatistics()
6846 void trackStatistics() const override {
6847 STATS_DECLTRACK_ARG_ATTR(value_range)
6848 }
6849};
6850
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006851struct AAValueConstantRangeReturned
6852 : AAReturnedFromReturnedValues<AAValueConstantRange,
6853 AAValueConstantRangeImpl> {
6854 using Base = AAReturnedFromReturnedValues<AAValueConstantRange,
6855 AAValueConstantRangeImpl>;
6856 AAValueConstantRangeReturned(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006857
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006858 /// See AbstractAttribute::initialize(...).
6859 void initialize(Attributor &A) override {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006860
6861 /// See AbstractAttribute::trackStatistics()
6862 void trackStatistics() const override {
6863 STATS_DECLTRACK_FNRET_ATTR(value_range)
6864 }
6865};
6866
6867struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
6868 AAValueConstantRangeFloating(const IRPosition &IRP)
6869 : AAValueConstantRangeImpl(IRP) {}
6870
6871 /// See AbstractAttribute::initialize(...).
6872 void initialize(Attributor &A) override {
Johannes Doerfert028db8c42020-02-09 19:05:15 -06006873 AAValueConstantRangeImpl::initialize(A);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006874 Value &V = getAssociatedValue();
6875
6876 if (auto *C = dyn_cast<ConstantInt>(&V)) {
6877 unionAssumed(ConstantRange(C->getValue()));
6878 indicateOptimisticFixpoint();
6879 return;
6880 }
6881
6882 if (isa<UndefValue>(&V)) {
Johannes Doerfertb53af0e2020-02-14 20:08:20 -06006883 // Collapse the undef state to 0.
6884 unionAssumed(ConstantRange(APInt(getBitWidth(), 0)));
Hideto Ueno188f9a32020-01-15 15:25:52 +09006885 indicateOptimisticFixpoint();
6886 return;
6887 }
6888
Johannes Doerfert7cbb1072020-02-13 14:22:26 -06006889 if (isa<BinaryOperator>(&V) || isa<CmpInst>(&V) || isa<CastInst>(&V))
6890 return;
Hideto Ueno188f9a32020-01-15 15:25:52 +09006891 // If it is a load instruction with range metadata, use it.
6892 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
6893 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
6894 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
6895 return;
6896 }
6897
Johannes Doerfert81554392020-02-09 20:14:35 -06006898 // We can work with PHI and select instruction as we traverse their operands
Johannes Doerfert7e7e6592020-02-09 19:08:04 -06006899 // during update.
Johannes Doerfert81554392020-02-09 20:14:35 -06006900 if (isa<SelectInst>(V) || isa<PHINode>(V))
Johannes Doerfert7e7e6592020-02-09 19:08:04 -06006901 return;
6902
Hideto Ueno188f9a32020-01-15 15:25:52 +09006903 // Otherwise we give up.
6904 indicatePessimisticFixpoint();
6905
Johannes Doerfert02bd8182020-01-28 11:49:35 -06006906 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
6907 << getAssociatedValue() << "\n");
Hideto Ueno188f9a32020-01-15 15:25:52 +09006908 }
6909
Johannes Doerfert81554392020-02-09 20:14:35 -06006910 bool calculateBinaryOperator(
6911 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
6912 Instruction *CtxI,
6913 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006914 Value *LHS = BinOp->getOperand(0);
6915 Value *RHS = BinOp->getOperand(1);
Johannes Doerfert7cbb1072020-02-13 14:22:26 -06006916 // TODO: Allow non integers as well.
6917 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
6918 return false;
Hideto Ueno188f9a32020-01-15 15:25:52 +09006919
6920 auto &LHSAA =
6921 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006922 QuerriedAAs.push_back(&LHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006923 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
6924
6925 auto &RHSAA =
6926 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006927 QuerriedAAs.push_back(&RHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006928 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
6929
6930 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
6931
6932 T.unionAssumed(AssumedRange);
6933
6934 // TODO: Track a known state too.
6935
6936 return T.isValidState();
6937 }
6938
Johannes Doerfert81554392020-02-09 20:14:35 -06006939 bool calculateCastInst(
6940 Attributor &A, CastInst *CastI, IntegerRangeState &T, Instruction *CtxI,
6941 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006942 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
6943 // TODO: Allow non integers as well.
6944 Value &OpV = *CastI->getOperand(0);
Johannes Doerfert7cbb1072020-02-13 14:22:26 -06006945 if (!OpV.getType()->isIntegerTy())
6946 return false;
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006947
6948 auto &OpAA =
6949 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV));
Johannes Doerfert81554392020-02-09 20:14:35 -06006950 QuerriedAAs.push_back(&OpAA);
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006951 T.unionAssumed(
6952 OpAA.getAssumed().castOp(CastI->getOpcode(), getState().getBitWidth()));
6953 return T.isValidState();
6954 }
6955
Johannes Doerfert81554392020-02-09 20:14:35 -06006956 bool
6957 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
6958 Instruction *CtxI,
6959 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006960 Value *LHS = CmpI->getOperand(0);
6961 Value *RHS = CmpI->getOperand(1);
Johannes Doerfert7cbb1072020-02-13 14:22:26 -06006962 // TODO: Allow non integers as well.
6963 if (!LHS->getType()->isIntegerTy() || !RHS->getType()->isIntegerTy())
6964 return false;
Hideto Ueno188f9a32020-01-15 15:25:52 +09006965
6966 auto &LHSAA =
6967 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006968 QuerriedAAs.push_back(&LHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006969 auto &RHSAA =
6970 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006971 QuerriedAAs.push_back(&RHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006972
6973 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
6974 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
6975
6976 // If one of them is empty set, we can't decide.
6977 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
6978 return true;
6979
6980 bool MustTrue = false, MustFalse = false;
6981
6982 auto AllowedRegion =
6983 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange);
6984
6985 auto SatisfyingRegion = ConstantRange::makeSatisfyingICmpRegion(
6986 CmpI->getPredicate(), RHSAARange);
6987
6988 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
6989 MustFalse = true;
6990
6991 if (SatisfyingRegion.contains(LHSAARange))
6992 MustTrue = true;
6993
6994 assert((!MustTrue || !MustFalse) &&
6995 "Either MustTrue or MustFalse should be false!");
6996
6997 if (MustTrue)
6998 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
6999 else if (MustFalse)
7000 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
7001 else
7002 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
7003
7004 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " " << LHSAA
7005 << " " << RHSAA << "\n");
7006
7007 // TODO: Track a known state too.
7008 return T.isValidState();
7009 }
7010
7011 /// See AbstractAttribute::updateImpl(...).
7012 ChangeStatus updateImpl(Attributor &A) override {
7013 Instruction *CtxI = getCtxI();
7014 auto VisitValueCB = [&](Value &V, IntegerRangeState &T,
7015 bool Stripped) -> bool {
7016 Instruction *I = dyn_cast<Instruction>(&V);
7017 if (!I) {
7018
7019 // If the value is not instruction, we query AA to Attributor.
7020 const auto &AA =
7021 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(V));
7022
7023 // Clamp operator is not used to utilize a program point CtxI.
7024 T.unionAssumed(AA.getAssumedConstantRange(A, CtxI));
7025
7026 return T.isValidState();
7027 }
7028
Johannes Doerfert81554392020-02-09 20:14:35 -06007029 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs;
7030 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
7031 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
7032 return false;
7033 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
7034 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
7035 return false;
7036 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
7037 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
7038 return false;
7039 } else {
Hideto Ueno188f9a32020-01-15 15:25:52 +09007040 // Give up with other instructions.
7041 // TODO: Add other instructions
7042
7043 T.indicatePessimisticFixpoint();
7044 return false;
7045 }
Johannes Doerfert81554392020-02-09 20:14:35 -06007046
7047 // Catch circular reasoning in a pessimistic way for now.
7048 // TODO: Check how the range evolves and if we stripped anything, see also
7049 // AADereferenceable or AAAlign for similar situations.
7050 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
7051 if (QueriedAA != this)
7052 continue;
7053 // If we are in a stady state we do not need to worry.
7054 if (T.getAssumed() == getState().getAssumed())
7055 continue;
7056 T.indicatePessimisticFixpoint();
7057 }
7058
7059 return T.isValidState();
Hideto Ueno188f9a32020-01-15 15:25:52 +09007060 };
7061
7062 IntegerRangeState T(getBitWidth());
7063
7064 if (!genericValueTraversal<AAValueConstantRange, IntegerRangeState>(
7065 A, getIRPosition(), *this, T, VisitValueCB))
7066 return indicatePessimisticFixpoint();
7067
7068 return clampStateAndIndicateChange(getState(), T);
7069 }
7070
7071 /// See AbstractAttribute::trackStatistics()
7072 void trackStatistics() const override {
7073 STATS_DECLTRACK_FLOATING_ATTR(value_range)
7074 }
7075};
7076
7077struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
7078 AAValueConstantRangeFunction(const IRPosition &IRP)
7079 : AAValueConstantRangeImpl(IRP) {}
7080
7081 /// See AbstractAttribute::initialize(...).
7082 ChangeStatus updateImpl(Attributor &A) override {
7083 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
7084 "not be called");
7085 }
7086
7087 /// See AbstractAttribute::trackStatistics()
7088 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
7089};
7090
7091struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
7092 AAValueConstantRangeCallSite(const IRPosition &IRP)
7093 : AAValueConstantRangeFunction(IRP) {}
7094
7095 /// See AbstractAttribute::trackStatistics()
7096 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
7097};
7098
Johannes Doerfert791c9f12020-01-29 18:02:42 -06007099struct AAValueConstantRangeCallSiteReturned
7100 : AACallSiteReturnedFromReturned<AAValueConstantRange,
7101 AAValueConstantRangeImpl> {
Hideto Ueno188f9a32020-01-15 15:25:52 +09007102 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP)
Johannes Doerfert791c9f12020-01-29 18:02:42 -06007103 : AACallSiteReturnedFromReturned<AAValueConstantRange,
7104 AAValueConstantRangeImpl>(IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09007105
7106 /// See AbstractAttribute::initialize(...).
7107 void initialize(Attributor &A) override {
7108 // If it is a load instruction with range metadata, use the metadata.
7109 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue()))
7110 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range))
7111 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
7112
Johannes Doerfert791c9f12020-01-29 18:02:42 -06007113 AAValueConstantRangeImpl::initialize(A);
Hideto Ueno188f9a32020-01-15 15:25:52 +09007114 }
7115
7116 /// See AbstractAttribute::trackStatistics()
7117 void trackStatistics() const override {
7118 STATS_DECLTRACK_CSRET_ATTR(value_range)
7119 }
7120};
7121struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
7122 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP)
7123 : AAValueConstantRangeFloating(IRP) {}
7124
7125 /// See AbstractAttribute::trackStatistics()
7126 void trackStatistics() const override {
7127 STATS_DECLTRACK_CSARG_ATTR(value_range)
7128 }
7129};
Benjamin Kramer564a9de2020-02-17 17:55:03 +01007130
7131} // namespace
Johannes Doerfertaade7822019-06-05 03:02:24 +00007132/// ----------------------------------------------------------------------------
7133/// Attributor
7134/// ----------------------------------------------------------------------------
7135
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007136bool Attributor::isAssumedDead(const AbstractAttribute &AA,
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007137 const AAIsDead *FnLivenessAA,
7138 bool CheckBBLivenessOnly, DepClassTy DepClass) {
7139 const IRPosition &IRP = AA.getIRPosition();
7140 if (!Functions.count(IRP.getAnchorScope()))
7141 return false;
7142 return isAssumedDead(IRP, &AA, FnLivenessAA, CheckBBLivenessOnly, DepClass);
7143}
7144
7145bool Attributor::isAssumedDead(const Use &U,
7146 const AbstractAttribute *QueryingAA,
7147 const AAIsDead *FnLivenessAA,
7148 bool CheckBBLivenessOnly, DepClassTy DepClass) {
7149 Instruction *UserI = dyn_cast<Instruction>(U.getUser());
7150 if (!UserI)
7151 return isAssumedDead(IRPosition::value(*U.get()), QueryingAA, FnLivenessAA,
7152 CheckBBLivenessOnly, DepClass);
7153
7154 if (CallSite CS = CallSite(UserI)) {
7155 // For call site argument uses we can check if the argument is
7156 // unused/dead.
7157 if (CS.isArgOperand(&U)) {
7158 const IRPosition &CSArgPos =
7159 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
7160 return isAssumedDead(CSArgPos, QueryingAA, FnLivenessAA,
7161 CheckBBLivenessOnly, DepClass);
7162 }
7163 } else if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
7164 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
7165 return isAssumedDead(RetPos, QueryingAA, FnLivenessAA, CheckBBLivenessOnly,
7166 DepClass);
7167 } else if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
7168 BasicBlock *IncomingBB = PHI->getIncomingBlock(U);
7169 return isAssumedDead(*IncomingBB->getTerminator(), QueryingAA, FnLivenessAA,
7170 CheckBBLivenessOnly, DepClass);
7171 }
7172
7173 return isAssumedDead(IRPosition::value(*UserI), QueryingAA, FnLivenessAA,
7174 CheckBBLivenessOnly, DepClass);
7175}
7176
7177bool Attributor::isAssumedDead(const Instruction &I,
7178 const AbstractAttribute *QueryingAA,
7179 const AAIsDead *FnLivenessAA,
7180 bool CheckBBLivenessOnly, DepClassTy DepClass) {
7181 if (!FnLivenessAA)
7182 FnLivenessAA = lookupAAFor<AAIsDead>(IRPosition::function(*I.getFunction()),
7183 QueryingAA,
7184 /* TrackDependence */ false);
7185
7186 // If we have a context instruction and a liveness AA we use it.
7187 if (FnLivenessAA &&
7188 FnLivenessAA->getIRPosition().getAnchorScope() == I.getFunction() &&
7189 FnLivenessAA->isAssumedDead(&I)) {
7190 if (QueryingAA)
7191 recordDependence(*FnLivenessAA, *QueryingAA, DepClass);
7192 return true;
7193 }
7194
7195 if (CheckBBLivenessOnly)
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007196 return false;
7197
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007198 const AAIsDead &IsDeadAA = getOrCreateAAFor<AAIsDead>(
7199 IRPosition::value(I), QueryingAA, /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00007200 // Don't check liveness for AAIsDead.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007201 if (QueryingAA == &IsDeadAA)
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00007202 return false;
7203
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007204 if (IsDeadAA.isAssumedDead()) {
7205 if (QueryingAA)
7206 recordDependence(IsDeadAA, *QueryingAA, DepClass);
7207 return true;
7208 }
7209
7210 return false;
7211}
7212
7213bool Attributor::isAssumedDead(const IRPosition &IRP,
7214 const AbstractAttribute *QueryingAA,
7215 const AAIsDead *FnLivenessAA,
7216 bool CheckBBLivenessOnly, DepClassTy DepClass) {
7217 Instruction *CtxI = IRP.getCtxI();
7218 if (CtxI &&
7219 isAssumedDead(*CtxI, QueryingAA, FnLivenessAA,
7220 /* CheckBBLivenessOnly */ true,
7221 CheckBBLivenessOnly ? DepClass : DepClassTy::OPTIONAL))
7222 return true;
7223
7224 if (CheckBBLivenessOnly)
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007225 return false;
7226
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007227 // If we haven't succeeded we query the specific liveness info for the IRP.
7228 const AAIsDead *IsDeadAA;
7229 if (IRP.getPositionKind() == IRPosition::IRP_CALL_SITE)
7230 IsDeadAA = &getOrCreateAAFor<AAIsDead>(
7231 IRPosition::callsite_returned(cast<CallBase>(IRP.getAssociatedValue())),
7232 QueryingAA, /* TrackDependence */ false);
7233 else
7234 IsDeadAA = &getOrCreateAAFor<AAIsDead>(IRP, QueryingAA,
7235 /* TrackDependence */ false);
7236 // Don't check liveness for AAIsDead.
7237 if (QueryingAA == IsDeadAA)
7238 return false;
Johannes Doerfert19b00432019-08-26 17:48:05 +00007239
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007240 if (IsDeadAA->isAssumedDead()) {
7241 if (QueryingAA)
7242 recordDependence(*IsDeadAA, *QueryingAA, DepClass);
7243 return true;
7244 }
7245
7246 return false;
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007247}
7248
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007249bool Attributor::checkForAllUses(
7250 const function_ref<bool(const Use &, bool &)> &Pred,
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007251 const AbstractAttribute &QueryingAA, const Value &V,
7252 DepClassTy LivenessDepClass) {
Johannes Doerfertb2c76002020-01-23 17:12:56 -06007253
7254 // Check the trivial case first as it catches void values.
7255 if (V.use_empty())
7256 return true;
7257
7258 // If the value is replaced by another one, for now a constant, we do not have
7259 // uses. Note that this requires users of `checkForAllUses` to not recurse but
7260 // instead use the `follow` callback argument to look at transitive users,
7261 // however, that should be clear from the presence of the argument.
7262 bool UsedAssumedInformation = false;
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06007263 Optional<Constant *> C =
Johannes Doerfertb2c76002020-01-23 17:12:56 -06007264 getAssumedConstant(*this, V, QueryingAA, UsedAssumedInformation);
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06007265 if (C.hasValue() && C.getValue()) {
Johannes Doerfertb2c76002020-01-23 17:12:56 -06007266 LLVM_DEBUG(dbgs() << "[Attributor] Value is simplified, uses skipped: " << V
Johannes Doerferte1eed6c2020-02-16 16:45:28 -06007267 << " -> " << *C.getValue() << "\n");
Johannes Doerfertb2c76002020-01-23 17:12:56 -06007268 return true;
7269 }
7270
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007271 const IRPosition &IRP = QueryingAA.getIRPosition();
7272 SmallVector<const Use *, 16> Worklist;
7273 SmallPtrSet<const Use *, 16> Visited;
7274
7275 for (const Use &U : V.uses())
7276 Worklist.push_back(&U);
7277
7278 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
7279 << " initial uses to check\n");
7280
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007281 const Function *ScopeFn = IRP.getAnchorScope();
7282 const auto *LivenessAA =
7283 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
7284 /* TrackDependence */ false)
7285 : nullptr;
7286
7287 while (!Worklist.empty()) {
7288 const Use *U = Worklist.pop_back_val();
7289 if (!Visited.insert(U).second)
7290 continue;
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007291 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << " in "
7292 << *U->getUser() << "\n");
7293 if (isAssumedDead(*U, &QueryingAA, LivenessAA,
7294 /* CheckBBLivenessOnly */ false, LivenessDepClass)) {
7295 LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
7296 continue;
Johannes Doerfert8e629682020-02-11 00:10:35 -06007297 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007298
7299 bool Follow = false;
7300 if (!Pred(*U, Follow))
7301 return false;
7302 if (!Follow)
7303 continue;
7304 for (const Use &UU : U->getUser()->uses())
7305 Worklist.push_back(&UU);
7306 }
7307
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007308 return true;
7309}
7310
Johannes Doerfert661db042019-10-07 23:14:58 +00007311bool Attributor::checkForAllCallSites(
7312 const function_ref<bool(AbstractCallSite)> &Pred,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007313 const AbstractAttribute &QueryingAA, bool RequireAllCallSites,
7314 bool &AllCallSitesKnown) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00007315 // We can try to determine information from
7316 // the call sites. However, this is only possible all call sites are known,
7317 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007318 const IRPosition &IRP = QueryingAA.getIRPosition();
7319 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00007320 if (!AssociatedFunction) {
7321 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
7322 << "\n");
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007323 AllCallSitesKnown = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007324 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00007325 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007326
Johannes Doerfert3753aa72019-10-13 04:16:02 +00007327 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007328 &QueryingAA, AllCallSitesKnown);
Johannes Doerfert3753aa72019-10-13 04:16:02 +00007329}
7330
7331bool Attributor::checkForAllCallSites(
7332 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007333 bool RequireAllCallSites, const AbstractAttribute *QueryingAA,
7334 bool &AllCallSitesKnown) {
Johannes Doerfert3753aa72019-10-13 04:16:02 +00007335 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00007336 LLVM_DEBUG(
7337 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00007338 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00007339 << " has no internal linkage, hence not all call sites are known\n");
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007340 AllCallSitesKnown = false;
Hideto Ueno54869ec2019-07-15 06:49:04 +00007341 return false;
7342 }
7343
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007344 // If we do not require all call sites we might not see all.
7345 AllCallSitesKnown = RequireAllCallSites;
7346
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06007347 SmallVector<const Use *, 8> Uses(make_pointer_range(Fn.uses()));
7348 for (unsigned u = 0; u < Uses.size(); ++u) {
7349 const Use &U = *Uses[u];
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007350 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << *U << " in "
7351 << *U.getUser() << "\n");
7352 if (isAssumedDead(U, QueryingAA, nullptr, /* CheckBBLivenessOnly */ true)) {
7353 LLVM_DEBUG(dbgs() << "[Attributor] Dead use, skip!\n");
7354 continue;
7355 }
Johannes Doerfertc6ac7172020-01-25 20:24:38 -06007356 if (ConstantExpr *CE = dyn_cast<ConstantExpr>(U.getUser())) {
7357 if (CE->isCast() && CE->getType()->isPointerTy() &&
7358 CE->getType()->getPointerElementType()->isFunctionTy()) {
7359 for (const Use &CEU : CE->uses())
7360 Uses.push_back(&CEU);
7361 continue;
7362 }
7363 }
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007364
Johannes Doerfert661db042019-10-07 23:14:58 +00007365 AbstractCallSite ACS(&U);
7366 if (!ACS) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007367 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00007368 << " has non call site use " << *U.get() << " in "
7369 << *U.getUser() << "\n");
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05007370 // BlockAddress users are allowed.
7371 if (isa<BlockAddress>(U.getUser()))
7372 continue;
Johannes Doerfertd98f9752019-08-21 21:48:56 +00007373 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00007374 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00007375
Johannes Doerfert661db042019-10-07 23:14:58 +00007376 const Use *EffectiveUse =
7377 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
7378 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00007379 if (!RequireAllCallSites)
7380 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00007381 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007382 << " is an invalid use of " << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00007383 return false;
7384 }
7385
Johannes Doerfert1e99fc92020-02-16 16:42:47 -06007386 // Make sure the arguments that can be matched between the call site and the
7387 // callee argee on their type. It is unlikely they do not and it doesn't
7388 // make sense for all attributes to know/care about this.
7389 assert(&Fn == ACS.getCalledFunction() && "Expected known callee");
7390 unsigned MinArgsParams =
7391 std::min(size_t(ACS.getNumArgOperands()), Fn.arg_size());
7392 for (unsigned u = 0; u < MinArgsParams; ++u) {
7393 Value *CSArgOp = ACS.getCallArgOperand(u);
7394 if (CSArgOp && Fn.getArg(u)->getType() != CSArgOp->getType()) {
7395 LLVM_DEBUG(
7396 dbgs() << "[Attributor] Call site / callee argument type mismatch ["
7397 << u << "@" << Fn.getName() << ": "
7398 << *Fn.getArg(u)->getType() << " vs. "
7399 << *ACS.getCallArgOperand(u)->getType() << "\n");
7400 return false;
7401 }
7402 }
7403
Johannes Doerfert661db042019-10-07 23:14:58 +00007404 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00007405 continue;
7406
Johannes Doerfert5304b722019-08-14 22:04:28 +00007407 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00007408 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00007409 return false;
7410 }
7411
7412 return true;
7413}
7414
Johannes Doerfert14a04932019-08-07 22:27:24 +00007415bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00007416 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00007417 &Pred,
7418 const AbstractAttribute &QueryingAA) {
7419
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007420 const IRPosition &IRP = QueryingAA.getIRPosition();
7421 // Since we need to provide return instructions we have to have an exact
7422 // definition.
7423 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00007424 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00007425 return false;
7426
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007427 // If this is a call site query we use the call site specific return values
7428 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00007429 // TODO: use the function scope once we have call site AAReturnedValues.
7430 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007431 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007432 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007433 return false;
7434
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007435 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00007436}
7437
7438bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007439 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00007440 const AbstractAttribute &QueryingAA) {
7441
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007442 const IRPosition &IRP = QueryingAA.getIRPosition();
7443 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00007444 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00007445 return false;
7446
Johannes Doerfert07a5c122019-08-28 14:09:14 +00007447 // TODO: use the function scope once we have call site AAReturnedValues.
7448 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007449 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007450 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007451 return false;
7452
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007453 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00007454 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00007455 return Pred(RV);
7456 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00007457}
7458
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007459static bool checkForAllInstructionsImpl(
7460 Attributor *A, InformationCache::OpcodeInstMapTy &OpcodeInstMap,
7461 const function_ref<bool(Instruction &)> &Pred,
7462 const AbstractAttribute *QueryingAA, const AAIsDead *LivenessAA,
7463 const ArrayRef<unsigned> &Opcodes, bool CheckBBLivenessOnly = false) {
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007464 for (unsigned Opcode : Opcodes) {
7465 for (Instruction *I : OpcodeInstMap[Opcode]) {
7466 // Skip dead instructions.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007467 if (A && A->isAssumedDead(IRPosition::value(*I), QueryingAA, LivenessAA,
7468 CheckBBLivenessOnly))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007469 continue;
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007470
7471 if (!Pred(*I))
7472 return false;
7473 }
7474 }
7475 return true;
7476}
7477
Johannes Doerfertd0f64002019-08-06 00:32:43 +00007478bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007479 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007480 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes,
7481 bool CheckBBLivenessOnly) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00007482
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007483 const IRPosition &IRP = QueryingAA.getIRPosition();
7484 // Since we need to provide instructions we have to have an exact definition.
7485 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00007486 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007487 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00007488
Johannes Doerfert07a5c122019-08-28 14:09:14 +00007489 // TODO: use the function scope once we have call site AAReturnedValues.
7490 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00007491 const auto &LivenessAA =
7492 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007493
7494 auto &OpcodeInstMap =
7495 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007496 if (!checkForAllInstructionsImpl(this, OpcodeInstMap, Pred, &QueryingAA,
7497 &LivenessAA, Opcodes, CheckBBLivenessOnly))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007498 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00007499
7500 return true;
7501}
7502
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007503bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007504 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00007505 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007506
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007507 const Function *AssociatedFunction =
7508 QueryingAA.getIRPosition().getAssociatedFunction();
7509 if (!AssociatedFunction)
7510 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007511
Johannes Doerfert07a5c122019-08-28 14:09:14 +00007512 // TODO: use the function scope once we have call site AAReturnedValues.
7513 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
7514 const auto &LivenessAA =
7515 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007516
7517 for (Instruction *I :
7518 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007519 // Skip dead instructions.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007520 if (isAssumedDead(IRPosition::value(*I), &QueryingAA, &LivenessAA))
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00007521 continue;
7522
7523 if (!Pred(*I))
7524 return false;
7525 }
7526
7527 return true;
7528}
7529
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007530ChangeStatus Attributor::run() {
Johannes Doerfertaade7822019-06-05 03:02:24 +00007531 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
7532 << AllAbstractAttributes.size()
7533 << " abstract attributes.\n");
7534
Stefan Stipanovic53605892019-06-27 11:27:54 +00007535 // Now that all abstract attributes are collected and initialized we start
7536 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00007537
7538 unsigned IterationCounter = 1;
7539
7540 SmallVector<AbstractAttribute *, 64> ChangedAAs;
Johannes Doerfert680f6382019-11-02 02:48:05 -05007541 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007542 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
7543
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00007544 bool RecomputeDependences = false;
7545
Johannes Doerfertaade7822019-06-05 03:02:24 +00007546 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007547 // Remember the size to determine new attributes.
7548 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00007549 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
7550 << ", Worklist size: " << Worklist.size() << "\n");
7551
Johannes Doerfert680f6382019-11-02 02:48:05 -05007552 // For invalid AAs we can fix dependent AAs that have a required dependence,
7553 // thereby folding long dependence chains in a single step without the need
7554 // to run updates.
7555 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
7556 AbstractAttribute *InvalidAA = InvalidAAs[u];
7557 auto &QuerriedAAs = QueryMap[InvalidAA];
7558 LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
7559 << QuerriedAAs.RequiredAAs.size() << "/"
7560 << QuerriedAAs.OptionalAAs.size()
7561 << " required/optional dependences\n");
7562 for (AbstractAttribute *DepOnInvalidAA : QuerriedAAs.RequiredAAs) {
7563 AbstractState &DOIAAState = DepOnInvalidAA->getState();
7564 DOIAAState.indicatePessimisticFixpoint();
7565 ++NumAttributesFixedDueToRequiredDependences;
7566 assert(DOIAAState.isAtFixpoint() && "Expected fixpoint state!");
7567 if (!DOIAAState.isValidState())
7568 InvalidAAs.insert(DepOnInvalidAA);
Johannes Doerfert22408542020-01-28 09:38:07 -06007569 else
7570 ChangedAAs.push_back(DepOnInvalidAA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05007571 }
7572 if (!RecomputeDependences)
7573 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
7574 QuerriedAAs.OptionalAAs.end());
7575 }
7576
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00007577 // If dependences (=QueryMap) are recomputed we have to look at all abstract
7578 // attributes again, regardless of what changed in the last iteration.
7579 if (RecomputeDependences) {
7580 LLVM_DEBUG(
7581 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
7582 QueryMap.clear();
7583 ChangedAAs.clear();
7584 Worklist.insert(AllAbstractAttributes.begin(),
7585 AllAbstractAttributes.end());
7586 }
7587
Johannes Doerfertaade7822019-06-05 03:02:24 +00007588 // Add all abstract attributes that are potentially dependent on one that
7589 // changed to the work list.
7590 for (AbstractAttribute *ChangedAA : ChangedAAs) {
7591 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05007592 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
7593 QuerriedAAs.OptionalAAs.end());
7594 Worklist.insert(QuerriedAAs.RequiredAAs.begin(),
7595 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00007596 }
7597
Johannes Doerfertb504eb82019-08-26 18:55:47 +00007598 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
7599 << ", Worklist+Dependent size: " << Worklist.size()
7600 << "\n");
7601
Johannes Doerfert680f6382019-11-02 02:48:05 -05007602 // Reset the changed and invalid set.
Johannes Doerfertaade7822019-06-05 03:02:24 +00007603 ChangedAAs.clear();
Johannes Doerfert680f6382019-11-02 02:48:05 -05007604 InvalidAAs.clear();
Johannes Doerfertaade7822019-06-05 03:02:24 +00007605
7606 // Update all abstract attribute in the work list and record the ones that
7607 // changed.
7608 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007609 if (!AA->getState().isAtFixpoint() &&
7610 !isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true)) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05007611 QueriedNonFixAA = false;
7612 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007613 ChangedAAs.push_back(AA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05007614 if (!AA->getState().isValidState())
7615 InvalidAAs.insert(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05007616 } else if (!QueriedNonFixAA) {
7617 // If the attribute did not query any non-fix information, the state
7618 // will not change and we can indicate that right away.
7619 AA->getState().indicateOptimisticFixpoint();
7620 }
7621 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00007622
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00007623 // Check if we recompute the dependences in the next iteration.
7624 RecomputeDependences = (DepRecomputeInterval > 0 &&
7625 IterationCounter % DepRecomputeInterval == 0);
7626
Johannes Doerfert9543f142019-08-23 15:24:57 +00007627 // Add attributes to the changed set if they have been created in the last
7628 // iteration.
7629 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
7630 AllAbstractAttributes.end());
7631
Johannes Doerfertaade7822019-06-05 03:02:24 +00007632 // Reset the work list and repopulate with the changed abstract attributes.
7633 // Note that dependent ones are added above.
7634 Worklist.clear();
7635 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
7636
Johannes Doerfertbf112132019-08-29 01:29:44 +00007637 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
7638 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00007639
Johannes Doerfertaade7822019-06-05 03:02:24 +00007640 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
7641 << IterationCounter << "/" << MaxFixpointIterations
7642 << " iterations\n");
7643
Johannes Doerfertbf112132019-08-29 01:29:44 +00007644 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00007645
Johannes Doerfertaade7822019-06-05 03:02:24 +00007646 // Reset abstract arguments not settled in a sound fixpoint by now. This
7647 // happens when we stopped the fixpoint iteration early. Note that only the
7648 // ones marked as "changed" *and* the ones transitively depending on them
7649 // need to be reverted to a pessimistic state. Others might not be in a
7650 // fixpoint state but we can use the optimistic results for them anyway.
7651 SmallPtrSet<AbstractAttribute *, 32> Visited;
7652 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
7653 AbstractAttribute *ChangedAA = ChangedAAs[u];
7654 if (!Visited.insert(ChangedAA).second)
7655 continue;
7656
7657 AbstractState &State = ChangedAA->getState();
7658 if (!State.isAtFixpoint()) {
7659 State.indicatePessimisticFixpoint();
7660
7661 NumAttributesTimedOut++;
7662 }
7663
7664 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05007665 ChangedAAs.append(QuerriedAAs.OptionalAAs.begin(),
7666 QuerriedAAs.OptionalAAs.end());
7667 ChangedAAs.append(QuerriedAAs.RequiredAAs.begin(),
7668 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00007669 }
7670
7671 LLVM_DEBUG({
7672 if (!Visited.empty())
7673 dbgs() << "\n[Attributor] Finalized " << Visited.size()
7674 << " abstract attributes.\n";
7675 });
7676
7677 unsigned NumManifested = 0;
7678 unsigned NumAtFixpoint = 0;
7679 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
7680 for (AbstractAttribute *AA : AllAbstractAttributes) {
7681 AbstractState &State = AA->getState();
7682
7683 // If there is not already a fixpoint reached, we can now take the
7684 // optimistic state. This is correct because we enforced a pessimistic one
7685 // on abstract attributes that were transitively dependent on a changed one
7686 // already above.
7687 if (!State.isAtFixpoint())
7688 State.indicateOptimisticFixpoint();
7689
7690 // If the state is invalid, we do not try to manifest it.
7691 if (!State.isValidState())
7692 continue;
7693
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007694 // Skip dead code.
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007695 if (isAssumedDead(*AA, nullptr, /* CheckBBLivenessOnly */ true))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00007696 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007697 // Manifest the state and record if we changed the IR.
7698 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00007699 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
7700 AA->trackStatistics();
Johannes Doerfert8e76fec2020-02-16 17:37:50 -06007701 LLVM_DEBUG(dbgs() << "[Attributor] Manifest " << LocalChange << " : " << *AA
7702 << "\n");
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00007703
Johannes Doerfertaade7822019-06-05 03:02:24 +00007704 ManifestChange = ManifestChange | LocalChange;
7705
7706 NumAtFixpoint++;
7707 NumManifested += (LocalChange == ChangeStatus::CHANGED);
7708 }
7709
7710 (void)NumManifested;
7711 (void)NumAtFixpoint;
7712 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
7713 << " arguments while " << NumAtFixpoint
7714 << " were in a valid fixpoint state\n");
7715
Johannes Doerfertaade7822019-06-05 03:02:24 +00007716 NumAttributesManifested += NumManifested;
7717 NumAttributesValidFixpoint += NumAtFixpoint;
7718
Fangrui Songf1826172019-08-20 07:21:43 +00007719 (void)NumFinalAAs;
Johannes Doerfertb70297a2020-02-14 10:34:31 -06007720 if (NumFinalAAs != AllAbstractAttributes.size()) {
7721 for (unsigned u = NumFinalAAs; u < AllAbstractAttributes.size(); ++u)
7722 errs() << "Unexpected abstract attribute: " << *AllAbstractAttributes[u]
7723 << " :: "
7724 << AllAbstractAttributes[u]->getIRPosition().getAssociatedValue()
7725 << "\n";
7726 llvm_unreachable("Expected the final number of abstract attributes to "
7727 "remain unchanged!");
7728 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00007729
7730 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00007731 {
7732 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
7733 << ToBeDeletedFunctions.size() << " functions and "
7734 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007735 << ToBeDeletedInsts.size() << " instructions and "
7736 << ToBeChangedUses.size() << " uses\n");
7737
Alina Sbirlea9e66c4e2020-01-23 14:21:08 -08007738 SmallVector<WeakTrackingVH, 32> DeadInsts;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007739 SmallVector<Instruction *, 32> TerminatorsToFold;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007740
7741 for (auto &It : ToBeChangedUses) {
7742 Use *U = It.first;
7743 Value *NewV = It.second;
7744 Value *OldV = U->get();
7745 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
7746 << " instead of " << *OldV << "\n");
7747 U->set(NewV);
Johannes Doerfert137c99a2020-02-14 20:06:34 -06007748 // Do not modify call instructions outside the SCC.
7749 if (auto *CB = dyn_cast<CallBase>(OldV))
7750 if (!Functions.count(CB->getCaller()))
7751 continue;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007752 if (Instruction *I = dyn_cast<Instruction>(OldV)) {
7753 CGModifiedFunctions.insert(I->getFunction());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007754 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007755 isInstructionTriviallyDead(I))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007756 DeadInsts.push_back(I);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007757 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007758 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
7759 Instruction *UserI = cast<Instruction>(U->getUser());
7760 if (isa<UndefValue>(NewV)) {
Hideto Uenocb5eb132019-12-27 02:39:37 +09007761 ToBeChangedToUnreachableInsts.insert(UserI);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007762 } else {
7763 TerminatorsToFold.push_back(UserI);
7764 }
7765 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00007766 }
Johannes Doerferta4088c72020-01-07 16:01:57 -06007767 for (auto &V : InvokeWithDeadSuccessor)
7768 if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
7769 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
7770 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
7771 bool Invoke2CallAllowed =
7772 !AAIsDeadFunction::mayCatchAsynchronousExceptions(
7773 *II->getFunction());
7774 assert((UnwindBBIsDead || NormalBBIsDead) &&
7775 "Invoke does not have dead successors!");
7776 BasicBlock *BB = II->getParent();
7777 BasicBlock *NormalDestBB = II->getNormalDest();
7778 if (UnwindBBIsDead) {
7779 Instruction *NormalNextIP = &NormalDestBB->front();
7780 if (Invoke2CallAllowed) {
7781 changeToCall(II);
7782 NormalNextIP = BB->getTerminator();
7783 }
7784 if (NormalBBIsDead)
7785 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
7786 } else {
7787 assert(NormalBBIsDead && "Broken invariant!");
7788 if (!NormalDestBB->getUniquePredecessor())
7789 NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
7790 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
7791 }
7792 }
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06007793 for (auto &V : ToBeChangedToUnreachableInsts)
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007794 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
7795 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06007796 changeToUnreachable(I, /* UseLLVMTrap */ false);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007797 }
7798 for (Instruction *I : TerminatorsToFold) {
7799 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007800 ConstantFoldTerminator(I->getParent());
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007801 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007802
Johannes Doerfert5429c822020-01-11 23:30:36 -06007803 for (auto &V : ToBeDeletedInsts) {
7804 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007805 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfertb4352e42020-02-13 20:10:59 -06007806 if (!I->getType()->isVoidTy())
7807 I->replaceAllUsesWith(UndefValue::get(I->getType()));
Johannes Doerfert5429c822020-01-11 23:30:36 -06007808 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
7809 DeadInsts.push_back(I);
7810 else
7811 I->eraseFromParent();
7812 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007813 }
7814
7815 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00007816
Johannes Doerfert2f622062019-09-04 16:35:20 +00007817 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
7818 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
7819 ToBeDeletedBBs.reserve(NumDeadBlocks);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007820 for (BasicBlock *BB : ToBeDeletedBlocks) {
7821 CGModifiedFunctions.insert(BB->getParent());
7822 ToBeDeletedBBs.push_back(BB);
7823 }
Johannes Doerfert5e442a52019-10-30 17:34:59 -05007824 // Actually we do not delete the blocks but squash them into a single
7825 // unreachable but untangling branches that jump here is something we need
7826 // to do in a more generic way.
7827 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
7828 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
7829 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00007830 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00007831
Johannes Doerfert2f622062019-09-04 16:35:20 +00007832 // Identify dead internal functions and delete them. This happens outside
7833 // the other fixpoint analysis as we might treat potentially dead functions
7834 // as live to lower the number of iterations. If they happen to be dead, the
7835 // below fixpoint loop will identify and eliminate them.
7836 SmallVector<Function *, 8> InternalFns;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007837 for (Function *F : Functions)
7838 if (F->hasLocalLinkage())
7839 InternalFns.push_back(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00007840
7841 bool FoundDeadFn = true;
7842 while (FoundDeadFn) {
7843 FoundDeadFn = false;
7844 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
7845 Function *F = InternalFns[u];
7846 if (!F)
7847 continue;
7848
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007849 bool AllCallSitesKnown;
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06007850 if (!checkForAllCallSites(
7851 [this](AbstractCallSite ACS) {
7852 return ToBeDeletedFunctions.count(
7853 ACS.getInstruction()->getFunction());
7854 },
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007855 *F, true, nullptr, AllCallSitesKnown))
Johannes Doerfert2f622062019-09-04 16:35:20 +00007856 continue;
7857
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007858 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00007859 InternalFns[u] = nullptr;
7860 FoundDeadFn = true;
7861 }
7862 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00007863 }
7864
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007865 // Rewrite the functions as requested during manifest.
7866 ManifestChange =
7867 ManifestChange | rewriteFunctionSignatures(CGModifiedFunctions);
7868
7869 for (Function *Fn : CGModifiedFunctions)
7870 CGUpdater.reanalyzeFunction(*Fn);
7871
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007872 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
7873 BUILD_STAT_NAME(AAIsDead, Function) += ToBeDeletedFunctions.size();
7874
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007875 for (Function *Fn : ToBeDeletedFunctions)
7876 CGUpdater.removeFunction(*Fn);
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06007877
Johannes Doerfertbf112132019-08-29 01:29:44 +00007878 if (VerifyMaxFixpointIterations &&
7879 IterationCounter != MaxFixpointIterations) {
7880 errs() << "\n[Attributor] Fixpoint iteration done after: "
7881 << IterationCounter << "/" << MaxFixpointIterations
7882 << " iterations\n";
7883 llvm_unreachable("The fixpoint was not reached with exactly the number of "
7884 "specified iterations!");
7885 }
7886
Johannes Doerfertaade7822019-06-05 03:02:24 +00007887 return ManifestChange;
7888}
7889
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007890bool Attributor::isValidFunctionSignatureRewrite(
7891 Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007892
7893 auto CallSiteCanBeChanged = [](AbstractCallSite ACS) {
7894 // Forbid must-tail calls for now.
7895 return !ACS.isCallbackCall() && !ACS.getCallSite().isMustTailCall();
7896 };
7897
7898 Function *Fn = Arg.getParent();
7899 // Avoid var-arg functions for now.
7900 if (Fn->isVarArg()) {
7901 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
7902 return false;
7903 }
7904
7905 // Avoid functions with complicated argument passing semantics.
7906 AttributeList FnAttributeList = Fn->getAttributes();
7907 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
7908 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
7909 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca)) {
7910 LLVM_DEBUG(
7911 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
7912 return false;
7913 }
7914
7915 // Avoid callbacks for now.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007916 bool AllCallSitesKnown;
7917 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,
7918 AllCallSitesKnown)) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007919 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
7920 return false;
7921 }
7922
7923 auto InstPred = [](Instruction &I) {
7924 if (auto *CI = dyn_cast<CallInst>(&I))
7925 return !CI->isMustTailCall();
7926 return true;
7927 };
7928
7929 // Forbid must-tail calls for now.
7930 // TODO:
Johannes Doerfert75133632019-10-10 01:39:16 -05007931 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
Johannes Doerfert23f41f12020-01-12 01:09:22 -06007932 if (!checkForAllInstructionsImpl(nullptr, OpcodeInstMap, InstPred, nullptr,
7933 nullptr, {Instruction::Call})) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007934 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
7935 return false;
7936 }
7937
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007938 return true;
7939}
7940
7941bool Attributor::registerFunctionSignatureRewrite(
7942 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
7943 ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,
7944 ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {
7945 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
7946 << Arg.getParent()->getName() << " with "
7947 << ReplacementTypes.size() << " replacements\n");
7948 assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&
7949 "Cannot register an invalid rewrite");
7950
7951 Function *Fn = Arg.getParent();
Johannes Doerfert75133632019-10-10 01:39:16 -05007952 SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = ArgumentReplacementMap[Fn];
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007953 if (ARIs.empty())
Johannes Doerfert75133632019-10-10 01:39:16 -05007954 ARIs.resize(Fn->arg_size());
7955
7956 // If we have a replacement already with less than or equal new arguments,
7957 // ignore this request.
7958 ArgumentReplacementInfo *&ARI = ARIs[Arg.getArgNo()];
7959 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
7960 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
7961 return false;
7962 }
7963
7964 // If we have a replacement already but we like the new one better, delete
7965 // the old.
7966 if (ARI)
7967 delete ARI;
7968
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007969 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
7970 << Arg.getParent()->getName() << " with "
7971 << ReplacementTypes.size() << " replacements\n");
7972
Johannes Doerfert75133632019-10-10 01:39:16 -05007973 // Remember the replacement.
7974 ARI = new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
7975 std::move(CalleeRepairCB),
7976 std::move(ACSRepairCB));
7977
7978 return true;
7979}
7980
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007981ChangeStatus Attributor::rewriteFunctionSignatures(
7982 SmallPtrSetImpl<Function *> &ModifiedFns) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007983 ChangeStatus Changed = ChangeStatus::UNCHANGED;
7984
7985 for (auto &It : ArgumentReplacementMap) {
7986 Function *OldFn = It.getFirst();
7987
7988 // Deleted functions do not require rewrites.
7989 if (ToBeDeletedFunctions.count(OldFn))
7990 continue;
7991
7992 const SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = It.getSecond();
7993 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
7994
7995 SmallVector<Type *, 16> NewArgumentTypes;
7996 SmallVector<AttributeSet, 16> NewArgumentAttributes;
7997
7998 // Collect replacement argument types and copy over existing attributes.
7999 AttributeList OldFnAttributeList = OldFn->getAttributes();
8000 for (Argument &Arg : OldFn->args()) {
8001 if (ArgumentReplacementInfo *ARI = ARIs[Arg.getArgNo()]) {
8002 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
8003 ARI->ReplacementTypes.end());
8004 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
8005 AttributeSet());
8006 } else {
8007 NewArgumentTypes.push_back(Arg.getType());
8008 NewArgumentAttributes.push_back(
8009 OldFnAttributeList.getParamAttributes(Arg.getArgNo()));
8010 }
8011 }
8012
8013 FunctionType *OldFnTy = OldFn->getFunctionType();
8014 Type *RetTy = OldFnTy->getReturnType();
8015
8016 // Construct the new function type using the new arguments types.
8017 FunctionType *NewFnTy =
8018 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
8019
8020 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
8021 << "' from " << *OldFn->getFunctionType() << " to "
8022 << *NewFnTy << "\n");
8023
8024 // Create the new function body and insert it into the module.
8025 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
8026 OldFn->getAddressSpace(), "");
8027 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
8028 NewFn->takeName(OldFn);
8029 NewFn->copyAttributesFrom(OldFn);
8030
8031 // Patch the pointer to LLVM function in debug info descriptor.
8032 NewFn->setSubprogram(OldFn->getSubprogram());
8033 OldFn->setSubprogram(nullptr);
8034
8035 // Recompute the parameter attributes list based on the new arguments for
8036 // the function.
8037 LLVMContext &Ctx = OldFn->getContext();
8038 NewFn->setAttributes(AttributeList::get(
8039 Ctx, OldFnAttributeList.getFnAttributes(),
8040 OldFnAttributeList.getRetAttributes(), NewArgumentAttributes));
8041
8042 // Since we have now created the new function, splice the body of the old
8043 // function right into the new function, leaving the old rotting hulk of the
8044 // function empty.
8045 NewFn->getBasicBlockList().splice(NewFn->begin(),
8046 OldFn->getBasicBlockList());
8047
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008048 // Set of all "call-like" instructions that invoke the old function mapped
8049 // to their new replacements.
8050 SmallVector<std::pair<CallBase *, CallBase *>, 8> CallSitePairs;
Johannes Doerfert75133632019-10-10 01:39:16 -05008051
8052 // Callback to create a new "call-like" instruction for a given one.
8053 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
8054 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
8055 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
8056
8057 // Collect the new argument operands for the replacement call site.
8058 SmallVector<Value *, 16> NewArgOperands;
8059 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
8060 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
8061 unsigned NewFirstArgNum = NewArgOperands.size();
Ilya Biryukov4f82af82019-12-31 10:21:52 +01008062 (void)NewFirstArgNum; // only used inside assert.
Johannes Doerfert75133632019-10-10 01:39:16 -05008063 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
8064 if (ARI->ACSRepairCB)
8065 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
8066 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
8067 NewArgOperands.size() &&
8068 "ACS repair callback did not provide as many operand as new "
8069 "types were registered!");
8070 // TODO: Exose the attribute set to the ACS repair callback
8071 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
8072 AttributeSet());
8073 } else {
8074 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
8075 NewArgOperandAttributes.push_back(
8076 OldCallAttributeList.getParamAttributes(OldArgNum));
8077 }
8078 }
8079
8080 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
8081 "Mismatch # argument operands vs. # argument operand attributes!");
8082 assert(NewArgOperands.size() == NewFn->arg_size() &&
8083 "Mismatch # argument operands vs. # function arguments!");
8084
8085 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
8086 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
8087
8088 // Create a new call or invoke instruction to replace the old one.
8089 CallBase *NewCB;
8090 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
8091 NewCB =
8092 InvokeInst::Create(NewFn, II->getNormalDest(), II->getUnwindDest(),
8093 NewArgOperands, OperandBundleDefs, "", OldCB);
8094 } else {
8095 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
8096 "", OldCB);
8097 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
8098 NewCB = NewCI;
8099 }
8100
8101 // Copy over various properties and the new attributes.
Johannes Doerfert75133632019-10-10 01:39:16 -05008102 uint64_t W;
8103 if (OldCB->extractProfTotalWeight(W))
8104 NewCB->setProfWeight(W);
8105 NewCB->setCallingConv(OldCB->getCallingConv());
8106 NewCB->setDebugLoc(OldCB->getDebugLoc());
8107 NewCB->takeName(OldCB);
8108 NewCB->setAttributes(AttributeList::get(
8109 Ctx, OldCallAttributeList.getFnAttributes(),
8110 OldCallAttributeList.getRetAttributes(), NewArgOperandAttributes));
8111
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008112 CallSitePairs.push_back({OldCB, NewCB});
Johannes Doerfert75133632019-10-10 01:39:16 -05008113 return true;
8114 };
8115
8116 // Use the CallSiteReplacementCreator to create replacement call sites.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06008117 bool AllCallSitesKnown;
8118 bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,
8119 true, nullptr, AllCallSitesKnown);
Ilya Biryukov4f82af82019-12-31 10:21:52 +01008120 (void)Success;
Johannes Doerfert75133632019-10-10 01:39:16 -05008121 assert(Success && "Assumed call site replacement to succeed!");
8122
8123 // Rewire the arguments.
8124 auto OldFnArgIt = OldFn->arg_begin();
8125 auto NewFnArgIt = NewFn->arg_begin();
8126 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
8127 ++OldArgNum, ++OldFnArgIt) {
8128 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
8129 if (ARI->CalleeRepairCB)
8130 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
8131 NewFnArgIt += ARI->ReplacementTypes.size();
8132 } else {
8133 NewFnArgIt->takeName(&*OldFnArgIt);
8134 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
8135 ++NewFnArgIt;
8136 }
8137 }
8138
8139 // Eliminate the instructions *after* we visited all of them.
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008140 for (auto &CallSitePair : CallSitePairs) {
8141 CallBase &OldCB = *CallSitePair.first;
8142 CallBase &NewCB = *CallSitePair.second;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008143 // We do not modify the call graph here but simply reanalyze the old
8144 // function. This should be revisited once the old PM is gone.
8145 ModifiedFns.insert(OldCB.getFunction());
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008146 OldCB.replaceAllUsesWith(&NewCB);
8147 OldCB.eraseFromParent();
8148 }
Johannes Doerfert75133632019-10-10 01:39:16 -05008149
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008150 // Replace the function in the call graph (if any).
8151 CGUpdater.replaceFunctionWith(*OldFn, *NewFn);
8152
8153 // If the old function was modified and needed to be reanalyzed, the new one
8154 // does now.
8155 if (ModifiedFns.erase(OldFn))
8156 ModifiedFns.insert(NewFn);
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06008157
Johannes Doerfert75133632019-10-10 01:39:16 -05008158 Changed = ChangeStatus::CHANGED;
8159 }
8160
8161 return Changed;
8162}
8163
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008164void Attributor::initializeInformationCache(Function &F) {
8165
8166 // Walk all instructions to find interesting instructions that might be
8167 // queried by abstract attributes during their initialization or update.
8168 // This has to happen before we create attributes.
8169 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
8170 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
8171
8172 for (Instruction &I : instructions(&F)) {
8173 bool IsInterestingOpcode = false;
8174
8175 // To allow easy access to all instructions in a function with a given
8176 // opcode we store them in the InfoCache. As not all opcodes are interesting
8177 // to concrete attributes we only cache the ones that are as identified in
8178 // the following switch.
8179 // Note: There are no concrete attributes now so this is initially empty.
8180 switch (I.getOpcode()) {
8181 default:
8182 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
8183 "New call site/base instruction type needs to be known int the "
8184 "Attributor.");
8185 break;
8186 case Instruction::Load:
8187 // The alignment of a pointer is interesting for loads.
8188 case Instruction::Store:
8189 // The alignment of a pointer is interesting for stores.
8190 case Instruction::Call:
8191 case Instruction::CallBr:
8192 case Instruction::Invoke:
8193 case Instruction::CleanupRet:
8194 case Instruction::CatchSwitch:
Johannes Doerfert5732f562019-12-24 19:25:08 -06008195 case Instruction::AtomicRMW:
8196 case Instruction::AtomicCmpXchg:
Hideto Uenoef4febd2019-12-29 17:34:08 +09008197 case Instruction::Br:
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008198 case Instruction::Resume:
8199 case Instruction::Ret:
8200 IsInterestingOpcode = true;
8201 }
8202 if (IsInterestingOpcode)
8203 InstOpcodeMap[I.getOpcode()].push_back(&I);
8204 if (I.mayReadOrWriteMemory())
8205 ReadOrWriteInsts.push_back(&I);
8206 }
8207}
8208
Johannes Doerfert12173e62019-10-13 20:25:25 -05008209void Attributor::recordDependence(const AbstractAttribute &FromAA,
Johannes Doerfert680f6382019-11-02 02:48:05 -05008210 const AbstractAttribute &ToAA,
8211 DepClassTy DepClass) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05008212 if (FromAA.getState().isAtFixpoint())
8213 return;
8214
Johannes Doerfert680f6382019-11-02 02:48:05 -05008215 if (DepClass == DepClassTy::REQUIRED)
8216 QueryMap[&FromAA].RequiredAAs.insert(
8217 const_cast<AbstractAttribute *>(&ToAA));
8218 else
8219 QueryMap[&FromAA].OptionalAAs.insert(
8220 const_cast<AbstractAttribute *>(&ToAA));
Johannes Doerfert2dad7292019-10-13 21:10:31 -05008221 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05008222}
8223
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00008224void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00008225 if (!VisitedFunctions.insert(&F).second)
8226 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05008227 if (F.isDeclaration())
8228 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00008229
Johannes Doerfert710ebb02019-08-14 21:18:01 +00008230 IRPosition FPos = IRPosition::function(F);
8231
Johannes Doerfert305b9612019-08-04 18:40:01 +00008232 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00008233 // We need dead instruction detection because we do not want to deal with
8234 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008235 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00008236
8237 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008238 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00008239
Johannes Doerfert58f324a2019-12-24 18:48:50 -06008240 // Every function might contain instructions that cause "undefined behavior".
8241 getOrCreateAAFor<AAUndefinedBehavior>(FPos);
8242
Stefan Stipanovic53605892019-06-27 11:27:54 +00008243 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008244 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00008245
Stefan Stipanovic06263672019-07-11 21:37:40 +00008246 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008247 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00008248
Hideto Ueno65bbaf92019-07-12 17:38:51 +00008249 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008250 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00008251
Johannes Doerferte83f3032019-08-05 23:22:05 +00008252 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008253 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00008254
Hideto Ueno63f60662019-09-21 15:13:19 +00008255 // Every function might be "no-recurse".
8256 getOrCreateAAFor<AANoRecurse>(FPos);
8257
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008258 // Every function might be "readnone/readonly/writeonly/...".
8259 getOrCreateAAFor<AAMemoryBehavior>(FPos);
8260
Johannes Doerfert282f5d72020-01-26 02:51:57 -06008261 // Every function can be "readnone/argmemonly/inaccessiblememonly/...".
8262 getOrCreateAAFor<AAMemoryLocation>(FPos);
8263
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008264 // Every function might be applicable for Heap-To-Stack conversion.
8265 if (EnableHeapToStack)
8266 getOrCreateAAFor<AAHeapToStack>(FPos);
8267
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00008268 // Return attributes are only appropriate if the return type is non void.
8269 Type *ReturnType = F.getReturnType();
8270 if (!ReturnType->isVoidTy()) {
8271 // Argument attribute "returned" --- Create only one per function even
8272 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008273 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00008274
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008275 IRPosition RetPos = IRPosition::returned(F);
8276
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008277 // Every returned value might be dead.
8278 getOrCreateAAFor<AAIsDead>(RetPos);
8279
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008280 // Every function might be simplified.
8281 getOrCreateAAFor<AAValueSimplify>(RetPos);
8282
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00008283 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00008284
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00008285 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008286 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00008287
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00008288 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008289 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00008290
8291 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008292 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00008293
8294 // Every function with pointer return type might be marked
8295 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008296 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00008297 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00008298 }
8299
Hideto Ueno54869ec2019-07-15 06:49:04 +00008300 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008301 IRPosition ArgPos = IRPosition::argument(Arg);
8302
8303 // Every argument might be simplified.
8304 getOrCreateAAFor<AAValueSimplify>(ArgPos);
8305
Johannes Doerfert1e99fc92020-02-16 16:42:47 -06008306 // Every argument might be dead.
8307 getOrCreateAAFor<AAIsDead>(ArgPos);
8308
Hideto Ueno19c07af2019-07-23 08:16:17 +00008309 if (Arg.getType()->isPointerTy()) {
8310 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008311 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00008312
Hideto Uenocbab3342019-08-29 05:52:00 +00008313 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008314 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00008315
Hideto Ueno19c07af2019-07-23 08:16:17 +00008316 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008317 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00008318
8319 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008320 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00008321
8322 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008323 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008324
8325 // Every argument with pointer type might be marked
8326 // "readnone/readonly/writeonly/..."
8327 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01008328
8329 // Every argument with pointer type might be marked nofree.
8330 getOrCreateAAFor<AANoFree>(ArgPos);
Johannes Doerfert89c2e732019-10-30 17:20:20 -05008331
8332 // Every argument with pointer type might be privatizable (or promotable)
8333 getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00008334 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00008335 }
8336
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008337 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00008338 CallSite CS(&I);
Johannes Doerfert86509e82020-01-12 00:34:38 -06008339 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
8340
8341 // Call sites might be dead if they do not have side effects and no live
8342 // users. The return value might be dead if there are no live users.
8343 getOrCreateAAFor<AAIsDead>(CSRetPos);
8344
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008345 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05008346 // Skip declerations except if annotations on their call sites were
8347 // explicitly requested.
Johannes Doerfert139c9ef2019-12-13 23:41:02 -06008348 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
8349 !Callee->hasMetadata(LLVMContext::MD_callback))
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05008350 return true;
8351
8352 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09008353
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008354 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
8355
Hideto Ueno188f9a32020-01-15 15:25:52 +09008356 // Call site return integer values might be limited by a constant range.
Johannes Doerfert86509e82020-01-12 00:34:38 -06008357 if (Callee->getReturnType()->isIntegerTy())
Hideto Ueno188f9a32020-01-15 15:25:52 +09008358 getOrCreateAAFor<AAValueConstantRange>(CSRetPos);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008359 }
8360
Johannes Doerfert28880192019-12-31 00:57:00 -06008361 for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008362
8363 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
8364
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008365 // Every call site argument might be dead.
8366 getOrCreateAAFor<AAIsDead>(CSArgPos);
8367
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008368 // Call site argument might be simplified.
8369 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
8370
Hideto Ueno54869ec2019-07-15 06:49:04 +00008371 if (!CS.getArgument(i)->getType()->isPointerTy())
8372 continue;
8373
8374 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008375 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00008376
Hideto Uenocbab3342019-08-29 05:52:00 +00008377 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008378 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00008379
Hideto Ueno19c07af2019-07-23 08:16:17 +00008380 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008381 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00008382
8383 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00008384 getOrCreateAAFor<AAAlign>(CSArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01008385
Johannes Doerfert28880192019-12-31 00:57:00 -06008386 // Call site argument attribute
8387 // "readnone/readonly/writeonly/..."
8388 getOrCreateAAFor<AAMemoryBehavior>(CSArgPos);
8389
Hideto Ueno4ecf2552019-12-12 13:42:40 +00008390 // Call site argument attribute "nofree".
8391 getOrCreateAAFor<AANoFree>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00008392 }
8393 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008394 return true;
8395 };
8396
8397 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008398 bool Success;
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008399 Success = checkForAllInstructionsImpl(
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008400 nullptr, OpcodeInstMap, CallSitePred, nullptr, nullptr,
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008401 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
8402 (unsigned)Instruction::Call});
8403 (void)Success;
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008404 assert(Success && "Expected the check call to be successful!");
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008405
8406 auto LoadStorePred = [&](Instruction &I) -> bool {
8407 if (isa<LoadInst>(I))
8408 getOrCreateAAFor<AAAlign>(
8409 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
8410 else
8411 getOrCreateAAFor<AAAlign>(
8412 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
8413 return true;
8414 };
8415 Success = checkForAllInstructionsImpl(
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008416 nullptr, OpcodeInstMap, LoadStorePred, nullptr, nullptr,
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008417 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
8418 (void)Success;
Johannes Doerfert23f41f12020-01-12 01:09:22 -06008419 assert(Success && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00008420}
8421
8422/// Helpers to ease debugging through output streams and print calls.
8423///
8424///{
8425raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
8426 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
8427}
8428
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008429raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00008430 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00008431 case IRPosition::IRP_INVALID:
8432 return OS << "inv";
8433 case IRPosition::IRP_FLOAT:
8434 return OS << "flt";
8435 case IRPosition::IRP_RETURNED:
8436 return OS << "fn_ret";
8437 case IRPosition::IRP_CALL_SITE_RETURNED:
8438 return OS << "cs_ret";
8439 case IRPosition::IRP_FUNCTION:
8440 return OS << "fn";
8441 case IRPosition::IRP_CALL_SITE:
8442 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008443 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00008444 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008445 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00008446 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00008447 }
8448 llvm_unreachable("Unknown attribute position!");
8449}
8450
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008451raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00008452 const Value &AV = Pos.getAssociatedValue();
8453 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008454 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
8455}
8456
Johannes Doerfert1a746452019-10-20 22:28:49 -05008457template <typename base_ty, base_ty BestState, base_ty WorstState>
Hideto Ueno188f9a32020-01-15 15:25:52 +09008458raw_ostream &
8459llvm::operator<<(raw_ostream &OS,
8460 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00008461 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
8462 << static_cast<const AbstractState &>(S);
8463}
8464
Hideto Ueno188f9a32020-01-15 15:25:52 +09008465raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {
8466 OS << "range-state(" << S.getBitWidth() << ")<";
8467 S.getKnown().print(OS);
8468 OS << " / ";
8469 S.getAssumed().print(OS);
8470 OS << ">";
8471
8472 return OS << static_cast<const AbstractState &>(S);
8473}
8474
Johannes Doerfertaade7822019-06-05 03:02:24 +00008475raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
8476 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
8477}
8478
8479raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
8480 AA.print(OS);
8481 return OS;
8482}
8483
8484void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00008485 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
8486 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00008487}
8488///}
8489
8490/// ----------------------------------------------------------------------------
8491/// Pass (Manager) Boilerplate
8492/// ----------------------------------------------------------------------------
8493
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008494static bool runAttributorOnFunctions(InformationCache &InfoCache,
8495 SetVector<Function *> &Functions,
8496 AnalysisGetter &AG,
8497 CallGraphUpdater &CGUpdater) {
8498 if (DisableAttributor || Functions.empty())
Johannes Doerfertaade7822019-06-05 03:02:24 +00008499 return false;
8500
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008501 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << Functions.size()
Johannes Doerfertaade7822019-06-05 03:02:24 +00008502 << " functions.\n");
8503
8504 // Create an Attributor and initially empty information cache that is filled
8505 // while we identify default attribute opportunities.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008506 Attributor A(Functions, InfoCache, CGUpdater, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00008507
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008508 for (Function *F : Functions)
8509 A.initializeInformationCache(*F);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00008510
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008511 for (Function *F : Functions) {
8512 if (F->hasExactDefinition())
Johannes Doerfertb0412e42019-09-04 16:16:13 +00008513 NumFnWithExactDefinition++;
8514 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00008515 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00008516
Johannes Doerfert2f622062019-09-04 16:35:20 +00008517 // We look at internal functions only on-demand but if any use is not a
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008518 // direct call or outside the current set of analyzed functions, we have to
8519 // do it eagerly.
8520 if (F->hasLocalLinkage()) {
8521 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
8522 ImmutableCallSite ICS(U.getUser());
8523 return ICS && ICS.isCallee(&U) &&
8524 Functions.count(const_cast<Function *>(ICS.getCaller()));
Johannes Doerfert2f622062019-09-04 16:35:20 +00008525 }))
8526 continue;
8527 }
8528
Johannes Doerfertaade7822019-06-05 03:02:24 +00008529 // Populate the Attributor with abstract attribute opportunities in the
8530 // function and the information cache with IR information.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008531 A.identifyDefaultAbstractAttributes(*F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00008532 }
8533
Johannes Doerfert77a9e612020-01-11 23:36:17 -06008534 ChangeStatus Changed = A.run();
Fangrui Songfd5665a2020-02-14 21:47:19 -08008535 assert(!verifyModule(*Functions.front()->getParent(), &errs()) &&
8536 "Module verification failed!");
Johannes Doerfert77a9e612020-01-11 23:36:17 -06008537 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
8538 << " functions, result: " << Changed << ".\n");
8539 return Changed == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00008540}
8541
8542PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008543 FunctionAnalysisManager &FAM =
8544 AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
8545 AnalysisGetter AG(FAM);
8546
8547 SetVector<Function *> Functions;
8548 for (Function &F : M)
8549 Functions.insert(&F);
8550
8551 CallGraphUpdater CGUpdater;
8552 InformationCache InfoCache(M, AG, /* CGSCC */ nullptr);
8553 if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
8554 // FIXME: Think about passes we will preserve and add them here.
8555 return PreservedAnalyses::none();
8556 }
8557 return PreservedAnalyses::all();
8558}
8559
8560PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C,
8561 CGSCCAnalysisManager &AM,
8562 LazyCallGraph &CG,
8563 CGSCCUpdateResult &UR) {
8564 FunctionAnalysisManager &FAM =
8565 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
8566 AnalysisGetter AG(FAM);
8567
8568 SetVector<Function *> Functions;
8569 for (LazyCallGraph::Node &N : C)
8570 Functions.insert(&N.getFunction());
8571
8572 if (Functions.empty())
8573 return PreservedAnalyses::all();
8574
8575 Module &M = *Functions.back()->getParent();
8576 CallGraphUpdater CGUpdater;
8577 CGUpdater.initialize(CG, C, AM, UR);
8578 InformationCache InfoCache(M, AG, /* CGSCC */ &Functions);
8579 if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00008580 // FIXME: Think about passes we will preserve and add them here.
8581 return PreservedAnalyses::none();
8582 }
8583 return PreservedAnalyses::all();
8584}
8585
8586namespace {
8587
8588struct AttributorLegacyPass : public ModulePass {
8589 static char ID;
8590
8591 AttributorLegacyPass() : ModulePass(ID) {
8592 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
8593 }
8594
8595 bool runOnModule(Module &M) override {
8596 if (skipModule(M))
8597 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008598
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00008599 AnalysisGetter AG;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008600 SetVector<Function *> Functions;
8601 for (Function &F : M)
8602 Functions.insert(&F);
8603
8604 CallGraphUpdater CGUpdater;
8605 InformationCache InfoCache(M, AG, /* CGSCC */ nullptr);
8606 return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater);
Johannes Doerfertaade7822019-06-05 03:02:24 +00008607 }
8608
8609 void getAnalysisUsage(AnalysisUsage &AU) const override {
8610 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008611 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00008612 }
8613};
8614
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008615struct AttributorCGSCCLegacyPass : public CallGraphSCCPass {
8616 CallGraphUpdater CGUpdater;
8617 static char ID;
8618
8619 AttributorCGSCCLegacyPass() : CallGraphSCCPass(ID) {
8620 initializeAttributorCGSCCLegacyPassPass(*PassRegistry::getPassRegistry());
8621 }
8622
8623 bool runOnSCC(CallGraphSCC &SCC) override {
8624 if (skipSCC(SCC))
8625 return false;
8626
8627 SetVector<Function *> Functions;
8628 for (CallGraphNode *CGN : SCC)
8629 if (Function *Fn = CGN->getFunction())
8630 if (!Fn->isDeclaration())
8631 Functions.insert(Fn);
8632
8633 if (Functions.empty())
8634 return false;
8635
8636 AnalysisGetter AG;
8637 CallGraph &CG = const_cast<CallGraph &>(SCC.getCallGraph());
8638 CGUpdater.initialize(CG, SCC);
8639 Module &M = *Functions.back()->getParent();
8640 InformationCache InfoCache(M, AG, /* CGSCC */ &Functions);
8641 return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater);
8642 }
8643
8644 bool doFinalization(CallGraph &CG) override { return CGUpdater.finalize(); }
8645
8646 void getAnalysisUsage(AnalysisUsage &AU) const override {
8647 // FIXME: Think about passes we will preserve and add them here.
8648 AU.addRequired<TargetLibraryInfoWrapperPass>();
8649 CallGraphSCCPass::getAnalysisUsage(AU);
8650 }
8651};
8652
Johannes Doerfertaade7822019-06-05 03:02:24 +00008653} // end anonymous namespace
8654
8655Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008656Pass *llvm::createAttributorCGSCCLegacyPass() {
8657 return new AttributorCGSCCLegacyPass();
8658}
Johannes Doerfertaade7822019-06-05 03:02:24 +00008659
8660char AttributorLegacyPass::ID = 0;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008661char AttributorCGSCCLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008662
8663const char AAReturnedValues::ID = 0;
8664const char AANoUnwind::ID = 0;
8665const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00008666const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008667const char AANonNull::ID = 0;
8668const char AANoRecurse::ID = 0;
8669const char AAWillReturn::ID = 0;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06008670const char AAUndefinedBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008671const char AANoAlias::ID = 0;
Pankaj Gode04945c92019-11-22 18:40:47 +05308672const char AAReachability::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008673const char AANoReturn::ID = 0;
8674const char AAIsDead::ID = 0;
8675const char AADereferenceable::ID = 0;
8676const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00008677const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008678const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008679const char AAHeapToStack::ID = 0;
Johannes Doerfert89c2e732019-10-30 17:20:20 -05008680const char AAPrivatizablePtr::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008681const char AAMemoryBehavior::ID = 0;
Johannes Doerfert282f5d72020-01-26 02:51:57 -06008682const char AAMemoryLocation::ID = 0;
Hideto Ueno188f9a32020-01-15 15:25:52 +09008683const char AAValueConstantRange::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00008684
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008685// Macro magic to create the static generator function for attributes that
8686// follow the naming scheme.
8687
8688#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
8689 case IRPosition::PK: \
8690 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
8691
8692#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
8693 case IRPosition::PK: \
8694 AA = new CLASS##SUFFIX(IRP); \
8695 break;
8696
8697#define CREATE_FUNCTION_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_FLOAT, "floating") \
8703 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
8704 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
8705 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
8706 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
8707 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
8708 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
8709 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008710 return *AA; \
8711 }
8712
8713#define CREATE_VALUE_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_INV(CLASS, IRP_FUNCTION, "function") \
8719 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
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 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008726 return *AA; \
8727 }
8728
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008729#define CREATE_ALL_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_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
8735 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
8736 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
8737 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
8738 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
8739 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
8740 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
8741 } \
8742 return *AA; \
8743 }
8744
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008745#define CREATE_FUNCTION_ONLY_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_ARGUMENT, "argument") \
8751 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
8752 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
8753 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
8754 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
8755 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
8756 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
8757 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008758 return *AA; \
8759 }
8760
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008761#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
8762 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
8763 CLASS *AA = nullptr; \
8764 switch (IRP.getPositionKind()) { \
8765 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
8766 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
8767 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
8768 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
8769 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
8770 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
8771 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
8772 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
8773 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008774 return *AA; \
8775 }
8776
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008777CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
8778CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008779CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
8780CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
8781CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008782CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
Johannes Doerfert282f5d72020-01-26 02:51:57 -06008783CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryLocation)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008784
8785CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
8786CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
Johannes Doerfert89c2e732019-10-30 17:20:20 -05008787CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008788CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
8789CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00008790CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Hideto Ueno188f9a32020-01-15 15:25:52 +09008791CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008792
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008793CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05008794CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01008795CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008796
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008797CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
Pankaj Gode04945c92019-11-22 18:40:47 +05308798CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06008799CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008800
Johannes Doerfert1097fab2019-10-07 21:07:57 +00008801CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
8802
Johannes Doerfertd4bea882019-10-07 23:28:54 +00008803#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008804#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00008805#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008806#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00008807#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00008808#undef SWITCH_PK_CREATE
8809#undef SWITCH_PK_INV
8810
Johannes Doerfertaade7822019-06-05 03:02:24 +00008811INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
8812 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008813INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00008814INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
8815 "Deduce and propagate attributes", false, false)
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008816INITIALIZE_PASS_BEGIN(AttributorCGSCCLegacyPass, "attributor-cgscc",
8817 "Deduce and propagate attributes (CGSCC pass)", false,
8818 false)
8819INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
8820INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
8821INITIALIZE_PASS_END(AttributorCGSCCLegacyPass, "attributor-cgscc",
8822 "Deduce and propagate attributes (CGSCC pass)", false,
8823 false)