blob: 86968d1f7761bae725f96a1de00a1725f4d6ab33 [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)
Hideto Ueno188f9a32020-01-15 15:25:52 +0900137PIPE_OPERATOR(AAValueConstantRange)
Johannes Doerfert89c2e732019-10-30 17:20:20 -0500138PIPE_OPERATOR(AAPrivatizablePtr)
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600139
140#undef PIPE_OPERATOR
141} // namespace llvm
142
Johannes Doerfertaade7822019-06-05 03:02:24 +0000143// TODO: Determine a good default value.
144//
145// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
146// (when run with the first 5 abstract attributes). The results also indicate
147// that we never reach 32 iterations but always find a fixpoint sooner.
148//
149// This will become more evolved once we perform two interleaved fixpoint
150// iterations: bottom-up and top-down.
151static cl::opt<unsigned>
152 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
153 cl::desc("Maximal number of fixpoint iterations."),
154 cl::init(32));
Johannes Doerfertb504eb82019-08-26 18:55:47 +0000155static cl::opt<bool> VerifyMaxFixpointIterations(
156 "attributor-max-iterations-verify", cl::Hidden,
157 cl::desc("Verify that max-iterations is a tight bound for a fixpoint"),
158 cl::init(false));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000159
160static cl::opt<bool> DisableAttributor(
161 "attributor-disable", cl::Hidden,
162 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +0000163 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +0000164
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500165static cl::opt<bool> AnnotateDeclarationCallSites(
166 "attributor-annotate-decl-cs", cl::Hidden,
James Hendersond68904f2020-01-06 10:15:44 +0000167 cl::desc("Annotate call sites of function declarations."), cl::init(false));
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -0500168
Johannes Doerfert7516a5e2019-09-03 20:37:24 +0000169static cl::opt<bool> ManifestInternal(
170 "attributor-manifest-internal", cl::Hidden,
171 cl::desc("Manifest Attributor internal string attributes."),
172 cl::init(false));
173
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +0000174static cl::opt<unsigned> DepRecInterval(
175 "attributor-dependence-recompute-interval", cl::Hidden,
176 cl::desc("Number of iterations until dependences are recomputed."),
177 cl::init(4));
178
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000179static cl::opt<bool> EnableHeapToStack("enable-heap-to-stack-conversion",
180 cl::init(true), cl::Hidden);
181
Johannes Doerfert1c2afae2019-10-10 05:34:21 +0000182static cl::opt<int> MaxHeapToStackSize("max-heap-to-stack-size", cl::init(128),
183 cl::Hidden);
Stefan Stipanovic431141c2019-09-15 21:47:41 +0000184
Johannes Doerfertaade7822019-06-05 03:02:24 +0000185/// Logic operators for the change status enum class.
186///
187///{
188ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
189 return l == ChangeStatus::CHANGED ? l : r;
190}
191ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
192 return l == ChangeStatus::UNCHANGED ? l : r;
193}
194///}
195
Johannes Doerfertb1b441d2019-10-10 01:19:57 -0500196Argument *IRPosition::getAssociatedArgument() const {
197 if (getPositionKind() == IRP_ARGUMENT)
198 return cast<Argument>(&getAnchorValue());
199
200 // Not an Argument and no argument number means this is not a call site
201 // argument, thus we cannot find a callback argument to return.
202 int ArgNo = getArgNo();
203 if (ArgNo < 0)
204 return nullptr;
205
206 // Use abstract call sites to make the connection between the call site
207 // values and the ones in callbacks. If a callback was found that makes use
208 // of the underlying call site operand, we want the corresponding callback
209 // callee argument and not the direct callee argument.
210 Optional<Argument *> CBCandidateArg;
211 SmallVector<const Use *, 4> CBUses;
212 ImmutableCallSite ICS(&getAnchorValue());
213 AbstractCallSite::getCallbackUses(ICS, CBUses);
214 for (const Use *U : CBUses) {
215 AbstractCallSite ACS(U);
216 assert(ACS && ACS.isCallbackCall());
217 if (!ACS.getCalledFunction())
218 continue;
219
220 for (unsigned u = 0, e = ACS.getNumArgOperands(); u < e; u++) {
221
222 // Test if the underlying call site operand is argument number u of the
223 // callback callee.
224 if (ACS.getCallArgOperandNo(u) != ArgNo)
225 continue;
226
227 assert(ACS.getCalledFunction()->arg_size() > u &&
228 "ACS mapped into var-args arguments!");
229 if (CBCandidateArg.hasValue()) {
230 CBCandidateArg = nullptr;
231 break;
232 }
233 CBCandidateArg = ACS.getCalledFunction()->getArg(u);
234 }
235 }
236
237 // If we found a unique callback candidate argument, return it.
238 if (CBCandidateArg.hasValue() && CBCandidateArg.getValue())
239 return CBCandidateArg.getValue();
240
241 // If no callbacks were found, or none used the underlying call site operand
242 // exclusively, use the direct callee argument if available.
243 const Function *Callee = ICS.getCalledFunction();
244 if (Callee && Callee->arg_size() > unsigned(ArgNo))
245 return Callee->getArg(ArgNo);
246
247 return nullptr;
248}
249
Johannes Doerfert214ed3f2020-01-11 23:35:45 -0600250static Optional<ConstantInt *>
251getAssumedConstant(Attributor &A, const Value &V, const AbstractAttribute &AA,
252 bool &UsedAssumedInformation) {
253 const auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
254 AA, IRPosition::value(V), /* TrackDependence */ false);
255 Optional<Value *> SimplifiedV = ValueSimplifyAA.getAssumedSimplifiedValue(A);
256 bool IsKnown = ValueSimplifyAA.isKnown();
257 UsedAssumedInformation |= !IsKnown;
258 if (!SimplifiedV.hasValue()) {
259 A.recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
260 return llvm::None;
261 }
262 if (isa_and_nonnull<UndefValue>(SimplifiedV.getValue())) {
263 A.recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
264 return llvm::None;
265 }
266 ConstantInt *CI = dyn_cast_or_null<ConstantInt>(SimplifiedV.getValue());
267 if (CI)
268 A.recordDependence(ValueSimplifyAA, AA, DepClassTy::OPTIONAL);
269 return CI;
270}
271
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -0600272/// Get pointer operand of memory accessing instruction. If \p I is
273/// not a memory accessing instruction, return nullptr. If \p AllowVolatile,
274/// is set to false and the instruction is volatile, return nullptr.
275static const Value *getPointerOperand(const Instruction *I,
276 bool AllowVolatile) {
277 if (auto *LI = dyn_cast<LoadInst>(I)) {
278 if (!AllowVolatile && LI->isVolatile())
279 return nullptr;
280 return LI->getPointerOperand();
281 }
282
283 if (auto *SI = dyn_cast<StoreInst>(I)) {
284 if (!AllowVolatile && SI->isVolatile())
285 return nullptr;
286 return SI->getPointerOperand();
287 }
288
289 if (auto *CXI = dyn_cast<AtomicCmpXchgInst>(I)) {
290 if (!AllowVolatile && CXI->isVolatile())
291 return nullptr;
292 return CXI->getPointerOperand();
293 }
294
295 if (auto *RMWI = dyn_cast<AtomicRMWInst>(I)) {
296 if (!AllowVolatile && RMWI->isVolatile())
297 return nullptr;
298 return RMWI->getPointerOperand();
299 }
300
301 return nullptr;
302}
303
Johannes Doerfert89c2e732019-10-30 17:20:20 -0500304/// Helper function to create a pointer of type \p ResTy, based on \p Ptr, and
305/// advanced by \p Offset bytes. To aid later analysis the method tries to build
306/// getelement pointer instructions that traverse the natural type of \p Ptr if
307/// possible. If that fails, the remaining offset is adjusted byte-wise, hence
308/// through a cast to i8*.
309///
310/// TODO: This could probably live somewhere more prominantly if it doesn't
311/// already exist.
312static Value *constructPointer(Type *ResTy, Value *Ptr, int64_t Offset,
313 IRBuilder<NoFolder> &IRB, const DataLayout &DL) {
314 assert(Offset >= 0 && "Negative offset not supported yet!");
315 LLVM_DEBUG(dbgs() << "Construct pointer: " << *Ptr << " + " << Offset
316 << "-bytes as " << *ResTy << "\n");
317
318 // The initial type we are trying to traverse to get nice GEPs.
319 Type *Ty = Ptr->getType();
320
321 SmallVector<Value *, 4> Indices;
322 std::string GEPName = Ptr->getName().str();
323 while (Offset) {
324 uint64_t Idx, Rem;
325
326 if (auto *STy = dyn_cast<StructType>(Ty)) {
327 const StructLayout *SL = DL.getStructLayout(STy);
328 if (int64_t(SL->getSizeInBytes()) < Offset)
329 break;
330 Idx = SL->getElementContainingOffset(Offset);
331 assert(Idx < STy->getNumElements() && "Offset calculation error!");
332 Rem = Offset - SL->getElementOffset(Idx);
333 Ty = STy->getElementType(Idx);
334 } else if (auto *PTy = dyn_cast<PointerType>(Ty)) {
335 Ty = PTy->getElementType();
336 if (!Ty->isSized())
337 break;
338 uint64_t ElementSize = DL.getTypeAllocSize(Ty);
339 assert(ElementSize && "Expected type with size!");
340 Idx = Offset / ElementSize;
341 Rem = Offset % ElementSize;
342 } else {
343 // Non-aggregate type, we cast and make byte-wise progress now.
344 break;
345 }
346
347 LLVM_DEBUG(errs() << "Ty: " << *Ty << " Offset: " << Offset
348 << " Idx: " << Idx << " Rem: " << Rem << "\n");
349
350 GEPName += "." + std::to_string(Idx);
351 Indices.push_back(ConstantInt::get(IRB.getInt32Ty(), Idx));
352 Offset = Rem;
353 }
354
355 // Create a GEP if we collected indices above.
356 if (Indices.size())
357 Ptr = IRB.CreateGEP(Ptr, Indices, GEPName);
358
359 // If an offset is left we use byte-wise adjustment.
360 if (Offset) {
361 Ptr = IRB.CreateBitCast(Ptr, IRB.getInt8PtrTy());
362 Ptr = IRB.CreateGEP(Ptr, IRB.getInt32(Offset),
363 GEPName + ".b" + Twine(Offset));
364 }
365
366 // Ensure the result has the requested type.
367 Ptr = IRB.CreateBitOrPointerCast(Ptr, ResTy, Ptr->getName() + ".cast");
368
369 LLVM_DEBUG(dbgs() << "Constructed pointer: " << *Ptr << "\n");
370 return Ptr;
371}
372
Johannes Doerfertdef99282019-08-14 21:29:37 +0000373/// Recursively visit all values that might become \p IRP at some point. This
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000374/// will be done by looking through cast instructions, selects, phis, and calls
Johannes Doerfertdef99282019-08-14 21:29:37 +0000375/// with the "returned" attribute. Once we cannot look through the value any
376/// further, the callback \p VisitValueCB is invoked and passed the current
Johannes Doerfert52aec322020-02-11 15:11:32 -0600377/// value, the \p State, and a flag to indicate if we stripped anything.
378/// Stripped means that we unpacked the value associated with \p IRP at least
379/// once. Note that the value used for the callback may still be the value
380/// associated with \p IRP (due to PHIs). To limit how much effort is invested,
381/// we will never visit more values than specified by \p MaxValues.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000382template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000383static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000384 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000385 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000386 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000387
Johannes Doerfertdef99282019-08-14 21:29:37 +0000388 const AAIsDead *LivenessAA = nullptr;
389 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000390 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000391 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
392 /* TrackDependence */ false);
393 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000394
395 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000396 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000397 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000398 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000399
400 int Iteration = 0;
401 do {
402 Value *V = Worklist.pop_back_val();
403
404 // Check if we should process the current value. To prevent endless
405 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000406 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000407 continue;
408
409 // Make sure we limit the compile time for complex expressions.
410 if (Iteration++ >= MaxValues)
411 return false;
412
413 // Explicitly look through calls with a "returned" attribute if we do
414 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000415 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000416 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000417 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000418 } else {
419 CallSite CS(V);
420 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000421 for (Argument &Arg : CS.getCalledFunction()->args())
422 if (Arg.hasReturnedAttr()) {
423 NewV = CS.getArgOperand(Arg.getArgNo());
424 break;
425 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000426 }
427 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000428 if (NewV && NewV != V) {
429 Worklist.push_back(NewV);
430 continue;
431 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000432
433 // Look through select instructions, visit both potential values.
434 if (auto *SI = dyn_cast<SelectInst>(V)) {
435 Worklist.push_back(SI->getTrueValue());
436 Worklist.push_back(SI->getFalseValue());
437 continue;
438 }
439
Johannes Doerfertdef99282019-08-14 21:29:37 +0000440 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000441 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000442 assert(LivenessAA &&
443 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000444 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
445 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000446 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000447 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000448 continue;
449 }
450 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000451 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000452 continue;
453 }
454
455 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000456 if (!VisitValueCB(*V, State, Iteration > 1))
457 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000458 } while (!Worklist.empty());
459
Johannes Doerfert19b00432019-08-26 17:48:05 +0000460 // If we actually used liveness information so we have to record a dependence.
461 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -0500462 A.recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000463
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000464 // All values have been visited.
465 return true;
466}
467
Johannes Doerfertaade7822019-06-05 03:02:24 +0000468/// Return true if \p New is equal or worse than \p Old.
469static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
470 if (!Old.isIntAttribute())
471 return true;
472
473 return Old.getValueAsInt() >= New.getValueAsInt();
474}
475
476/// Return true if the information provided by \p Attr was added to the
477/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000478/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000479static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000480 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000481
482 if (Attr.isEnumAttribute()) {
483 Attribute::AttrKind Kind = Attr.getKindAsEnum();
484 if (Attrs.hasAttribute(AttrIdx, Kind))
485 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
486 return false;
487 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
488 return true;
489 }
490 if (Attr.isStringAttribute()) {
491 StringRef Kind = Attr.getKindAsString();
492 if (Attrs.hasAttribute(AttrIdx, Kind))
493 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
494 return false;
495 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
496 return true;
497 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000498 if (Attr.isIntAttribute()) {
499 Attribute::AttrKind Kind = Attr.getKindAsEnum();
500 if (Attrs.hasAttribute(AttrIdx, Kind))
501 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
502 return false;
503 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
504 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
505 return true;
506 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000507
508 llvm_unreachable("Expected enum or string attribute!");
509}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000510
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000511static const Value *
512getBasePointerOfAccessPointerOperand(const Instruction *I, int64_t &BytesOffset,
513 const DataLayout &DL,
514 bool AllowNonInbounds = false) {
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -0600515 const Value *Ptr = getPointerOperand(I, /* AllowVolatile */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000516 if (!Ptr)
517 return nullptr;
518
519 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000520 AllowNonInbounds);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000521}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000522
Johannes Doerfertece81902019-08-12 22:05:53 +0000523ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000524 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
525 if (getState().isAtFixpoint())
526 return HasChanged;
527
528 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
529
Johannes Doerfertece81902019-08-12 22:05:53 +0000530 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000531
532 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
533 << "\n");
534
535 return HasChanged;
536}
537
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000538ChangeStatus
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500539IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000540 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000541 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000542 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000543
Johannes Doerfertaade7822019-06-05 03:02:24 +0000544 // In the following some generic code that will manifest attributes in
545 // DeducedAttrs if they improve the current IR. Due to the different
546 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000547
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000548 AttributeList Attrs;
549 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000550 case IRPosition::IRP_INVALID:
551 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000552 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000553 case IRPosition::IRP_ARGUMENT:
554 case IRPosition::IRP_FUNCTION:
555 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000556 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000557 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000558 case IRPosition::IRP_CALL_SITE:
559 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000560 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000561 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000562 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000563 }
564
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000565 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000566 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000567 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000568 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000569 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000570
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000571 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000572 }
573
574 if (HasChanged == ChangeStatus::UNCHANGED)
575 return HasChanged;
576
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000577 switch (PK) {
578 case IRPosition::IRP_ARGUMENT:
579 case IRPosition::IRP_FUNCTION:
580 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000581 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000582 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000583 case IRPosition::IRP_CALL_SITE:
584 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000585 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000586 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000587 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000588 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000589 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000590 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000591 }
592
593 return HasChanged;
594}
595
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000596const IRPosition IRPosition::EmptyKey(255);
597const IRPosition IRPosition::TombstoneKey(256);
598
599SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
600 IRPositions.emplace_back(IRP);
601
602 ImmutableCallSite ICS(&IRP.getAnchorValue());
603 switch (IRP.getPositionKind()) {
604 case IRPosition::IRP_INVALID:
605 case IRPosition::IRP_FLOAT:
606 case IRPosition::IRP_FUNCTION:
607 return;
608 case IRPosition::IRP_ARGUMENT:
609 case IRPosition::IRP_RETURNED:
610 IRPositions.emplace_back(
611 IRPosition::function(*IRP.getAssociatedFunction()));
612 return;
613 case IRPosition::IRP_CALL_SITE:
614 assert(ICS && "Expected call site!");
615 // TODO: We need to look at the operand bundles similar to the redirection
616 // in CallBase.
617 if (!ICS.hasOperandBundles())
618 if (const Function *Callee = ICS.getCalledFunction())
619 IRPositions.emplace_back(IRPosition::function(*Callee));
620 return;
621 case IRPosition::IRP_CALL_SITE_RETURNED:
622 assert(ICS && "Expected call site!");
623 // TODO: We need to look at the operand bundles similar to the redirection
624 // in CallBase.
625 if (!ICS.hasOperandBundles()) {
626 if (const Function *Callee = ICS.getCalledFunction()) {
627 IRPositions.emplace_back(IRPosition::returned(*Callee));
628 IRPositions.emplace_back(IRPosition::function(*Callee));
629 }
630 }
631 IRPositions.emplace_back(
632 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
633 return;
634 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
635 int ArgNo = IRP.getArgNo();
636 assert(ICS && ArgNo >= 0 && "Expected call site!");
637 // TODO: We need to look at the operand bundles similar to the redirection
638 // in CallBase.
639 if (!ICS.hasOperandBundles()) {
640 const Function *Callee = ICS.getCalledFunction();
641 if (Callee && Callee->arg_size() > unsigned(ArgNo))
642 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
643 if (Callee)
644 IRPositions.emplace_back(IRPosition::function(*Callee));
645 }
646 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
647 return;
648 }
649 }
650}
651
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000652bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
653 bool IgnoreSubsumingPositions) const {
654 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000655 for (Attribute::AttrKind AK : AKs)
656 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
657 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000658 // The first position returned by the SubsumingPositionIterator is
659 // always the position itself. If we ignore subsuming positions we
660 // are done after the first iteration.
661 if (IgnoreSubsumingPositions)
662 break;
663 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000664 return false;
665}
666
667void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600668 SmallVectorImpl<Attribute> &Attrs,
669 bool IgnoreSubsumingPositions) const {
670 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000671 for (Attribute::AttrKind AK : AKs) {
672 const Attribute &Attr = EquivIRP.getAttr(AK);
673 if (Attr.getKindAsEnum() == AK)
674 Attrs.push_back(Attr);
675 }
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600676 // The first position returned by the SubsumingPositionIterator is
677 // always the position itself. If we ignore subsuming positions we
678 // are done after the first iteration.
679 if (IgnoreSubsumingPositions)
680 break;
681 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000682}
683
684void IRPosition::verify() {
685 switch (KindOrArgNo) {
686 default:
687 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
688 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
689 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000690 if (isa<Argument>(AnchorVal)) {
691 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000692 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000693 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
694 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000695 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000696 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000697 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000698 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
699 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000700 "Associated value mismatch!");
701 }
702 break;
703 case IRP_INVALID:
704 assert(!AnchorVal && "Expected no value for an invalid position!");
705 break;
706 case IRP_FLOAT:
707 assert((!isa<CallBase>(&getAssociatedValue()) &&
708 !isa<Argument>(&getAssociatedValue())) &&
709 "Expected specialized kind for call base and argument values!");
710 break;
711 case IRP_RETURNED:
712 assert(isa<Function>(AnchorVal) &&
713 "Expected function for a 'returned' position!");
714 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
715 break;
716 case IRP_CALL_SITE_RETURNED:
717 assert((isa<CallBase>(AnchorVal)) &&
718 "Expected call base for 'call site returned' position!");
719 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
720 break;
721 case IRP_CALL_SITE:
722 assert((isa<CallBase>(AnchorVal)) &&
723 "Expected call base for 'call site function' position!");
724 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
725 break;
726 case IRP_FUNCTION:
727 assert(isa<Function>(AnchorVal) &&
728 "Expected function for a 'function' position!");
729 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
730 break;
731 }
732}
733
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000734namespace {
Johannes Doerfert1a746452019-10-20 22:28:49 -0500735/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000736/// information in \p R and indicate/return if \p S did change (as-in update is
737/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000738template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500739ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000740 auto Assumed = S.getAssumed();
741 S ^= R;
742 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
743 : ChangeStatus::CHANGED;
744}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000745
Johannes Doerfert234eda52019-08-16 19:51:23 +0000746/// Clamp the information known for all returned values of a function
747/// (identified by \p QueryingAA) into \p S.
748template <typename AAType, typename StateType = typename AAType::StateType>
749static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
750 StateType &S) {
751 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600752 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000753
754 assert((QueryingAA.getIRPosition().getPositionKind() ==
755 IRPosition::IRP_RETURNED ||
756 QueryingAA.getIRPosition().getPositionKind() ==
757 IRPosition::IRP_CALL_SITE_RETURNED) &&
758 "Can only clamp returned value states for a function returned or call "
759 "site returned position!");
760
761 // Use an optional state as there might not be any return values and we want
762 // to join (IntegerState::operator&) the state of all there are.
763 Optional<StateType> T;
764
765 // Callback for each possibly returned value.
766 auto CheckReturnValue = [&](Value &RV) -> bool {
767 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000768 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
769 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
770 << " @ " << RVPos << "\n");
771 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000772 if (T.hasValue())
773 *T &= AAS;
774 else
775 T = AAS;
776 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
777 << "\n");
778 return T->isValidState();
779 };
780
781 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
782 S.indicatePessimisticFixpoint();
783 else if (T.hasValue())
784 S ^= *T;
785}
786
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000787/// Helper class to compose two generic deduction
788template <typename AAType, typename Base, typename StateType,
789 template <typename...> class F, template <typename...> class G>
790struct AAComposeTwoGenericDeduction
791 : public F<AAType, G<AAType, Base, StateType>, StateType> {
792 AAComposeTwoGenericDeduction(const IRPosition &IRP)
793 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
794
795 /// See AbstractAttribute::updateImpl(...).
796 ChangeStatus updateImpl(Attributor &A) override {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100797 ChangeStatus ChangedF =
798 F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000799 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
800 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000801 }
802};
803
Johannes Doerfert234eda52019-08-16 19:51:23 +0000804/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000805template <typename AAType, typename Base,
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600806 typename StateType = typename Base::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000807struct AAReturnedFromReturnedValues : public Base {
808 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000809
810 /// See AbstractAttribute::updateImpl(...).
811 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600812 StateType S(StateType::getBestState(this->getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000813 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000814 // TODO: If we know we visited all returned values, thus no are assumed
815 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000816 return clampStateAndIndicateChange<StateType>(this->getState(), S);
817 }
818};
819
820/// Clamp the information known at all call sites for a given argument
821/// (identified by \p QueryingAA) into \p S.
822template <typename AAType, typename StateType = typename AAType::StateType>
823static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
824 StateType &S) {
825 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600826 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000827
828 assert(QueryingAA.getIRPosition().getPositionKind() ==
829 IRPosition::IRP_ARGUMENT &&
830 "Can only clamp call site argument states for an argument position!");
831
832 // Use an optional state as there might not be any return values and we want
833 // to join (IntegerState::operator&) the state of all there are.
834 Optional<StateType> T;
835
836 // The argument number which is also the call site argument number.
837 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
838
Johannes Doerfert661db042019-10-07 23:14:58 +0000839 auto CallSiteCheck = [&](AbstractCallSite ACS) {
840 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
841 // Check if a coresponding argument was found or if it is on not associated
842 // (which can happen for callback calls).
843 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
844 return false;
845
846 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
847 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
848 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000849 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000850 if (T.hasValue())
851 *T &= AAS;
852 else
853 T = AAS;
854 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
855 << "\n");
856 return T->isValidState();
857 };
858
Johannes Doerfert368f7ee2019-12-30 16:12:36 -0600859 bool AllCallSitesKnown;
860 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
861 AllCallSitesKnown))
Johannes Doerfert234eda52019-08-16 19:51:23 +0000862 S.indicatePessimisticFixpoint();
863 else if (T.hasValue())
864 S ^= *T;
865}
866
867/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000868template <typename AAType, typename Base,
869 typename StateType = typename AAType::StateType>
870struct AAArgumentFromCallSiteArguments : public Base {
871 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000872
873 /// See AbstractAttribute::updateImpl(...).
874 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertea5fabe2020-01-28 09:46:15 -0600875 StateType S(StateType::getBestState(this->getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000876 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000877 // TODO: If we know we visited all incoming values, thus no are assumed
878 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000879 return clampStateAndIndicateChange<StateType>(this->getState(), S);
880 }
881};
882
883/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000884template <typename AAType, typename Base,
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600885 typename StateType = typename Base::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000886struct AACallSiteReturnedFromReturned : public Base {
887 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000888
889 /// See AbstractAttribute::updateImpl(...).
890 ChangeStatus updateImpl(Attributor &A) override {
891 assert(this->getIRPosition().getPositionKind() ==
892 IRPosition::IRP_CALL_SITE_RETURNED &&
893 "Can only wrap function returned positions for call site returned "
894 "positions!");
895 auto &S = this->getState();
896
897 const Function *AssociatedFunction =
898 this->getIRPosition().getAssociatedFunction();
899 if (!AssociatedFunction)
900 return S.indicatePessimisticFixpoint();
901
902 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000903 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000904 return clampStateAndIndicateChange(
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600905 S, static_cast<const StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000906 }
907};
908
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000909/// Helper class for generic deduction using must-be-executed-context
910/// Base class is required to have `followUse` method.
911
912/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000913/// U - Underlying use.
914/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000915/// `followUse` returns true if the value should be tracked transitively.
916
917template <typename AAType, typename Base,
918 typename StateType = typename AAType::StateType>
919struct AAFromMustBeExecutedContext : public Base {
920 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
921
922 void initialize(Attributor &A) override {
923 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500924 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000925 Instruction *CtxI = IRP.getCtxI();
926
927 if (!CtxI)
928 return;
929
930 for (const Use &U : IRP.getAssociatedValue().uses())
931 Uses.insert(&U);
932 }
933
934 /// See AbstractAttribute::updateImpl(...).
935 ChangeStatus updateImpl(Attributor &A) override {
936 auto BeforeState = this->getState();
937 auto &S = this->getState();
938 Instruction *CtxI = this->getIRPosition().getCtxI();
939 if (!CtxI)
940 return ChangeStatus::UNCHANGED;
941
942 MustBeExecutedContextExplorer &Explorer =
943 A.getInfoCache().getMustBeExecutedContextExplorer();
944
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500945 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100946 for (unsigned u = 0; u < Uses.size(); ++u) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500947 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000948 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500949 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000950 if (Found && Base::followUse(A, U, UserI))
951 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500952 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000953 }
954 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000955
956 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
957 }
958
959private:
960 /// Container for (transitive) uses of the associated value.
961 SetVector<const Use *> Uses;
962};
963
964template <typename AAType, typename Base,
965 typename StateType = typename AAType::StateType>
966using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
967 AAComposeTwoGenericDeduction<AAType, Base, StateType,
968 AAFromMustBeExecutedContext,
969 AAArgumentFromCallSiteArguments>;
970
971template <typename AAType, typename Base,
972 typename StateType = typename AAType::StateType>
973using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
974 AAComposeTwoGenericDeduction<AAType, Base, StateType,
975 AAFromMustBeExecutedContext,
976 AACallSiteReturnedFromReturned>;
977
Stefan Stipanovic53605892019-06-27 11:27:54 +0000978/// -----------------------NoUnwind Function Attribute--------------------------
979
Johannes Doerfert344d0382019-08-07 22:34:26 +0000980struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000981 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000982
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000983 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000984 return getAssumed() ? "nounwind" : "may-unwind";
985 }
986
987 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000988 ChangeStatus updateImpl(Attributor &A) override {
989 auto Opcodes = {
990 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
991 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
992 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
993
994 auto CheckForNoUnwind = [&](Instruction &I) {
995 if (!I.mayThrow())
996 return true;
997
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000998 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
999 const auto &NoUnwindAA =
1000 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
1001 return NoUnwindAA.isAssumedNoUnwind();
1002 }
1003 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001004 };
1005
1006 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
1007 return indicatePessimisticFixpoint();
1008
1009 return ChangeStatus::UNCHANGED;
1010 }
Stefan Stipanovic53605892019-06-27 11:27:54 +00001011};
1012
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001013struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001014 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001015
1016 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001017 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001018};
1019
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001020/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001021struct AANoUnwindCallSite final : AANoUnwindImpl {
1022 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
1023
1024 /// See AbstractAttribute::initialize(...).
1025 void initialize(Attributor &A) override {
1026 AANoUnwindImpl::initialize(A);
1027 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001028 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001029 indicatePessimisticFixpoint();
1030 }
1031
1032 /// See AbstractAttribute::updateImpl(...).
1033 ChangeStatus updateImpl(Attributor &A) override {
1034 // TODO: Once we have call site specific value information we can provide
1035 // call site specific liveness information and then it makes
1036 // sense to specialize attributes for call sites arguments instead of
1037 // redirecting requests to the callee argument.
1038 Function *F = getAssociatedFunction();
1039 const IRPosition &FnPos = IRPosition::function(*F);
1040 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
1041 return clampStateAndIndicateChange(
1042 getState(),
1043 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
1044 }
1045
1046 /// See AbstractAttribute::trackStatistics()
1047 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
1048};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001049
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001050/// --------------------- Function Return Values -------------------------------
1051
1052/// "Attribute" that collects all potential returned values and the return
1053/// instructions that they arise from.
1054///
1055/// If there is a unique returned value R, the manifest method will:
1056/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +00001057class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001058
1059 /// Mapping of values potentially returned by the associated function to the
1060 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +00001061 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001062
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001063 /// Mapping to remember the number of returned values for a call site such
1064 /// that we can avoid updates if nothing changed.
1065 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
1066
1067 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001068 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001069
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001070 /// State flags
1071 ///
1072 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001073 bool IsFixed = false;
1074 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001075 ///}
1076
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001077public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001078 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001079
1080 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001081 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001082 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001083 IsFixed = false;
1084 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001085 ReturnedValues.clear();
1086
Johannes Doerfertdef99282019-08-14 21:29:37 +00001087 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001088 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001089 indicatePessimisticFixpoint();
1090 return;
1091 }
Johannes Doerferte273ac42020-01-12 00:13:03 -06001092 assert(!F->getReturnType()->isVoidTy() &&
1093 "Did not expect a void return type!");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001094
1095 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001096 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001097
1098 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001099 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001100 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001101 auto &ReturnInstSet = ReturnedValues[&Arg];
1102 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
1103 ReturnInstSet.insert(cast<ReturnInst>(RI));
1104
1105 indicateOptimisticFixpoint();
1106 return;
1107 }
1108 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001109
1110 if (!F->hasExactDefinition())
1111 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001112 }
1113
1114 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001115 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001116
1117 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001118 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001119
1120 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001121 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001122
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001123 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00001124 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001125
Johannes Doerfertdef99282019-08-14 21:29:37 +00001126 llvm::iterator_range<iterator> returned_values() override {
1127 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1128 }
1129
1130 llvm::iterator_range<const_iterator> returned_values() const override {
1131 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1132 }
1133
Johannes Doerfert695089e2019-08-23 15:23:49 +00001134 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001135 return UnresolvedCalls;
1136 }
1137
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001138 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001139 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001140 return isValidState() ? ReturnedValues.size() : -1;
1141 }
1142
1143 /// Return an assumed unique return value if a single candidate is found. If
1144 /// there cannot be one, return a nullptr. If it is not clear yet, return the
1145 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001146 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001147
Johannes Doerfert14a04932019-08-07 22:27:24 +00001148 /// See AbstractState::checkForAllReturnedValues(...).
1149 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001150 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001151 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001152
1153 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001154 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001155
1156 /// See AbstractState::isAtFixpoint().
1157 bool isAtFixpoint() const override { return IsFixed; }
1158
1159 /// See AbstractState::isValidState().
1160 bool isValidState() const override { return IsValidState; }
1161
1162 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001163 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001164 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001165 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001166 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001167
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001168 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001169 IsFixed = true;
1170 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001171 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001172 }
1173};
1174
1175ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
1176 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1177
1178 // Bookkeeping.
1179 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001180 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
1181 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001182
1183 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001184 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001185
1186 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
1187 return Changed;
1188
1189 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001190 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
1191 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001192
Johannes Doerfert23400e612019-08-23 17:41:37 +00001193 // Callback to replace the uses of CB with the constant C.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06001194 auto ReplaceCallSiteUsersWith = [&A](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +00001195 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +00001196 return ChangeStatus::UNCHANGED;
Johannes Doerfert4c62a352020-01-12 00:17:08 -06001197 if (A.changeValueAfterManifest(CB, C))
1198 return ChangeStatus::CHANGED;
1199 return ChangeStatus::UNCHANGED;
Johannes Doerfert23400e612019-08-23 17:41:37 +00001200 };
1201
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001202 // If the assumed unique return value is an argument, annotate it.
1203 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05001204 // TODO: This should be handled differently!
1205 this->AnchorVal = UniqueRVArg;
1206 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +00001207 Changed = IRAttribute::manifest(A);
1208 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
1209 // We can replace the returned value with the unique returned constant.
1210 Value &AnchorValue = getAnchorValue();
1211 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1212 for (const Use &U : F->uses())
1213 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001214 if (CB->isCallee(&U)) {
1215 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001216 CB->getType() == RVC->getType()
1217 ? RVC
1218 : ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001219 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1220 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001221 } else {
1222 assert(isa<CallBase>(AnchorValue) &&
1223 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001224 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001225 AnchorValue.getType() == RVC->getType()
1226 ? RVC
1227 : ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001228 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001229 }
1230 if (Changed == ChangeStatus::CHANGED)
1231 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1232 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001233 }
1234
1235 return Changed;
1236}
1237
1238const std::string AAReturnedValuesImpl::getAsStr() const {
1239 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001240 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001241 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001242}
1243
Johannes Doerfert14a04932019-08-07 22:27:24 +00001244Optional<Value *>
1245AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1246 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001247 // undef values that can also be present, it is assumed to be the actual
1248 // return value and forwarded to the caller of this method. If there are
1249 // multiple, a nullptr is returned indicating there cannot be a unique
1250 // returned value.
1251 Optional<Value *> UniqueRV;
1252
Johannes Doerfert14a04932019-08-07 22:27:24 +00001253 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001254 // If we found a second returned value and neither the current nor the saved
1255 // one is an undef, there is no unique returned value. Undefs are special
1256 // since we can pretend they have any value.
1257 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1258 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1259 UniqueRV = nullptr;
1260 return false;
1261 }
1262
1263 // Do not overwrite a value with an undef.
1264 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1265 UniqueRV = &RV;
1266
1267 return true;
1268 };
1269
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001270 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001271 UniqueRV = nullptr;
1272
1273 return UniqueRV;
1274}
1275
Johannes Doerfert14a04932019-08-07 22:27:24 +00001276bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001277 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001278 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001279 if (!isValidState())
1280 return false;
1281
1282 // Check all returned values but ignore call sites as long as we have not
1283 // encountered an overdefined one during an update.
1284 for (auto &It : ReturnedValues) {
1285 Value *RV = It.first;
1286
Johannes Doerfertdef99282019-08-14 21:29:37 +00001287 CallBase *CB = dyn_cast<CallBase>(RV);
1288 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001289 continue;
1290
Johannes Doerfert695089e2019-08-23 15:23:49 +00001291 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001292 return false;
1293 }
1294
1295 return true;
1296}
1297
Johannes Doerfertece81902019-08-12 22:05:53 +00001298ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001299 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1300 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001301
Johannes Doerfertdef99282019-08-14 21:29:37 +00001302 // State used in the value traversals starting in returned values.
1303 struct RVState {
1304 // The map in which we collect return values -> return instrs.
1305 decltype(ReturnedValues) &RetValsMap;
1306 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001307 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001308 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001309 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001310 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001311
Johannes Doerfertdef99282019-08-14 21:29:37 +00001312 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001313 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001314 auto Size = RVS.RetValsMap[&Val].size();
1315 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1316 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1317 RVS.Changed |= Inserted;
1318 LLVM_DEBUG({
1319 if (Inserted)
1320 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1321 << " => " << RVS.RetInsts.size() << "\n";
1322 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001323 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001324 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001325
Johannes Doerfertdef99282019-08-14 21:29:37 +00001326 // Helper method to invoke the generic value traversal.
1327 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1328 IRPosition RetValPos = IRPosition::value(RV);
1329 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1330 RVS, VisitValueCB);
1331 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001332
Johannes Doerfertdef99282019-08-14 21:29:37 +00001333 // Callback for all "return intructions" live in the associated function.
1334 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1335 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001336 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001337 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001338 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1339 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001340
Johannes Doerfertdef99282019-08-14 21:29:37 +00001341 // Start by discovering returned values from all live returned instructions in
1342 // the associated function.
1343 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1344 return indicatePessimisticFixpoint();
1345
1346 // Once returned values "directly" present in the code are handled we try to
1347 // resolve returned calls.
1348 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001349 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001350 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1351 << " by #" << It.second.size() << " RIs\n");
1352 CallBase *CB = dyn_cast<CallBase>(It.first);
1353 if (!CB || UnresolvedCalls.count(CB))
1354 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001355
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001356 if (!CB->getCalledFunction()) {
1357 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1358 << "\n");
1359 UnresolvedCalls.insert(CB);
1360 continue;
1361 }
1362
1363 // TODO: use the function scope once we have call site AAReturnedValues.
1364 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1365 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001366 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06001367 << RetValAA << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001368
1369 // Skip dead ends, thus if we do not know anything about the returned
1370 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001371 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001372 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1373 << "\n");
1374 UnresolvedCalls.insert(CB);
1375 continue;
1376 }
1377
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001378 // Do not try to learn partial information. If the callee has unresolved
1379 // return values we will treat the call as unresolved/opaque.
1380 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1381 if (!RetValAAUnresolvedCalls.empty()) {
1382 UnresolvedCalls.insert(CB);
1383 continue;
1384 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001385
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001386 // Now check if we can track transitively returned values. If possible, thus
1387 // if all return value can be represented in the current scope, do so.
1388 bool Unresolved = false;
1389 for (auto &RetValAAIt : RetValAA.returned_values()) {
1390 Value *RetVal = RetValAAIt.first;
1391 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1392 isa<Constant>(RetVal))
1393 continue;
1394 // Anything that did not fit in the above categories cannot be resolved,
1395 // mark the call as unresolved.
1396 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1397 "cannot be translated: "
1398 << *RetVal << "\n");
1399 UnresolvedCalls.insert(CB);
1400 Unresolved = true;
1401 break;
1402 }
1403
1404 if (Unresolved)
1405 continue;
1406
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001407 // Now track transitively returned values.
1408 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1409 if (NumRetAA == RetValAA.getNumReturnValues()) {
1410 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1411 "changed since it was seen last\n");
1412 continue;
1413 }
1414 NumRetAA = RetValAA.getNumReturnValues();
1415
Johannes Doerfertdef99282019-08-14 21:29:37 +00001416 for (auto &RetValAAIt : RetValAA.returned_values()) {
1417 Value *RetVal = RetValAAIt.first;
1418 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1419 // Arguments are mapped to call site operands and we begin the traversal
1420 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001421 bool Unused = false;
1422 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001423 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1424 continue;
1425 } else if (isa<CallBase>(RetVal)) {
1426 // Call sites are resolved by the callee attribute over time, no need to
1427 // do anything for us.
1428 continue;
1429 } else if (isa<Constant>(RetVal)) {
1430 // Constants are valid everywhere, we can simply take them.
1431 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1432 continue;
1433 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001434 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001435 }
1436
Johannes Doerfertdef99282019-08-14 21:29:37 +00001437 // To avoid modifications to the ReturnedValues map while we iterate over it
1438 // we kept record of potential new entries in a copy map, NewRVsMap.
1439 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001440 assert(!It.second.empty() && "Entry does not add anything.");
1441 auto &ReturnInsts = ReturnedValues[It.first];
1442 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001443 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001444 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1445 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001446 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001447 }
1448 }
1449
Johannes Doerfertdef99282019-08-14 21:29:37 +00001450 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1451 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001452}
1453
Johannes Doerfertdef99282019-08-14 21:29:37 +00001454struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1455 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1456
1457 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001458 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001459};
1460
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001461/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001462struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1463 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1464
1465 /// See AbstractAttribute::initialize(...).
1466 void initialize(Attributor &A) override {
1467 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001468 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001469 // sense to specialize attributes for call sites instead of
1470 // redirecting requests to the callee.
1471 llvm_unreachable("Abstract attributes for returned values are not "
1472 "supported for call sites yet!");
1473 }
1474
1475 /// See AbstractAttribute::updateImpl(...).
1476 ChangeStatus updateImpl(Attributor &A) override {
1477 return indicatePessimisticFixpoint();
1478 }
1479
1480 /// See AbstractAttribute::trackStatistics()
1481 void trackStatistics() const override {}
1482};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001483
Stefan Stipanovic06263672019-07-11 21:37:40 +00001484/// ------------------------ NoSync Function Attribute -------------------------
1485
Johannes Doerfert344d0382019-08-07 22:34:26 +00001486struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001487 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001488
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001489 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001490 return getAssumed() ? "nosync" : "may-sync";
1491 }
1492
1493 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001494 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001495
Stefan Stipanovic06263672019-07-11 21:37:40 +00001496 /// Helper function used to determine whether an instruction is non-relaxed
1497 /// atomic. In other words, if an atomic instruction does not have unordered
1498 /// or monotonic ordering
1499 static bool isNonRelaxedAtomic(Instruction *I);
1500
1501 /// Helper function used to determine whether an instruction is volatile.
1502 static bool isVolatile(Instruction *I);
1503
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001504 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1505 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001506 static bool isNoSyncIntrinsic(Instruction *I);
1507};
1508
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001509bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001510 if (!I->isAtomic())
1511 return false;
1512
1513 AtomicOrdering Ordering;
1514 switch (I->getOpcode()) {
1515 case Instruction::AtomicRMW:
1516 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1517 break;
1518 case Instruction::Store:
1519 Ordering = cast<StoreInst>(I)->getOrdering();
1520 break;
1521 case Instruction::Load:
1522 Ordering = cast<LoadInst>(I)->getOrdering();
1523 break;
1524 case Instruction::Fence: {
1525 auto *FI = cast<FenceInst>(I);
1526 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1527 return false;
1528 Ordering = FI->getOrdering();
1529 break;
1530 }
1531 case Instruction::AtomicCmpXchg: {
1532 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1533 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1534 // Only if both are relaxed, than it can be treated as relaxed.
1535 // Otherwise it is non-relaxed.
1536 if (Success != AtomicOrdering::Unordered &&
1537 Success != AtomicOrdering::Monotonic)
1538 return true;
1539 if (Failure != AtomicOrdering::Unordered &&
1540 Failure != AtomicOrdering::Monotonic)
1541 return true;
1542 return false;
1543 }
1544 default:
1545 llvm_unreachable(
1546 "New atomic operations need to be known in the attributor.");
1547 }
1548
1549 // Relaxed.
1550 if (Ordering == AtomicOrdering::Unordered ||
1551 Ordering == AtomicOrdering::Monotonic)
1552 return false;
1553 return true;
1554}
1555
1556/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1557/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001558bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001559 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1560 switch (II->getIntrinsicID()) {
1561 /// Element wise atomic memory intrinsics are can only be unordered,
1562 /// therefore nosync.
1563 case Intrinsic::memset_element_unordered_atomic:
1564 case Intrinsic::memmove_element_unordered_atomic:
1565 case Intrinsic::memcpy_element_unordered_atomic:
1566 return true;
1567 case Intrinsic::memset:
1568 case Intrinsic::memmove:
1569 case Intrinsic::memcpy:
1570 if (!cast<MemIntrinsic>(II)->isVolatile())
1571 return true;
1572 return false;
1573 default:
1574 return false;
1575 }
1576 }
1577 return false;
1578}
1579
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001580bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001581 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1582 "Calls should not be checked here");
1583
1584 switch (I->getOpcode()) {
1585 case Instruction::AtomicRMW:
1586 return cast<AtomicRMWInst>(I)->isVolatile();
1587 case Instruction::Store:
1588 return cast<StoreInst>(I)->isVolatile();
1589 case Instruction::Load:
1590 return cast<LoadInst>(I)->isVolatile();
1591 case Instruction::AtomicCmpXchg:
1592 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1593 default:
1594 return false;
1595 }
1596}
1597
Johannes Doerfertece81902019-08-12 22:05:53 +00001598ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001599
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001600 auto CheckRWInstForNoSync = [&](Instruction &I) {
1601 /// We are looking for volatile instructions or Non-Relaxed atomics.
Pankaj Godeb9a26a82019-11-22 14:46:43 +05301602 /// FIXME: We should improve the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001603
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001604 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1605 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001606
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001607 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1608 if (ICS.hasFnAttr(Attribute::NoSync))
1609 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001610
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001611 const auto &NoSyncAA =
1612 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1613 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001614 return true;
1615 return false;
1616 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001617
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001618 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1619 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001620
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001621 return false;
1622 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001623
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001624 auto CheckForNoSync = [&](Instruction &I) {
1625 // At this point we handled all read/write effects and they are all
1626 // nosync, so they can be skipped.
1627 if (I.mayReadOrWriteMemory())
1628 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001629
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001630 // non-convergent and readnone imply nosync.
1631 return !ImmutableCallSite(&I).isConvergent();
1632 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001633
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001634 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1635 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001636 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001637
Stefan Stipanovic06263672019-07-11 21:37:40 +00001638 return ChangeStatus::UNCHANGED;
1639}
1640
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001641struct AANoSyncFunction final : public AANoSyncImpl {
1642 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1643
1644 /// See AbstractAttribute::trackStatistics()
1645 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1646};
1647
1648/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001649struct AANoSyncCallSite final : AANoSyncImpl {
1650 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1651
1652 /// See AbstractAttribute::initialize(...).
1653 void initialize(Attributor &A) override {
1654 AANoSyncImpl::initialize(A);
1655 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001656 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001657 indicatePessimisticFixpoint();
1658 }
1659
1660 /// See AbstractAttribute::updateImpl(...).
1661 ChangeStatus updateImpl(Attributor &A) override {
1662 // TODO: Once we have call site specific value information we can provide
1663 // call site specific liveness information and then it makes
1664 // sense to specialize attributes for call sites arguments instead of
1665 // redirecting requests to the callee argument.
1666 Function *F = getAssociatedFunction();
1667 const IRPosition &FnPos = IRPosition::function(*F);
1668 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1669 return clampStateAndIndicateChange(
1670 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1671 }
1672
1673 /// See AbstractAttribute::trackStatistics()
1674 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1675};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001676
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001677/// ------------------------ No-Free Attributes ----------------------------
1678
Johannes Doerfert344d0382019-08-07 22:34:26 +00001679struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001680 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001681
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001682 /// See AbstractAttribute::updateImpl(...).
1683 ChangeStatus updateImpl(Attributor &A) override {
1684 auto CheckForNoFree = [&](Instruction &I) {
1685 ImmutableCallSite ICS(&I);
1686 if (ICS.hasFnAttr(Attribute::NoFree))
1687 return true;
1688
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001689 const auto &NoFreeAA =
1690 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1691 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001692 };
1693
1694 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1695 return indicatePessimisticFixpoint();
1696 return ChangeStatus::UNCHANGED;
1697 }
1698
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001699 /// See AbstractAttribute::getAsStr().
1700 const std::string getAsStr() const override {
1701 return getAssumed() ? "nofree" : "may-free";
1702 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001703};
1704
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001705struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001706 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001707
1708 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001709 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001710};
1711
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001712/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001713struct AANoFreeCallSite final : AANoFreeImpl {
1714 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1715
1716 /// See AbstractAttribute::initialize(...).
1717 void initialize(Attributor &A) override {
1718 AANoFreeImpl::initialize(A);
1719 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001720 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001721 indicatePessimisticFixpoint();
1722 }
1723
1724 /// See AbstractAttribute::updateImpl(...).
1725 ChangeStatus updateImpl(Attributor &A) override {
1726 // TODO: Once we have call site specific value information we can provide
1727 // call site specific liveness information and then it makes
1728 // sense to specialize attributes for call sites arguments instead of
1729 // redirecting requests to the callee argument.
1730 Function *F = getAssociatedFunction();
1731 const IRPosition &FnPos = IRPosition::function(*F);
1732 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1733 return clampStateAndIndicateChange(
1734 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1735 }
1736
1737 /// See AbstractAttribute::trackStatistics()
1738 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1739};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001740
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001741/// NoFree attribute for floating values.
1742struct AANoFreeFloating : AANoFreeImpl {
1743 AANoFreeFloating(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1744
1745 /// See AbstractAttribute::trackStatistics()
1746 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
1747
1748 /// See Abstract Attribute::updateImpl(...).
1749 ChangeStatus updateImpl(Attributor &A) override {
1750 const IRPosition &IRP = getIRPosition();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001751
1752 const auto &NoFreeAA =
1753 A.getAAFor<AANoFree>(*this, IRPosition::function_scope(IRP));
1754 if (NoFreeAA.isAssumedNoFree())
1755 return ChangeStatus::UNCHANGED;
1756
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001757 Value &AssociatedValue = getIRPosition().getAssociatedValue();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001758 auto Pred = [&](const Use &U, bool &Follow) -> bool {
1759 Instruction *UserI = cast<Instruction>(U.getUser());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001760 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001761 if (CB->isBundleOperand(&U))
1762 return false;
1763 if (!CB->isArgOperand(&U))
1764 return true;
1765 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001766
1767 const auto &NoFreeArg = A.getAAFor<AANoFree>(
1768 *this, IRPosition::callsite_argument(*CB, ArgNo));
Hideto Ueno63599bd2019-12-12 12:26:09 +00001769 return NoFreeArg.isAssumedNoFree();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001770 }
1771
1772 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
1773 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001774 Follow = true;
1775 return true;
Hideto Ueno4ecf2552019-12-12 13:42:40 +00001776 }
Johannes Doerfertf9555392020-01-10 14:49:45 -06001777 if (isa<ReturnInst>(UserI))
1778 return true;
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001779
1780 // Unknown user.
Hideto Ueno63599bd2019-12-12 12:26:09 +00001781 return false;
1782 };
1783 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001784 return indicatePessimisticFixpoint();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001785
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001786 return ChangeStatus::UNCHANGED;
1787 }
1788};
1789
1790/// NoFree attribute for a call site argument.
1791struct AANoFreeArgument final : AANoFreeFloating {
1792 AANoFreeArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1793
1794 /// See AbstractAttribute::trackStatistics()
1795 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
1796};
1797
1798/// NoFree attribute for call site arguments.
1799struct AANoFreeCallSiteArgument final : AANoFreeFloating {
1800 AANoFreeCallSiteArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1801
1802 /// See AbstractAttribute::updateImpl(...).
1803 ChangeStatus updateImpl(Attributor &A) override {
1804 // TODO: Once we have call site specific value information we can provide
1805 // call site specific liveness information and then it makes
1806 // sense to specialize attributes for call sites arguments instead of
1807 // redirecting requests to the callee argument.
1808 Argument *Arg = getAssociatedArgument();
1809 if (!Arg)
1810 return indicatePessimisticFixpoint();
1811 const IRPosition &ArgPos = IRPosition::argument(*Arg);
1812 auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
1813 return clampStateAndIndicateChange(
1814 getState(), static_cast<const AANoFree::StateType &>(ArgAA.getState()));
1815 }
1816
1817 /// See AbstractAttribute::trackStatistics()
1818 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
1819};
1820
1821/// NoFree attribute for function return value.
1822struct AANoFreeReturned final : AANoFreeFloating {
1823 AANoFreeReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {
1824 llvm_unreachable("NoFree is not applicable to function returns!");
1825 }
1826
1827 /// See AbstractAttribute::initialize(...).
1828 void initialize(Attributor &A) override {
1829 llvm_unreachable("NoFree is not applicable to function returns!");
1830 }
1831
1832 /// See AbstractAttribute::updateImpl(...).
1833 ChangeStatus updateImpl(Attributor &A) override {
1834 llvm_unreachable("NoFree is not applicable to function returns!");
1835 }
1836
1837 /// See AbstractAttribute::trackStatistics()
1838 void trackStatistics() const override {}
1839};
1840
1841/// NoFree attribute deduction for a call site return value.
1842struct AANoFreeCallSiteReturned final : AANoFreeFloating {
1843 AANoFreeCallSiteReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1844
1845 ChangeStatus manifest(Attributor &A) override {
1846 return ChangeStatus::UNCHANGED;
1847 }
1848 /// See AbstractAttribute::trackStatistics()
1849 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
1850};
1851
Hideto Ueno54869ec2019-07-15 06:49:04 +00001852/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001853static int64_t getKnownNonNullAndDerefBytesForUse(
1854 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1855 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001856 TrackUse = false;
1857
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001858 const Value *UseV = U->get();
1859 if (!UseV->getType()->isPointerTy())
1860 return 0;
1861
1862 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001863 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001864 bool NullPointerIsDefined =
1865 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001866 const DataLayout &DL = A.getInfoCache().getDL();
1867 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1868 if (ICS.isBundleOperand(U))
1869 return 0;
1870
1871 if (ICS.isCallee(U)) {
1872 IsNonNull |= !NullPointerIsDefined;
1873 return 0;
1874 }
1875
1876 unsigned ArgNo = ICS.getArgumentNo(U);
1877 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001878 // As long as we only use known information there is no need to track
1879 // dependences here.
1880 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP,
1881 /* TrackDependence */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001882 IsNonNull |= DerefAA.isKnownNonNull();
1883 return DerefAA.getKnownDereferenceableBytes();
1884 }
1885
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001886 // We need to follow common pointer manipulation uses to the accesses they
1887 // feed into. We can try to be smart to avoid looking through things we do not
1888 // like for now, e.g., non-inbounds GEPs.
1889 if (isa<CastInst>(I)) {
1890 TrackUse = true;
1891 return 0;
1892 }
1893 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001894 if (GEP->hasAllConstantIndices()) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001895 TrackUse = true;
1896 return 0;
1897 }
1898
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001899 int64_t Offset;
1900 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09001901 if (Base == &AssociatedValue &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06001902 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001903 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001904 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001905
1906 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001907 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001908 }
1909 }
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001910
1911 /// Corner case when an offset is 0.
1912 if (const Value *Base = getBasePointerOfAccessPointerOperand(
1913 I, Offset, DL, /*AllowNonInbounds*/ true)) {
1914 if (Offset == 0 && Base == &AssociatedValue &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06001915 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001916 int64_t DerefBytes =
1917 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType());
1918 IsNonNull |= !NullPointerIsDefined;
1919 return std::max(int64_t(0), DerefBytes);
1920 }
1921 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001922
1923 return 0;
1924}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001925
Johannes Doerfert344d0382019-08-07 22:34:26 +00001926struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001927 AANonNullImpl(const IRPosition &IRP)
1928 : AANonNull(IRP),
1929 NullIsDefined(NullPointerIsDefined(
1930 getAnchorScope(),
1931 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001932
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001933 /// See AbstractAttribute::initialize(...).
1934 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001935 if (!NullIsDefined &&
1936 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001937 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001938 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1939 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001940 else
1941 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001942 }
1943
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001944 /// See AAFromMustBeExecutedContext
1945 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1946 bool IsNonNull = false;
1947 bool TrackUse = false;
1948 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1949 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001950 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001951 return TrackUse;
1952 }
1953
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001954 /// See AbstractAttribute::getAsStr().
1955 const std::string getAsStr() const override {
1956 return getAssumed() ? "nonnull" : "may-null";
1957 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001958
1959 /// Flag to determine if the underlying value can be null and still allow
1960 /// valid accesses.
1961 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001962};
1963
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001964/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001965struct AANonNullFloating
1966 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1967 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1968 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001969
Hideto Ueno54869ec2019-07-15 06:49:04 +00001970 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001971 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001972 ChangeStatus Change = Base::updateImpl(A);
1973 if (isKnownNonNull())
1974 return Change;
1975
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001976 if (!NullIsDefined) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001977 const auto &DerefAA =
1978 A.getAAFor<AADereferenceable>(*this, getIRPosition());
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001979 if (DerefAA.getAssumedDereferenceableBytes())
1980 return Change;
1981 }
1982
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001983 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001984
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001985 DominatorTree *DT = nullptr;
1986 InformationCache &InfoCache = A.getInfoCache();
1987 if (const Function *Fn = getAnchorScope())
1988 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
1989
Johannes Doerfert1a746452019-10-20 22:28:49 -05001990 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001991 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001992 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1993 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001994 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001995 T.indicatePessimisticFixpoint();
1996 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001997 // Use abstract attribute information.
1998 const AANonNull::StateType &NS =
1999 static_cast<const AANonNull::StateType &>(AA.getState());
2000 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002001 }
2002 return T.isValidState();
2003 };
2004
2005 StateType T;
2006 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
2007 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002008 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002009
2010 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002011 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002012
2013 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002014 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002015};
2016
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002017/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002018struct AANonNullReturned final
2019 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002020 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002021 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002022
2023 /// See AbstractAttribute::trackStatistics()
2024 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2025};
2026
Hideto Ueno54869ec2019-07-15 06:49:04 +00002027/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002028struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002029 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
2030 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002031 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002032 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
2033 AANonNullImpl>(
2034 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002035
2036 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002037 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002038};
2039
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002040struct AANonNullCallSiteArgument final : AANonNullFloating {
2041 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002042
2043 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00002044 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002045};
Johannes Doerfert007153e2019-08-05 23:26:06 +00002046
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002047/// NonNull attribute for a call site return position.
2048struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002049 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
2050 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002051 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002052 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
2053 AANonNullImpl>(
2054 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002055
2056 /// See AbstractAttribute::trackStatistics()
2057 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2058};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002059
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002060/// ------------------------ No-Recurse Attributes ----------------------------
2061
2062struct AANoRecurseImpl : public AANoRecurse {
2063 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
2064
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002065 /// See AbstractAttribute::getAsStr()
2066 const std::string getAsStr() const override {
2067 return getAssumed() ? "norecurse" : "may-recurse";
2068 }
2069};
2070
2071struct AANoRecurseFunction final : AANoRecurseImpl {
2072 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2073
Hideto Ueno63f60662019-09-21 15:13:19 +00002074 /// See AbstractAttribute::initialize(...).
2075 void initialize(Attributor &A) override {
2076 AANoRecurseImpl::initialize(A);
2077 if (const Function *F = getAnchorScope())
Johannes Doerfert26d02b02019-12-30 16:15:38 -06002078 if (A.getInfoCache().getSccSize(*F) != 1)
2079 indicatePessimisticFixpoint();
Hideto Ueno63f60662019-09-21 15:13:19 +00002080 }
2081
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002082 /// See AbstractAttribute::updateImpl(...).
2083 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00002084
Johannes Doerfert26d02b02019-12-30 16:15:38 -06002085 // If all live call sites are known to be no-recurse, we are as well.
2086 auto CallSitePred = [&](AbstractCallSite ACS) {
2087 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(
2088 *this, IRPosition::function(*ACS.getInstruction()->getFunction()),
2089 /* TrackDependence */ false, DepClassTy::OPTIONAL);
2090 return NoRecurseAA.isKnownNoRecurse();
2091 };
2092 bool AllCallSitesKnown;
2093 if (A.checkForAllCallSites(CallSitePred, *this, true, AllCallSitesKnown)) {
2094 // If we know all call sites and all are known no-recurse, we are done.
2095 // If all known call sites, which might not be all that exist, are known
2096 // to be no-recurse, we are not done but we can continue to assume
2097 // no-recurse. If one of the call sites we have not visited will become
2098 // live, another update is triggered.
2099 if (AllCallSitesKnown)
2100 indicateOptimisticFixpoint();
2101 return ChangeStatus::UNCHANGED;
2102 }
2103
2104 // If the above check does not hold anymore we look at the calls.
Hideto Ueno63f60662019-09-21 15:13:19 +00002105 auto CheckForNoRecurse = [&](Instruction &I) {
2106 ImmutableCallSite ICS(&I);
2107 if (ICS.hasFnAttr(Attribute::NoRecurse))
2108 return true;
2109
2110 const auto &NoRecurseAA =
2111 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
2112 if (!NoRecurseAA.isAssumedNoRecurse())
2113 return false;
2114
2115 // Recursion to the same function
2116 if (ICS.getCalledFunction() == getAnchorScope())
2117 return false;
2118
2119 return true;
2120 };
2121
2122 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
2123 return indicatePessimisticFixpoint();
2124 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002125 }
2126
2127 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2128};
2129
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002130/// NoRecurse attribute deduction for a call sites.
2131struct AANoRecurseCallSite final : AANoRecurseImpl {
2132 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2133
2134 /// See AbstractAttribute::initialize(...).
2135 void initialize(Attributor &A) override {
2136 AANoRecurseImpl::initialize(A);
2137 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002138 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002139 indicatePessimisticFixpoint();
2140 }
2141
2142 /// See AbstractAttribute::updateImpl(...).
2143 ChangeStatus updateImpl(Attributor &A) override {
2144 // TODO: Once we have call site specific value information we can provide
2145 // call site specific liveness information and then it makes
2146 // sense to specialize attributes for call sites arguments instead of
2147 // redirecting requests to the callee argument.
2148 Function *F = getAssociatedFunction();
2149 const IRPosition &FnPos = IRPosition::function(*F);
2150 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
2151 return clampStateAndIndicateChange(
2152 getState(),
2153 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
2154 }
2155
2156 /// See AbstractAttribute::trackStatistics()
2157 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2158};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002159
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002160/// -------------------- Undefined-Behavior Attributes ------------------------
2161
2162struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2163 AAUndefinedBehaviorImpl(const IRPosition &IRP) : AAUndefinedBehavior(IRP) {}
2164
2165 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert5732f562019-12-24 19:25:08 -06002166 // through a pointer (i.e. also branches etc.)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002167 ChangeStatus updateImpl(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002168 const size_t UBPrevSize = KnownUBInsts.size();
2169 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002170
Johannes Doerfert5732f562019-12-24 19:25:08 -06002171 auto InspectMemAccessInstForUB = [&](Instruction &I) {
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002172 // Skip instructions that are already saved.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002173 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002174 return true;
2175
Hideto Uenoef4febd2019-12-29 17:34:08 +09002176 // If we reach here, we know we have an instruction
2177 // that accesses memory through a pointer operand,
2178 // for which getPointerOperand() should give it to us.
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06002179 const Value *PtrOp = getPointerOperand(&I, /* AllowVolatile */ true);
Hideto Uenoef4febd2019-12-29 17:34:08 +09002180 assert(PtrOp &&
2181 "Expected pointer operand of memory accessing instruction");
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002182
Johannes Doerfert5732f562019-12-24 19:25:08 -06002183 // A memory access through a pointer is considered UB
2184 // only if the pointer has constant null value.
2185 // TODO: Expand it to not only check constant values.
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002186 if (!isa<ConstantPointerNull>(PtrOp)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002187 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002188 return true;
2189 }
Johannes Doerfert5732f562019-12-24 19:25:08 -06002190 const Type *PtrTy = PtrOp->getType();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002191
Johannes Doerfert5732f562019-12-24 19:25:08 -06002192 // Because we only consider instructions inside functions,
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002193 // assume that a parent function exists.
2194 const Function *F = I.getFunction();
2195
Johannes Doerfert5732f562019-12-24 19:25:08 -06002196 // A memory access using constant null pointer is only considered UB
2197 // if null pointer is _not_ defined for the target platform.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002198 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()))
2199 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002200 else
Hideto Uenoef4febd2019-12-29 17:34:08 +09002201 KnownUBInsts.insert(&I);
2202 return true;
2203 };
2204
2205 auto InspectBrInstForUB = [&](Instruction &I) {
2206 // A conditional branch instruction is considered UB if it has `undef`
2207 // condition.
2208
2209 // Skip instructions that are already saved.
2210 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2211 return true;
2212
2213 // We know we have a branch instruction.
2214 auto BrInst = cast<BranchInst>(&I);
2215
2216 // Unconditional branches are never considered UB.
2217 if (BrInst->isUnconditional())
2218 return true;
2219
2220 // Either we stopped and the appropriate action was taken,
2221 // or we got back a simplified value to continue.
2222 Optional<Value *> SimplifiedCond =
2223 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2224 if (!SimplifiedCond.hasValue())
2225 return true;
2226 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002227 return true;
2228 };
2229
Johannes Doerfert5732f562019-12-24 19:25:08 -06002230 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
2231 {Instruction::Load, Instruction::Store,
2232 Instruction::AtomicCmpXchg,
2233 Instruction::AtomicRMW});
Hideto Uenoef4febd2019-12-29 17:34:08 +09002234 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br});
2235 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
2236 UBPrevSize != KnownUBInsts.size())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002237 return ChangeStatus::CHANGED;
2238 return ChangeStatus::UNCHANGED;
2239 }
2240
Hideto Uenoef4febd2019-12-29 17:34:08 +09002241 bool isKnownToCauseUB(Instruction *I) const override {
2242 return KnownUBInsts.count(I);
2243 }
2244
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002245 bool isAssumedToCauseUB(Instruction *I) const override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002246 // In simple words, if an instruction is not in the assumed to _not_
2247 // cause UB, then it is assumed UB (that includes those
2248 // in the KnownUBInsts set). The rest is boilerplate
2249 // is to ensure that it is one of the instructions we test
2250 // for UB.
2251
2252 switch (I->getOpcode()) {
2253 case Instruction::Load:
2254 case Instruction::Store:
2255 case Instruction::AtomicCmpXchg:
2256 case Instruction::AtomicRMW:
2257 return !AssumedNoUBInsts.count(I);
2258 case Instruction::Br: {
2259 auto BrInst = cast<BranchInst>(I);
2260 if (BrInst->isUnconditional())
2261 return false;
2262 return !AssumedNoUBInsts.count(I);
2263 } break;
2264 default:
2265 return false;
2266 }
2267 return false;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002268 }
2269
2270 ChangeStatus manifest(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002271 if (KnownUBInsts.empty())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002272 return ChangeStatus::UNCHANGED;
Hideto Uenoef4febd2019-12-29 17:34:08 +09002273 for (Instruction *I : KnownUBInsts)
Hideto Uenocb5eb132019-12-27 02:39:37 +09002274 A.changeToUnreachableAfterManifest(I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002275 return ChangeStatus::CHANGED;
2276 }
2277
2278 /// See AbstractAttribute::getAsStr()
2279 const std::string getAsStr() const override {
2280 return getAssumed() ? "undefined-behavior" : "no-ub";
2281 }
2282
Hideto Uenoef4febd2019-12-29 17:34:08 +09002283 /// Note: The correctness of this analysis depends on the fact that the
2284 /// following 2 sets will stop changing after some point.
2285 /// "Change" here means that their size changes.
2286 /// The size of each set is monotonically increasing
2287 /// (we only add items to them) and it is upper bounded by the number of
2288 /// instructions in the processed function (we can never save more
2289 /// elements in either set than this number). Hence, at some point,
2290 /// they will stop increasing.
2291 /// Consequently, at some point, both sets will have stopped
2292 /// changing, effectively making the analysis reach a fixpoint.
2293
2294 /// Note: These 2 sets are disjoint and an instruction can be considered
2295 /// one of 3 things:
2296 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
2297 /// the KnownUBInsts set.
2298 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
2299 /// has a reason to assume it).
2300 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
2301 /// could not find a reason to assume or prove that it can cause UB,
2302 /// hence it assumes it doesn't. We have a set for these instructions
2303 /// so that we don't reprocess them in every update.
2304 /// Note however that instructions in this set may cause UB.
2305
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002306protected:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002307 /// A set of all live instructions _known_ to cause UB.
2308 SmallPtrSet<Instruction *, 8> KnownUBInsts;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002309
2310private:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002311 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
2312 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
2313
2314 // Should be called on updates in which if we're processing an instruction
2315 // \p I that depends on a value \p V, one of the following has to happen:
2316 // - If the value is assumed, then stop.
2317 // - If the value is known but undef, then consider it UB.
2318 // - Otherwise, do specific processing with the simplified value.
2319 // We return None in the first 2 cases to signify that an appropriate
2320 // action was taken and the caller should stop.
2321 // Otherwise, we return the simplified value that the caller should
2322 // use for specific processing.
2323 Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
2324 Instruction *I) {
2325 const auto &ValueSimplifyAA =
2326 A.getAAFor<AAValueSimplify>(*this, IRPosition::value(*V));
2327 Optional<Value *> SimplifiedV =
2328 ValueSimplifyAA.getAssumedSimplifiedValue(A);
2329 if (!ValueSimplifyAA.isKnown()) {
2330 // Don't depend on assumed values.
2331 return llvm::None;
2332 }
2333 if (!SimplifiedV.hasValue()) {
2334 // If it is known (which we tested above) but it doesn't have a value,
2335 // then we can assume `undef` and hence the instruction is UB.
2336 KnownUBInsts.insert(I);
2337 return llvm::None;
2338 }
2339 Value *Val = SimplifiedV.getValue();
2340 if (isa<UndefValue>(Val)) {
2341 KnownUBInsts.insert(I);
2342 return llvm::None;
2343 }
2344 return Val;
2345 }
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002346};
2347
2348struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
2349 AAUndefinedBehaviorFunction(const IRPosition &IRP)
2350 : AAUndefinedBehaviorImpl(IRP) {}
2351
2352 /// See AbstractAttribute::trackStatistics()
2353 void trackStatistics() const override {
2354 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
2355 "Number of instructions known to have UB");
2356 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
Hideto Uenoef4febd2019-12-29 17:34:08 +09002357 KnownUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002358 }
2359};
2360
Hideto Ueno11d37102019-07-17 15:15:43 +00002361/// ------------------------ Will-Return Attributes ----------------------------
2362
Hideto Ueno11d37102019-07-17 15:15:43 +00002363// Helper function that checks whether a function has any cycle.
2364// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002365static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00002366 SmallPtrSet<BasicBlock *, 32> Visited;
2367
2368 // Traverse BB by dfs and check whether successor is already visited.
2369 for (BasicBlock *BB : depth_first(&F)) {
2370 Visited.insert(BB);
2371 for (auto *SuccBB : successors(BB)) {
2372 if (Visited.count(SuccBB))
2373 return true;
2374 }
2375 }
2376 return false;
2377}
2378
2379// Helper function that checks the function have a loop which might become an
2380// endless loop
2381// FIXME: Any cycle is regarded as endless loop for now.
2382// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002383static bool containsPossiblyEndlessLoop(Function *F) {
2384 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00002385}
2386
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002387struct AAWillReturnImpl : public AAWillReturn {
2388 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00002389
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002390 /// See AbstractAttribute::initialize(...).
2391 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002392 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00002393
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002394 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002395 if (containsPossiblyEndlessLoop(F))
2396 indicatePessimisticFixpoint();
2397 }
Hideto Ueno11d37102019-07-17 15:15:43 +00002398
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002399 /// See AbstractAttribute::updateImpl(...).
2400 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002401 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002402 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
2403 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
2404 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002405 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002406 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002407 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002408 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
2409 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002410 };
2411
2412 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
2413 return indicatePessimisticFixpoint();
2414
2415 return ChangeStatus::UNCHANGED;
2416 }
2417
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002418 /// See AbstractAttribute::getAsStr()
2419 const std::string getAsStr() const override {
2420 return getAssumed() ? "willreturn" : "may-noreturn";
2421 }
2422};
2423
2424struct AAWillReturnFunction final : AAWillReturnImpl {
2425 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2426
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002427 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002428 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002429};
Hideto Ueno11d37102019-07-17 15:15:43 +00002430
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002431/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002432struct AAWillReturnCallSite final : AAWillReturnImpl {
2433 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2434
2435 /// See AbstractAttribute::initialize(...).
2436 void initialize(Attributor &A) override {
2437 AAWillReturnImpl::initialize(A);
2438 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002439 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002440 indicatePessimisticFixpoint();
2441 }
2442
2443 /// See AbstractAttribute::updateImpl(...).
2444 ChangeStatus updateImpl(Attributor &A) override {
2445 // TODO: Once we have call site specific value information we can provide
2446 // call site specific liveness information and then it makes
2447 // sense to specialize attributes for call sites arguments instead of
2448 // redirecting requests to the callee argument.
2449 Function *F = getAssociatedFunction();
2450 const IRPosition &FnPos = IRPosition::function(*F);
2451 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
2452 return clampStateAndIndicateChange(
2453 getState(),
2454 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
2455 }
2456
2457 /// See AbstractAttribute::trackStatistics()
2458 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
2459};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002460
Pankaj Gode04945c92019-11-22 18:40:47 +05302461/// -------------------AAReachability Attribute--------------------------
2462
2463struct AAReachabilityImpl : AAReachability {
2464 AAReachabilityImpl(const IRPosition &IRP) : AAReachability(IRP) {}
2465
2466 const std::string getAsStr() const override {
2467 // TODO: Return the number of reachable queries.
2468 return "reachable";
2469 }
2470
2471 /// See AbstractAttribute::initialize(...).
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002472 void initialize(Attributor &A) override { indicatePessimisticFixpoint(); }
Pankaj Gode04945c92019-11-22 18:40:47 +05302473
2474 /// See AbstractAttribute::updateImpl(...).
2475 ChangeStatus updateImpl(Attributor &A) override {
2476 return indicatePessimisticFixpoint();
2477 }
2478};
2479
2480struct AAReachabilityFunction final : public AAReachabilityImpl {
2481 AAReachabilityFunction(const IRPosition &IRP) : AAReachabilityImpl(IRP) {}
2482
2483 /// See AbstractAttribute::trackStatistics()
2484 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); }
2485};
2486
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002487/// ------------------------ NoAlias Argument Attribute ------------------------
2488
Johannes Doerfert344d0382019-08-07 22:34:26 +00002489struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002490 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002491
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002492 const std::string getAsStr() const override {
2493 return getAssumed() ? "noalias" : "may-alias";
2494 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002495};
2496
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002497/// NoAlias attribute for a floating value.
2498struct AANoAliasFloating final : AANoAliasImpl {
2499 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2500
Hideto Uenocbab3342019-08-29 05:52:00 +00002501 /// See AbstractAttribute::initialize(...).
2502 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002503 AANoAliasImpl::initialize(A);
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002504 Value *Val = &getAssociatedValue();
2505 do {
2506 CastInst *CI = dyn_cast<CastInst>(Val);
2507 if (!CI)
2508 break;
2509 Value *Base = CI->getOperand(0);
2510 if (Base->getNumUses() != 1)
2511 break;
2512 Val = Base;
2513 } while (true);
2514
Johannes Doerfert72adda12019-10-10 05:33:21 +00002515 if (isa<AllocaInst>(Val))
2516 indicateOptimisticFixpoint();
Johannes Doerfert24ae77e2020-01-27 22:19:11 -06002517 else if (isa<ConstantPointerNull>(Val) &&
2518 !NullPointerIsDefined(getAnchorScope(),
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002519 Val->getType()->getPointerAddressSpace()))
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002520 indicateOptimisticFixpoint();
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002521 else if (Val != &getAssociatedValue()) {
2522 const auto &ValNoAliasAA =
2523 A.getAAFor<AANoAlias>(*this, IRPosition::value(*Val));
2524 if (ValNoAliasAA.isKnownNoAlias())
2525 indicateOptimisticFixpoint();
2526 }
Hideto Uenocbab3342019-08-29 05:52:00 +00002527 }
2528
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002529 /// See AbstractAttribute::updateImpl(...).
2530 ChangeStatus updateImpl(Attributor &A) override {
2531 // TODO: Implement this.
2532 return indicatePessimisticFixpoint();
2533 }
2534
2535 /// See AbstractAttribute::trackStatistics()
2536 void trackStatistics() const override {
2537 STATS_DECLTRACK_FLOATING_ATTR(noalias)
2538 }
2539};
2540
2541/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00002542struct AANoAliasArgument final
2543 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002544 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
2545 AANoAliasArgument(const IRPosition &IRP) : Base(IRP) {}
2546
Johannes Doerfert2baf0002020-01-12 00:18:07 -06002547 /// See AbstractAttribute::initialize(...).
2548 void initialize(Attributor &A) override {
2549 Base::initialize(A);
2550 // See callsite argument attribute and callee argument attribute.
2551 if (hasAttr({Attribute::ByVal}))
2552 indicateOptimisticFixpoint();
2553 }
2554
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002555 /// See AbstractAttribute::update(...).
2556 ChangeStatus updateImpl(Attributor &A) override {
2557 // We have to make sure no-alias on the argument does not break
2558 // synchronization when this is a callback argument, see also [1] below.
2559 // If synchronization cannot be affected, we delegate to the base updateImpl
2560 // function, otherwise we give up for now.
2561
2562 // If the function is no-sync, no-alias cannot break synchronization.
2563 const auto &NoSyncAA = A.getAAFor<AANoSync>(
2564 *this, IRPosition::function_scope(getIRPosition()));
2565 if (NoSyncAA.isAssumedNoSync())
2566 return Base::updateImpl(A);
2567
2568 // If the argument is read-only, no-alias cannot break synchronization.
2569 const auto &MemBehaviorAA =
2570 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
2571 if (MemBehaviorAA.isAssumedReadOnly())
2572 return Base::updateImpl(A);
2573
2574 // If the argument is never passed through callbacks, no-alias cannot break
2575 // synchronization.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002576 bool AllCallSitesKnown;
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002577 if (A.checkForAllCallSites(
2578 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002579 true, AllCallSitesKnown))
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002580 return Base::updateImpl(A);
2581
2582 // TODO: add no-alias but make sure it doesn't break synchronization by
2583 // introducing fake uses. See:
2584 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
2585 // International Workshop on OpenMP 2018,
2586 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
2587
2588 return indicatePessimisticFixpoint();
2589 }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002590
2591 /// See AbstractAttribute::trackStatistics()
2592 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
2593};
2594
2595struct AANoAliasCallSiteArgument final : AANoAliasImpl {
2596 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2597
Hideto Uenocbab3342019-08-29 05:52:00 +00002598 /// See AbstractAttribute::initialize(...).
2599 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00002600 // See callsite argument attribute and callee argument attribute.
2601 ImmutableCallSite ICS(&getAnchorValue());
2602 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
2603 indicateOptimisticFixpoint();
Johannes Doerfert24ae77e2020-01-27 22:19:11 -06002604 Value &Val = getAssociatedValue();
2605 if (isa<ConstantPointerNull>(Val) &&
2606 !NullPointerIsDefined(getAnchorScope(),
2607 Val.getType()->getPointerAddressSpace()))
2608 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002609 }
2610
Johannes Doerfert53992c72020-01-27 22:24:32 -06002611 /// Determine if the underlying value may alias with the call site argument
2612 /// \p OtherArgNo of \p ICS (= the underlying call site).
2613 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
2614 const AAMemoryBehavior &MemBehaviorAA,
2615 ImmutableCallSite ICS, unsigned OtherArgNo) {
2616 // We do not need to worry about aliasing with the underlying IRP.
2617 if (this->getArgNo() == (int)OtherArgNo)
2618 return false;
2619
2620 // If it is not a pointer or pointer vector we do not alias.
2621 const Value *ArgOp = ICS.getArgOperand(OtherArgNo);
2622 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
2623 return false;
2624
2625 auto &ICSArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
2626 *this, IRPosition::callsite_argument(ICS, OtherArgNo),
2627 /* TrackDependence */ false);
2628
2629 // If the argument is readnone, there is no read-write aliasing.
2630 if (ICSArgMemBehaviorAA.isAssumedReadNone()) {
2631 A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
2632 return false;
2633 }
2634
2635 // If the argument is readonly and the underlying value is readonly, there
2636 // is no read-write aliasing.
2637 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
2638 if (ICSArgMemBehaviorAA.isAssumedReadOnly() && IsReadOnly) {
2639 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
2640 A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
2641 return false;
2642 }
2643
2644 // We have to utilize actual alias analysis queries so we need the object.
2645 if (!AAR)
2646 AAR = A.getInfoCache().getAAResultsForFunction(*getAnchorScope());
2647
2648 // Try to rule it out at the call site.
2649 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
2650 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
2651 "callsite arguments: "
2652 << getAssociatedValue() << " " << *ArgOp << " => "
2653 << (IsAliasing ? "" : "no-") << "alias \n");
2654
2655 return IsAliasing;
2656 }
2657
2658 bool
2659 isKnownNoAliasDueToNoAliasPreservation(Attributor &A, AAResults *&AAR,
2660 const AAMemoryBehavior &MemBehaviorAA,
2661 const AANoAlias &NoAliasAA) {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002662 // We can deduce "noalias" if the following conditions hold.
2663 // (i) Associated value is assumed to be noalias in the definition.
2664 // (ii) Associated value is assumed to be no-capture in all the uses
2665 // possibly executed before this callsite.
2666 // (iii) There is no other pointer argument which could alias with the
2667 // value.
2668
Johannes Doerfert53992c72020-01-27 22:24:32 -06002669 bool AssociatedValueIsNoAliasAtDef = NoAliasAA.isAssumedNoAlias();
2670 if (!AssociatedValueIsNoAliasAtDef) {
2671 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
2672 << " is not no-alias at the definition\n");
2673 return false;
2674 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002675
Johannes Doerfert53992c72020-01-27 22:24:32 -06002676 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
2677 auto &NoCaptureAA =
2678 A.getAAFor<AANoCapture>(*this, VIRP, /* TrackDependence */ false);
2679 // Check whether the value is captured in the scope using AANoCapture.
2680 // FIXME: This is conservative though, it is better to look at CFG and
2681 // check only uses possibly executed before this callsite.
Johannes Doerfert72adda12019-10-10 05:33:21 +00002682 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2683 LLVM_DEBUG(
Johannes Doerfert53992c72020-01-27 22:24:32 -06002684 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
Johannes Doerfert72adda12019-10-10 05:33:21 +00002685 << " cannot be noalias as it is potentially captured\n");
Johannes Doerfert53992c72020-01-27 22:24:32 -06002686 return false;
Johannes Doerfert72adda12019-10-10 05:33:21 +00002687 }
Johannes Doerfert53992c72020-01-27 22:24:32 -06002688 A.recordDependence(NoCaptureAA, *this, DepClassTy::OPTIONAL);
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002689
Johannes Doerfert53992c72020-01-27 22:24:32 -06002690 // Check there is no other pointer argument which could alias with the
2691 // value passed at this call site.
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002692 // TODO: AbstractCallSite
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002693 ImmutableCallSite ICS(&getAnchorValue());
Johannes Doerfert53992c72020-01-27 22:24:32 -06002694 for (unsigned OtherArgNo = 0; OtherArgNo < ICS.getNumArgOperands();
2695 OtherArgNo++)
2696 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, ICS, OtherArgNo))
2697 return false;
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002698
Johannes Doerfert53992c72020-01-27 22:24:32 -06002699 return true;
2700 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002701
Johannes Doerfert53992c72020-01-27 22:24:32 -06002702 /// See AbstractAttribute::updateImpl(...).
2703 ChangeStatus updateImpl(Attributor &A) override {
2704 // If the argument is readnone we are done as there are no accesses via the
2705 // argument.
2706 auto &MemBehaviorAA =
2707 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(),
2708 /* TrackDependence */ false);
2709 if (MemBehaviorAA.isAssumedReadNone()) {
2710 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
2711 return ChangeStatus::UNCHANGED;
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002712 }
2713
Johannes Doerfert53992c72020-01-27 22:24:32 -06002714 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
2715 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, VIRP,
2716 /* TrackDependence */ false);
2717
2718 AAResults *AAR = nullptr;
2719 if (isKnownNoAliasDueToNoAliasPreservation(A, AAR, MemBehaviorAA,
2720 NoAliasAA)) {
2721 LLVM_DEBUG(
2722 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
2723 return ChangeStatus::UNCHANGED;
2724 }
2725
2726 return indicatePessimisticFixpoint();
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002727 }
2728
2729 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002730 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002731};
2732
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002733/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002734struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002735 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002736
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002737 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002738 virtual ChangeStatus updateImpl(Attributor &A) override {
2739
2740 auto CheckReturnValue = [&](Value &RV) -> bool {
2741 if (Constant *C = dyn_cast<Constant>(&RV))
2742 if (C->isNullValue() || isa<UndefValue>(C))
2743 return true;
2744
2745 /// For now, we can only deduce noalias if we have call sites.
2746 /// FIXME: add more support.
2747 ImmutableCallSite ICS(&RV);
2748 if (!ICS)
2749 return false;
2750
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002751 const IRPosition &RVPos = IRPosition::value(RV);
2752 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002753 if (!NoAliasAA.isAssumedNoAlias())
2754 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002755
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002756 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2757 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002758 };
2759
2760 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2761 return indicatePessimisticFixpoint();
2762
2763 return ChangeStatus::UNCHANGED;
2764 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002765
2766 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002767 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002768};
2769
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002770/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002771struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2772 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2773
2774 /// See AbstractAttribute::initialize(...).
2775 void initialize(Attributor &A) override {
2776 AANoAliasImpl::initialize(A);
2777 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002778 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002779 indicatePessimisticFixpoint();
2780 }
2781
2782 /// See AbstractAttribute::updateImpl(...).
2783 ChangeStatus updateImpl(Attributor &A) override {
2784 // TODO: Once we have call site specific value information we can provide
2785 // call site specific liveness information and then it makes
2786 // sense to specialize attributes for call sites arguments instead of
2787 // redirecting requests to the callee argument.
2788 Function *F = getAssociatedFunction();
2789 const IRPosition &FnPos = IRPosition::returned(*F);
2790 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2791 return clampStateAndIndicateChange(
2792 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2793 }
2794
2795 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002796 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002797};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002798
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002799/// -------------------AAIsDead Function Attribute-----------------------
2800
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002801struct AAIsDeadValueImpl : public AAIsDead {
2802 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002803
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002804 /// See AAIsDead::isAssumedDead().
2805 bool isAssumedDead() const override { return getAssumed(); }
2806
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002807 /// See AAIsDead::isKnownDead().
2808 bool isKnownDead() const override { return getKnown(); }
2809
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002810 /// See AAIsDead::isAssumedDead(BasicBlock *).
2811 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2812
2813 /// See AAIsDead::isKnownDead(BasicBlock *).
2814 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2815
2816 /// See AAIsDead::isAssumedDead(Instruction *I).
2817 bool isAssumedDead(const Instruction *I) const override {
2818 return I == getCtxI() && isAssumedDead();
2819 }
2820
2821 /// See AAIsDead::isKnownDead(Instruction *I).
2822 bool isKnownDead(const Instruction *I) const override {
2823 return I == getCtxI() && getKnown();
2824 }
2825
2826 /// See AbstractAttribute::getAsStr().
2827 const std::string getAsStr() const override {
2828 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2829 }
2830};
2831
2832struct AAIsDeadFloating : public AAIsDeadValueImpl {
2833 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2834
2835 /// See AbstractAttribute::initialize(...).
2836 void initialize(Attributor &A) override {
2837 if (Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()))
2838 if (!wouldInstructionBeTriviallyDead(I))
2839 indicatePessimisticFixpoint();
2840 if (isa<UndefValue>(getAssociatedValue()))
2841 indicatePessimisticFixpoint();
2842 }
2843
2844 /// See AbstractAttribute::updateImpl(...).
2845 ChangeStatus updateImpl(Attributor &A) override {
2846 auto UsePred = [&](const Use &U, bool &Follow) {
2847 Instruction *UserI = cast<Instruction>(U.getUser());
2848 if (CallSite CS = CallSite(UserI)) {
2849 if (!CS.isArgOperand(&U))
2850 return false;
2851 const IRPosition &CSArgPos =
2852 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
2853 const auto &CSArgIsDead = A.getAAFor<AAIsDead>(*this, CSArgPos);
2854 return CSArgIsDead.isAssumedDead();
2855 }
2856 if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
2857 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
2858 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, RetPos);
2859 return RetIsDeadAA.isAssumedDead();
2860 }
2861 Follow = true;
2862 return wouldInstructionBeTriviallyDead(UserI);
2863 };
2864
2865 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
2866 return indicatePessimisticFixpoint();
2867 return ChangeStatus::UNCHANGED;
2868 }
2869
2870 /// See AbstractAttribute::manifest(...).
2871 ChangeStatus manifest(Attributor &A) override {
2872 Value &V = getAssociatedValue();
2873 if (auto *I = dyn_cast<Instruction>(&V))
2874 if (wouldInstructionBeTriviallyDead(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002875 A.deleteAfterManifest(*I);
2876 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002877 }
2878
2879 if (V.use_empty())
2880 return ChangeStatus::UNCHANGED;
2881
2882 UndefValue &UV = *UndefValue::get(V.getType());
Hideto Ueno34fe8d02019-12-30 17:08:48 +09002883 bool AnyChange = A.changeValueAfterManifest(V, UV);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002884 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2885 }
2886
2887 /// See AbstractAttribute::trackStatistics()
2888 void trackStatistics() const override {
2889 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2890 }
2891};
2892
2893struct AAIsDeadArgument : public AAIsDeadFloating {
2894 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2895
2896 /// See AbstractAttribute::initialize(...).
2897 void initialize(Attributor &A) override {
2898 if (!getAssociatedFunction()->hasExactDefinition())
2899 indicatePessimisticFixpoint();
2900 }
2901
Johannes Doerfert75133632019-10-10 01:39:16 -05002902 /// See AbstractAttribute::manifest(...).
2903 ChangeStatus manifest(Attributor &A) override {
2904 ChangeStatus Changed = AAIsDeadFloating::manifest(A);
2905 Argument &Arg = *getAssociatedArgument();
Johannes Doerfert89c2e732019-10-30 17:20:20 -05002906 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
Johannes Doerfert75133632019-10-10 01:39:16 -05002907 if (A.registerFunctionSignatureRewrite(
2908 Arg, /* ReplacementTypes */ {},
2909 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{},
2910 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{}))
2911 return ChangeStatus::CHANGED;
2912 return Changed;
2913 }
2914
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002915 /// See AbstractAttribute::trackStatistics()
2916 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2917};
2918
2919struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2920 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2921
2922 /// See AbstractAttribute::initialize(...).
2923 void initialize(Attributor &A) override {
2924 if (isa<UndefValue>(getAssociatedValue()))
2925 indicatePessimisticFixpoint();
2926 }
2927
2928 /// See AbstractAttribute::updateImpl(...).
2929 ChangeStatus updateImpl(Attributor &A) override {
2930 // TODO: Once we have call site specific value information we can provide
2931 // call site specific liveness information and then it makes
2932 // sense to specialize attributes for call sites arguments instead of
2933 // redirecting requests to the callee argument.
2934 Argument *Arg = getAssociatedArgument();
2935 if (!Arg)
2936 return indicatePessimisticFixpoint();
2937 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2938 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
2939 return clampStateAndIndicateChange(
2940 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
2941 }
2942
2943 /// See AbstractAttribute::manifest(...).
2944 ChangeStatus manifest(Attributor &A) override {
2945 CallBase &CB = cast<CallBase>(getAnchorValue());
2946 Use &U = CB.getArgOperandUse(getArgNo());
2947 assert(!isa<UndefValue>(U.get()) &&
2948 "Expected undef values to be filtered out!");
2949 UndefValue &UV = *UndefValue::get(U->getType());
2950 if (A.changeUseAfterManifest(U, UV))
2951 return ChangeStatus::CHANGED;
2952 return ChangeStatus::UNCHANGED;
2953 }
2954
2955 /// See AbstractAttribute::trackStatistics()
2956 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
2957};
2958
2959struct AAIsDeadReturned : public AAIsDeadValueImpl {
2960 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2961
2962 /// See AbstractAttribute::updateImpl(...).
2963 ChangeStatus updateImpl(Attributor &A) override {
2964
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002965 bool AllKnownDead = true;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002966 auto PredForCallSite = [&](AbstractCallSite ACS) {
2967 if (ACS.isCallbackCall())
2968 return false;
2969 const IRPosition &CSRetPos =
2970 IRPosition::callsite_returned(ACS.getCallSite());
2971 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, CSRetPos);
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002972 AllKnownDead &= RetIsDeadAA.isKnownDead();
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002973 return RetIsDeadAA.isAssumedDead();
2974 };
2975
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002976 bool AllCallSitesKnown;
2977 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
2978 AllCallSitesKnown))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002979 return indicatePessimisticFixpoint();
2980
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002981 if (AllCallSitesKnown && AllKnownDead)
2982 indicateOptimisticFixpoint();
2983
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002984 return ChangeStatus::UNCHANGED;
2985 }
2986
2987 /// See AbstractAttribute::manifest(...).
2988 ChangeStatus manifest(Attributor &A) override {
2989 // TODO: Rewrite the signature to return void?
2990 bool AnyChange = false;
2991 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
2992 auto RetInstPred = [&](Instruction &I) {
2993 ReturnInst &RI = cast<ReturnInst>(I);
2994 if (!isa<UndefValue>(RI.getReturnValue()))
2995 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
2996 return true;
2997 };
2998 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
2999 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
3000 }
3001
3002 /// See AbstractAttribute::trackStatistics()
3003 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
3004};
3005
3006struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
3007 AAIsDeadCallSiteReturned(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
3008
3009 /// See AbstractAttribute::initialize(...).
3010 void initialize(Attributor &A) override {}
3011
3012 /// See AbstractAttribute::trackStatistics()
3013 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(IsDead) }
3014};
3015
3016struct AAIsDeadFunction : public AAIsDead {
3017 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
3018
3019 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003020 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003021 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003022 if (F && !F->isDeclaration()) {
3023 ToBeExploredFrom.insert(&F->getEntryBlock().front());
3024 assumeLive(A, F->getEntryBlock());
3025 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003026 }
3027
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003028 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003029 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003030 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003031 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003032 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
3033 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003034 }
3035
3036 /// See AbstractAttribute::manifest(...).
3037 ChangeStatus manifest(Attributor &A) override {
3038 assert(getState().isValidState() &&
3039 "Attempted to manifest an invalid state!");
3040
3041 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003042 Function &F = *getAssociatedFunction();
3043
3044 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003045 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003046 return ChangeStatus::CHANGED;
3047 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00003048
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003049 // Flag to determine if we can change an invoke to a call assuming the
3050 // callee is nounwind. This is not possible if the personality of the
3051 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00003052 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003053
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003054 KnownDeadEnds.set_union(ToBeExploredFrom);
3055 for (const Instruction *DeadEndI : KnownDeadEnds) {
3056 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003057 if (!CB)
3058 continue;
3059 const auto &NoReturnAA =
3060 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05003061 bool MayReturn = !NoReturnAA.isAssumedNoReturn();
3062 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003063 continue;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003064
Johannes Doerferta4088c72020-01-07 16:01:57 -06003065 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
3066 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
3067 else
3068 A.changeToUnreachableAfterManifest(
3069 const_cast<Instruction *>(DeadEndI->getNextNode()));
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003070 HasChanged = ChangeStatus::CHANGED;
3071 }
3072
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003073 for (BasicBlock &BB : F)
3074 if (!AssumedLiveBlocks.count(&BB))
3075 A.deleteAfterManifest(BB);
3076
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003077 return HasChanged;
3078 }
3079
3080 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003081 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003082
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003083 /// See AbstractAttribute::trackStatistics()
3084 void trackStatistics() const override {}
3085
3086 /// Returns true if the function is assumed dead.
3087 bool isAssumedDead() const override { return false; }
3088
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06003089 /// See AAIsDead::isKnownDead().
3090 bool isKnownDead() const override { return false; }
3091
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003092 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003093 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003094 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003095 "BB must be in the same anchor scope function.");
3096
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003097 if (!getAssumed())
3098 return false;
3099 return !AssumedLiveBlocks.count(BB);
3100 }
3101
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003102 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003103 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003104 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003105 }
3106
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003107 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003108 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003109 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003110 "Instruction must be in the same anchor scope function.");
3111
Stefan Stipanovic7849e412019-08-03 15:27:41 +00003112 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003113 return false;
3114
3115 // If it is not in AssumedLiveBlocks then it for sure dead.
3116 // Otherwise, it can still be after noreturn call in a live block.
3117 if (!AssumedLiveBlocks.count(I->getParent()))
3118 return true;
3119
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003120 // If it is not after a liveness barrier it is live.
3121 const Instruction *PrevI = I->getPrevNode();
3122 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003123 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003124 return true;
3125 PrevI = PrevI->getPrevNode();
3126 }
3127 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003128 }
3129
3130 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003131 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003132 return getKnown() && isAssumedDead(I);
3133 }
3134
Johannes Doerfert924d2132019-08-05 21:34:45 +00003135 /// Determine if \p F might catch asynchronous exceptions.
3136 static bool mayCatchAsynchronousExceptions(const Function &F) {
3137 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
3138 }
3139
Johannes Doerfert2f622062019-09-04 16:35:20 +00003140 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
3141 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003142 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00003143 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003144 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003145
3146 // We assume that all of BB is (probably) live now and if there are calls to
3147 // internal functions we will assume that those are now live as well. This
3148 // is a performance optimization for blocks with calls to a lot of internal
3149 // functions. It can however cause dead functions to be treated as live.
3150 for (const Instruction &I : BB)
3151 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
3152 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00003153 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00003154 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003155 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003156 }
3157
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003158 /// Collection of instructions that need to be explored again, e.g., we
3159 /// did assume they do not transfer control to (one of their) successors.
3160 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003161
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003162 /// Collection of instructions that are known to not transfer control.
3163 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
3164
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003165 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00003166 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003167};
3168
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003169static bool
3170identifyAliveSuccessors(Attributor &A, const CallBase &CB,
3171 AbstractAttribute &AA,
3172 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3173 const IRPosition &IPos = IRPosition::callsite_function(CB);
3174
3175 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
3176 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003177 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003178 if (CB.isTerminator())
3179 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
3180 else
3181 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003182 return false;
3183}
3184
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003185static bool
3186identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
3187 AbstractAttribute &AA,
3188 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3189 bool UsedAssumedInformation =
3190 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00003191
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003192 // First, determine if we can change an invoke to a call assuming the
3193 // callee is nounwind. This is not possible if the personality of the
3194 // function allows to catch asynchronous exceptions.
3195 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
3196 AliveSuccessors.push_back(&II.getUnwindDest()->front());
3197 } else {
3198 const IRPosition &IPos = IRPosition::callsite_function(II);
3199 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003200 if (AANoUnw.isAssumedNoUnwind()) {
3201 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
3202 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003203 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003204 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003205 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003206 return UsedAssumedInformation;
3207}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003208
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003209static bool
3210identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
3211 AbstractAttribute &AA,
3212 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3213 bool UsedAssumedInformation = false;
3214 if (BI.getNumSuccessors() == 1) {
3215 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3216 } else {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003217 Optional<ConstantInt *> CI =
3218 getAssumedConstant(A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003219 if (!CI.hasValue()) {
3220 // No value yet, assume both edges are dead.
3221 } else if (CI.getValue()) {
3222 const BasicBlock *SuccBB =
3223 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
3224 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003225 } else {
3226 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3227 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003228 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003229 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003230 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003231 return UsedAssumedInformation;
3232}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003233
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003234static bool
3235identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
3236 AbstractAttribute &AA,
3237 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003238 bool UsedAssumedInformation = false;
3239 Optional<ConstantInt *> CI =
3240 getAssumedConstant(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003241 if (!CI.hasValue()) {
3242 // No value yet, assume all edges are dead.
3243 } else if (CI.getValue()) {
3244 for (auto &CaseIt : SI.cases()) {
3245 if (CaseIt.getCaseValue() == CI.getValue()) {
3246 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003247 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003248 }
3249 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05003250 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003251 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003252 } else {
3253 for (const BasicBlock *SuccBB : successors(SI.getParent()))
3254 AliveSuccessors.push_back(&SuccBB->front());
3255 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003256 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003257}
3258
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003259ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003260 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003261
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003262 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
3263 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003264 << ToBeExploredFrom.size() << " exploration points and "
3265 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003266
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003267 // Copy and clear the list of instructions we need to explore from. It is
3268 // refilled with instructions the next update has to look at.
3269 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
3270 ToBeExploredFrom.end());
3271 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003272
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003273 SmallVector<const Instruction *, 8> AliveSuccessors;
3274 while (!Worklist.empty()) {
3275 const Instruction *I = Worklist.pop_back_val();
3276 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003277
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003278 AliveSuccessors.clear();
3279
3280 bool UsedAssumedInformation = false;
3281 switch (I->getOpcode()) {
3282 // TODO: look for (assumed) UB to backwards propagate "deadness".
3283 default:
3284 if (I->isTerminator()) {
3285 for (const BasicBlock *SuccBB : successors(I->getParent()))
3286 AliveSuccessors.push_back(&SuccBB->front());
3287 } else {
3288 AliveSuccessors.push_back(I->getNextNode());
3289 }
3290 break;
3291 case Instruction::Call:
3292 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
3293 *this, AliveSuccessors);
3294 break;
3295 case Instruction::Invoke:
3296 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
3297 *this, AliveSuccessors);
3298 break;
3299 case Instruction::Br:
3300 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
3301 *this, AliveSuccessors);
3302 break;
3303 case Instruction::Switch:
3304 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
3305 *this, AliveSuccessors);
3306 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00003307 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003308
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003309 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003310 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003311 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003312 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003313 if (AliveSuccessors.empty() ||
3314 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
3315 KnownDeadEnds.insert(I);
3316 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003317
3318 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
3319 << AliveSuccessors.size() << " UsedAssumedInformation: "
3320 << UsedAssumedInformation << "\n");
3321
3322 for (const Instruction *AliveSuccessor : AliveSuccessors) {
3323 if (!I->isTerminator()) {
3324 assert(AliveSuccessors.size() == 1 &&
3325 "Non-terminator expected to have a single successor!");
3326 Worklist.push_back(AliveSuccessor);
3327 } else {
3328 if (assumeLive(A, *AliveSuccessor->getParent()))
3329 Worklist.push_back(AliveSuccessor);
3330 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00003331 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003332 }
3333
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003334 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003335
Johannes Doerfertd6207812019-08-07 22:32:38 +00003336 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003337 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003338 // "invalid" and all queries to be answered conservatively without lookups.
3339 // To be in this state we have to (1) finished the exploration and (3) not
3340 // discovered any non-trivial dead end and (2) not ruled unreachable code
3341 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003342 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003343 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
3344 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
3345 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
3346 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003347 return indicatePessimisticFixpoint();
3348 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003349}
3350
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003351/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003352struct AAIsDeadCallSite final : AAIsDeadFunction {
3353 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003354
3355 /// See AbstractAttribute::initialize(...).
3356 void initialize(Attributor &A) override {
3357 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003358 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003359 // sense to specialize attributes for call sites instead of
3360 // redirecting requests to the callee.
3361 llvm_unreachable("Abstract attributes for liveness are not "
3362 "supported for call sites yet!");
3363 }
3364
3365 /// See AbstractAttribute::updateImpl(...).
3366 ChangeStatus updateImpl(Attributor &A) override {
3367 return indicatePessimisticFixpoint();
3368 }
3369
3370 /// See AbstractAttribute::trackStatistics()
3371 void trackStatistics() const override {}
3372};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003373
Hideto Ueno19c07af2019-07-23 08:16:17 +00003374/// -------------------- Dereferenceable Argument Attribute --------------------
3375
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003376template <>
3377ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
3378 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05003379 ChangeStatus CS0 =
3380 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
3381 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003382 return CS0 | CS1;
3383}
3384
Hideto Ueno70576ca2019-08-22 14:18:29 +00003385struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003386 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003387 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00003388
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003389 void initialize(Attributor &A) override {
3390 SmallVector<Attribute, 4> Attrs;
3391 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
3392 Attrs);
3393 for (const Attribute &Attr : Attrs)
3394 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
3395
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003396 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition(),
3397 /* TrackDependence */ false);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003398
3399 const IRPosition &IRP = this->getIRPosition();
3400 bool IsFnInterface = IRP.isFnInterfaceKind();
3401 const Function *FnScope = IRP.getAnchorScope();
3402 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
3403 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003404 }
3405
Hideto Ueno19c07af2019-07-23 08:16:17 +00003406 /// See AbstractAttribute::getState()
3407 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00003408 StateType &getState() override { return *this; }
3409 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003410 /// }
3411
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003412 /// Helper function for collecting accessed bytes in must-be-executed-context
3413 void addAccessedBytesForUse(Attributor &A, const Use *U,
3414 const Instruction *I) {
3415 const Value *UseV = U->get();
3416 if (!UseV->getType()->isPointerTy())
3417 return;
3418
3419 Type *PtrTy = UseV->getType();
3420 const DataLayout &DL = A.getDataLayout();
3421 int64_t Offset;
3422 if (const Value *Base = getBasePointerOfAccessPointerOperand(
3423 I, Offset, DL, /*AllowNonInbounds*/ true)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09003424 if (Base == &getAssociatedValue() &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06003425 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003426 uint64_t Size = DL.getTypeStoreSize(PtrTy->getPointerElementType());
3427 addAccessedBytes(Offset, Size);
3428 }
3429 }
3430 return;
3431 }
3432
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003433 /// See AAFromMustBeExecutedContext
3434 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3435 bool IsNonNull = false;
3436 bool TrackUse = false;
3437 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
3438 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003439
3440 addAccessedBytesForUse(A, U, I);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003441 takeKnownDerefBytesMaximum(DerefBytes);
3442 return TrackUse;
3443 }
3444
Hideto Uenodfedae52019-11-29 06:45:07 +00003445 /// See AbstractAttribute::manifest(...).
3446 ChangeStatus manifest(Attributor &A) override {
3447 ChangeStatus Change = AADereferenceable::manifest(A);
3448 if (isAssumedNonNull() && hasAttr(Attribute::DereferenceableOrNull)) {
3449 removeAttrs({Attribute::DereferenceableOrNull});
3450 return ChangeStatus::CHANGED;
3451 }
3452 return Change;
3453 }
3454
Johannes Doerferteccdf082019-08-05 23:35:12 +00003455 void getDeducedAttributes(LLVMContext &Ctx,
3456 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00003457 // TODO: Add *_globally support
3458 if (isAssumedNonNull())
3459 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
3460 Ctx, getAssumedDereferenceableBytes()));
3461 else
3462 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
3463 Ctx, getAssumedDereferenceableBytes()));
3464 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003465
3466 /// See AbstractAttribute::getAsStr().
3467 const std::string getAsStr() const override {
3468 if (!getAssumedDereferenceableBytes())
3469 return "unknown-dereferenceable";
3470 return std::string("dereferenceable") +
3471 (isAssumedNonNull() ? "" : "_or_null") +
3472 (isAssumedGlobal() ? "_globally" : "") + "<" +
3473 std::to_string(getKnownDereferenceableBytes()) + "-" +
3474 std::to_string(getAssumedDereferenceableBytes()) + ">";
3475 }
3476};
3477
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003478/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003479struct AADereferenceableFloating
3480 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
3481 using Base =
3482 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
3483 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00003484
3485 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003486 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003487 ChangeStatus Change = Base::updateImpl(A);
3488
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003489 const DataLayout &DL = A.getDataLayout();
3490
3491 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
3492 unsigned IdxWidth =
3493 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
3494 APInt Offset(IdxWidth, 0);
3495 const Value *Base =
3496 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
3497
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003498 const auto &AA =
3499 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003500 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003501 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003502 // Use IR information if we did not strip anything.
3503 // TODO: track globally.
3504 bool CanBeNull;
3505 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
3506 T.GlobalState.indicatePessimisticFixpoint();
3507 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003508 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003509 DerefBytes = DS.DerefBytesState.getAssumed();
3510 T.GlobalState &= DS.GlobalState;
3511 }
3512
Hideto Ueno188f9a32020-01-15 15:25:52 +09003513 // TODO: Use `AAConstantRange` to infer dereferenceable bytes.
3514
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003515 // For now we do not try to "increase" dereferenceability due to negative
3516 // indices as we first have to come up with code to deal with loops and
3517 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00003518 int64_t OffsetSExt = Offset.getSExtValue();
3519 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00003520 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003521
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003522 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00003523 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003524
Johannes Doerfert785fad32019-08-23 17:29:23 +00003525 if (this == &AA) {
3526 if (!Stripped) {
3527 // If nothing was stripped IR information is all we got.
3528 T.takeKnownDerefBytesMaximum(
3529 std::max(int64_t(0), DerefBytes - OffsetSExt));
3530 T.indicatePessimisticFixpoint();
3531 } else if (OffsetSExt > 0) {
3532 // If something was stripped but there is circular reasoning we look
3533 // for the offset. If it is positive we basically decrease the
3534 // dereferenceable bytes in a circluar loop now, which will simply
3535 // drive them down to the known value in a very slow way which we
3536 // can accelerate.
3537 T.indicatePessimisticFixpoint();
3538 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003539 }
3540
3541 return T.isValidState();
3542 };
3543
3544 DerefState T;
3545 if (!genericValueTraversal<AADereferenceable, DerefState>(
3546 A, getIRPosition(), *this, T, VisitValueCB))
3547 return indicatePessimisticFixpoint();
3548
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003549 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003550 }
3551
3552 /// See AbstractAttribute::trackStatistics()
3553 void trackStatistics() const override {
3554 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
3555 }
3556};
3557
3558/// Dereferenceable attribute for a return value.
3559struct AADereferenceableReturned final
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003560 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003561 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003562 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>(
3563 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003564
3565 /// See AbstractAttribute::trackStatistics()
3566 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003567 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003568 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003569};
3570
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003571/// Dereferenceable attribute for an argument
3572struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003573 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003574 AADereferenceable, AADereferenceableImpl> {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003575 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003576 AADereferenceable, AADereferenceableImpl>;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003577 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003578
3579 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003580 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00003581 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
3582 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003583};
3584
Hideto Ueno19c07af2019-07-23 08:16:17 +00003585/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003586struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003587 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003588 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003589
3590 /// See AbstractAttribute::trackStatistics()
3591 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003592 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003593 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003594};
3595
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003596/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003597struct AADereferenceableCallSiteReturned final
3598 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3599 AADereferenceable, AADereferenceableImpl> {
3600 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3601 AADereferenceable, AADereferenceableImpl>;
3602 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003603
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003604 /// See AbstractAttribute::trackStatistics()
3605 void trackStatistics() const override {
3606 STATS_DECLTRACK_CS_ATTR(dereferenceable);
3607 }
3608};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003609
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003610// ------------------------ Align Argument Attribute ------------------------
3611
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003612static unsigned int getKnownAlignForUse(Attributor &A,
3613 AbstractAttribute &QueryingAA,
3614 Value &AssociatedValue, const Use *U,
3615 const Instruction *I, bool &TrackUse) {
Hideto Ueno78a75022019-11-26 07:51:59 +00003616 // We need to follow common pointer manipulation uses to the accesses they
3617 // feed into.
3618 if (isa<CastInst>(I)) {
Johannes Doerfertc90681b2020-01-02 16:41:17 -06003619 // Follow all but ptr2int casts.
3620 TrackUse = !isa<PtrToIntInst>(I);
Hideto Ueno78a75022019-11-26 07:51:59 +00003621 return 0;
3622 }
3623 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
3624 if (GEP->hasAllConstantIndices()) {
3625 TrackUse = true;
3626 return 0;
3627 }
3628 }
3629
3630 unsigned Alignment = 0;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003631 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
3632 if (ICS.isBundleOperand(U) || ICS.isCallee(U))
3633 return 0;
3634
3635 unsigned ArgNo = ICS.getArgumentNo(U);
3636 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
3637 // As long as we only use known information there is no need to track
3638 // dependences here.
3639 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP,
3640 /* TrackDependence */ false);
Hideto Ueno78a75022019-11-26 07:51:59 +00003641 Alignment = AlignAA.getKnownAlign();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003642 }
3643
Hideto Ueno78a75022019-11-26 07:51:59 +00003644 const Value *UseV = U->get();
Johannes Doerfert30ae8592020-01-10 12:13:10 -06003645 if (auto *SI = dyn_cast<StoreInst>(I)) {
3646 if (SI->getPointerOperand() == UseV)
3647 Alignment = SI->getAlignment();
3648 } else if (auto *LI = dyn_cast<LoadInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003649 Alignment = LI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003650
Hideto Ueno78a75022019-11-26 07:51:59 +00003651 if (Alignment <= 1)
3652 return 0;
3653
3654 auto &DL = A.getDataLayout();
3655 int64_t Offset;
3656
3657 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
3658 if (Base == &AssociatedValue) {
3659 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
3660 // So we can say that the maximum power of two which is a divisor of
3661 // gcd(Offset, Alignment) is an alignment.
3662
3663 uint32_t gcd =
3664 greatestCommonDivisor(uint32_t(abs((int32_t)Offset)), Alignment);
3665 Alignment = llvm::PowerOf2Floor(gcd);
3666 }
3667 }
3668
3669 return Alignment;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003670}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003671struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003672 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003673
Johannes Doerfert234eda52019-08-16 19:51:23 +00003674 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003675 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003676 SmallVector<Attribute, 4> Attrs;
3677 getAttrs({Attribute::Alignment}, Attrs);
3678 for (const Attribute &Attr : Attrs)
3679 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003680
3681 if (getIRPosition().isFnInterfaceKind() &&
3682 (!getAssociatedFunction() ||
3683 !getAssociatedFunction()->hasExactDefinition()))
3684 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003685 }
3686
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003687 /// See AbstractAttribute::manifest(...).
3688 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003689 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003690
3691 // Check for users that allow alignment annotations.
3692 Value &AnchorVal = getIRPosition().getAnchorValue();
3693 for (const Use &U : AnchorVal.uses()) {
3694 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
3695 if (SI->getPointerOperand() == &AnchorVal)
3696 if (SI->getAlignment() < getAssumedAlign()) {
3697 STATS_DECLTRACK(AAAlign, Store,
James Hendersond68904f2020-01-06 10:15:44 +00003698 "Number of times alignment added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00003699 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert30179d72020-01-12 00:25:45 -06003700 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003701 }
3702 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
3703 if (LI->getPointerOperand() == &AnchorVal)
3704 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00003705 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003706 STATS_DECLTRACK(AAAlign, Load,
James Hendersond68904f2020-01-06 10:15:44 +00003707 "Number of times alignment added to a load");
Johannes Doerfert30179d72020-01-12 00:25:45 -06003708 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003709 }
3710 }
3711 }
3712
Johannes Doerfert30179d72020-01-12 00:25:45 -06003713 ChangeStatus Changed = AAAlign::manifest(A);
3714
3715 MaybeAlign InheritAlign =
3716 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3717 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3718 return LoadStoreChanged;
3719 return Changed | LoadStoreChanged;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003720 }
3721
Johannes Doerfert81df4522019-08-30 15:22:28 +00003722 // TODO: Provide a helper to determine the implied ABI alignment and check in
3723 // the existing manifest method and a new one for AAAlignImpl that value
3724 // to avoid making the alignment explicit if it did not improve.
3725
3726 /// See AbstractAttribute::getDeducedAttributes
3727 virtual void
3728 getDeducedAttributes(LLVMContext &Ctx,
3729 SmallVectorImpl<Attribute> &Attrs) const override {
3730 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00003731 Attrs.emplace_back(
3732 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00003733 }
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003734 /// See AAFromMustBeExecutedContext
3735 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3736 bool TrackUse = false;
3737
Hideto Ueno4ecf2552019-12-12 13:42:40 +00003738 unsigned int KnownAlign =
3739 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003740 takeKnownMaximum(KnownAlign);
3741
3742 return TrackUse;
3743 }
Johannes Doerfert81df4522019-08-30 15:22:28 +00003744
3745 /// See AbstractAttribute::getAsStr().
3746 const std::string getAsStr() const override {
3747 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
3748 "-" + std::to_string(getAssumedAlign()) + ">")
3749 : "unknown-align";
3750 }
3751};
3752
3753/// Align attribute for a floating value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003754struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
3755 using Base = AAFromMustBeExecutedContext<AAAlign, AAAlignImpl>;
3756 AAAlignFloating(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert81df4522019-08-30 15:22:28 +00003757
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003758 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00003759 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003760 Base::updateImpl(A);
3761
Johannes Doerfert234eda52019-08-16 19:51:23 +00003762 const DataLayout &DL = A.getDataLayout();
3763
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003764 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3765 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003766 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3767 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003768 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003769 const MaybeAlign PA = V.getPointerAlignment(DL);
3770 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003771 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003772 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003773 // Use abstract attribute information.
3774 const AAAlign::StateType &DS =
3775 static_cast<const AAAlign::StateType &>(AA.getState());
3776 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003777 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003778 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003779 };
3780
3781 StateType T;
3782 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3783 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003784 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003785
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003786 // TODO: If we know we visited all incoming values, thus no are assumed
3787 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003788 return clampStateAndIndicateChange(getState(), T);
3789 }
3790
3791 /// See AbstractAttribute::trackStatistics()
3792 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3793};
3794
3795/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003796struct AAAlignReturned final
3797 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003798 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003799 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003800
3801 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003802 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003803};
3804
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003805/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003806struct AAAlignArgument final
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003807 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3808 AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003809 AAAlignArgument(const IRPosition &IRP)
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003810 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3811 AAAlignImpl>(
3812 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003813
3814 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003815 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003816};
3817
Johannes Doerfert234eda52019-08-16 19:51:23 +00003818struct AAAlignCallSiteArgument final : AAAlignFloating {
3819 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003820
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003821 /// See AbstractAttribute::manifest(...).
3822 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003823 ChangeStatus Changed = AAAlignImpl::manifest(A);
3824 MaybeAlign InheritAlign =
3825 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3826 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3827 Changed = ChangeStatus::UNCHANGED;
3828 return Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003829 }
3830
Johannes Doerfertdada8132019-12-31 01:27:50 -06003831 /// See AbstractAttribute::updateImpl(Attributor &A).
3832 ChangeStatus updateImpl(Attributor &A) override {
3833 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
3834 if (Argument *Arg = getAssociatedArgument()) {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003835 // We only take known information from the argument
3836 // so we do not need to track a dependence.
Johannes Doerfertdada8132019-12-31 01:27:50 -06003837 const auto &ArgAlignAA = A.getAAFor<AAAlign>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003838 *this, IRPosition::argument(*Arg), /* TrackDependence */ false);
Johannes Doerfertdada8132019-12-31 01:27:50 -06003839 takeKnownMaximum(ArgAlignAA.getKnownAlign());
3840 }
3841 return Changed;
3842 }
3843
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003844 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003845 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003846};
3847
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003848/// Align attribute deduction for a call site return value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003849struct AAAlignCallSiteReturned final
3850 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3851 AAAlignImpl> {
3852 using Base =
3853 AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3854 AAAlignImpl>;
3855 AAAlignCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003856
3857 /// See AbstractAttribute::initialize(...).
3858 void initialize(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003859 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003860 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003861 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003862 indicatePessimisticFixpoint();
3863 }
3864
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003865 /// See AbstractAttribute::trackStatistics()
3866 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3867};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003868
Johannes Doerferte83f3032019-08-05 23:22:05 +00003869/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003870struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003871 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003872
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003873 /// See AbstractAttribute::initialize(...).
3874 void initialize(Attributor &A) override {
3875 AANoReturn::initialize(A);
3876 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003877 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003878 indicatePessimisticFixpoint();
3879 }
3880
Johannes Doerferte83f3032019-08-05 23:22:05 +00003881 /// See AbstractAttribute::getAsStr().
3882 const std::string getAsStr() const override {
3883 return getAssumed() ? "noreturn" : "may-return";
3884 }
3885
Johannes Doerferte83f3032019-08-05 23:22:05 +00003886 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00003887 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003888 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003889 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003890 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003891 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003892 return ChangeStatus::UNCHANGED;
3893 }
3894};
3895
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003896struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003897 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003898
3899 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003900 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003901};
3902
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003903/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003904struct AANoReturnCallSite final : AANoReturnImpl {
3905 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3906
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003907 /// See AbstractAttribute::updateImpl(...).
3908 ChangeStatus updateImpl(Attributor &A) override {
3909 // TODO: Once we have call site specific value information we can provide
3910 // call site specific liveness information and then it makes
3911 // sense to specialize attributes for call sites arguments instead of
3912 // redirecting requests to the callee argument.
3913 Function *F = getAssociatedFunction();
3914 const IRPosition &FnPos = IRPosition::function(*F);
3915 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3916 return clampStateAndIndicateChange(
3917 getState(),
3918 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3919 }
3920
3921 /// See AbstractAttribute::trackStatistics()
3922 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3923};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003924
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003925/// ----------------------- Variable Capturing ---------------------------------
3926
3927/// A class to hold the state of for no-capture attributes.
3928struct AANoCaptureImpl : public AANoCapture {
3929 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3930
3931 /// See AbstractAttribute::initialize(...).
3932 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003933 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3934 indicateOptimisticFixpoint();
3935 return;
3936 }
3937 Function *AnchorScope = getAnchorScope();
3938 if (isFnInterfaceKind() &&
3939 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3940 indicatePessimisticFixpoint();
3941 return;
3942 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003943
Johannes Doerfert72adda12019-10-10 05:33:21 +00003944 // You cannot "capture" null in the default address space.
3945 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3946 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3947 indicateOptimisticFixpoint();
3948 return;
3949 }
3950
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003951 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003952
3953 // Check what state the associated function can actually capture.
3954 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003955 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003956 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003957 indicatePessimisticFixpoint();
3958 }
3959
3960 /// See AbstractAttribute::updateImpl(...).
3961 ChangeStatus updateImpl(Attributor &A) override;
3962
3963 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3964 virtual void
3965 getDeducedAttributes(LLVMContext &Ctx,
3966 SmallVectorImpl<Attribute> &Attrs) const override {
3967 if (!isAssumedNoCaptureMaybeReturned())
3968 return;
3969
Hideto Ueno37367642019-09-11 06:52:11 +00003970 if (getArgNo() >= 0) {
3971 if (isAssumedNoCapture())
3972 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3973 else if (ManifestInternal)
3974 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3975 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003976 }
3977
3978 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3979 /// depending on the ability of the function associated with \p IRP to capture
3980 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003981 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3982 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003983 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003984 // TODO: Once we have memory behavior attributes we should use them here.
3985
3986 // If we know we cannot communicate or write to memory, we do not care about
3987 // ptr2int anymore.
3988 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3989 F.getReturnType()->isVoidTy()) {
3990 State.addKnownBits(NO_CAPTURE);
3991 return;
3992 }
3993
3994 // A function cannot capture state in memory if it only reads memory, it can
3995 // however return/throw state and the state might be influenced by the
3996 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3997 if (F.onlyReadsMemory())
3998 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3999
4000 // A function cannot communicate state back if it does not through
4001 // exceptions and doesn not return values.
4002 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
4003 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004004
4005 // Check existing "returned" attributes.
4006 int ArgNo = IRP.getArgNo();
4007 if (F.doesNotThrow() && ArgNo >= 0) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01004008 for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
Johannes Doerfert3839b572019-10-21 00:48:42 +00004009 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00004010 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00004011 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
4012 else if (F.onlyReadsMemory())
4013 State.addKnownBits(NO_CAPTURE);
4014 else
4015 State.addKnownBits(NOT_CAPTURED_IN_RET);
4016 break;
4017 }
4018 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004019 }
4020
4021 /// See AbstractState::getAsStr().
4022 const std::string getAsStr() const override {
4023 if (isKnownNoCapture())
4024 return "known not-captured";
4025 if (isAssumedNoCapture())
4026 return "assumed not-captured";
4027 if (isKnownNoCaptureMaybeReturned())
4028 return "known not-captured-maybe-returned";
4029 if (isAssumedNoCaptureMaybeReturned())
4030 return "assumed not-captured-maybe-returned";
4031 return "assumed-captured";
4032 }
4033};
4034
4035/// Attributor-aware capture tracker.
4036struct AACaptureUseTracker final : public CaptureTracker {
4037
4038 /// Create a capture tracker that can lookup in-flight abstract attributes
4039 /// through the Attributor \p A.
4040 ///
4041 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
4042 /// search is stopped. If a use leads to a return instruction,
4043 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
4044 /// If a use leads to a ptr2int which may capture the value,
4045 /// \p CapturedInInteger is set. If a use is found that is currently assumed
4046 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
4047 /// set. All values in \p PotentialCopies are later tracked as well. For every
4048 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
4049 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
4050 /// conservatively set to true.
4051 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05004052 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004053 SmallVectorImpl<const Value *> &PotentialCopies,
4054 unsigned &RemainingUsesToExplore)
4055 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
4056 PotentialCopies(PotentialCopies),
4057 RemainingUsesToExplore(RemainingUsesToExplore) {}
4058
4059 /// Determine if \p V maybe captured. *Also updates the state!*
4060 bool valueMayBeCaptured(const Value *V) {
4061 if (V->getType()->isPointerTy()) {
4062 PointerMayBeCaptured(V, this);
4063 } else {
4064 State.indicatePessimisticFixpoint();
4065 }
4066 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4067 }
4068
4069 /// See CaptureTracker::tooManyUses().
4070 void tooManyUses() override {
4071 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
4072 }
4073
4074 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
4075 if (CaptureTracker::isDereferenceableOrNull(O, DL))
4076 return true;
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004077 const auto &DerefAA = A.getAAFor<AADereferenceable>(
4078 NoCaptureAA, IRPosition::value(*O), /* TrackDependence */ true,
4079 DepClassTy::OPTIONAL);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004080 return DerefAA.getAssumedDereferenceableBytes();
4081 }
4082
4083 /// See CaptureTracker::captured(...).
4084 bool captured(const Use *U) override {
4085 Instruction *UInst = cast<Instruction>(U->getUser());
4086 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
4087 << "\n");
4088
4089 // Because we may reuse the tracker multiple times we keep track of the
4090 // number of explored uses ourselves as well.
4091 if (RemainingUsesToExplore-- == 0) {
4092 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
4093 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4094 /* Return */ true);
4095 }
4096
4097 // Deal with ptr2int by following uses.
4098 if (isa<PtrToIntInst>(UInst)) {
4099 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
4100 return valueMayBeCaptured(UInst);
4101 }
4102
4103 // Explicitly catch return instructions.
4104 if (isa<ReturnInst>(UInst))
4105 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4106 /* Return */ true);
4107
4108 // For now we only use special logic for call sites. However, the tracker
4109 // itself knows about a lot of other non-capturing cases already.
4110 CallSite CS(UInst);
4111 if (!CS || !CS.isArgOperand(U))
4112 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4113 /* Return */ true);
4114
4115 unsigned ArgNo = CS.getArgumentNo(U);
4116 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
4117 // If we have a abstract no-capture attribute for the argument we can use
4118 // it to justify a non-capture attribute here. This allows recursion!
4119 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
4120 if (ArgNoCaptureAA.isAssumedNoCapture())
4121 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4122 /* Return */ false);
4123 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4124 addPotentialCopy(CS);
4125 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4126 /* Return */ false);
4127 }
4128
4129 // Lastly, we could not find a reason no-capture can be assumed so we don't.
4130 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4131 /* Return */ true);
4132 }
4133
4134 /// Register \p CS as potential copy of the value we are checking.
4135 void addPotentialCopy(CallSite CS) {
4136 PotentialCopies.push_back(CS.getInstruction());
4137 }
4138
4139 /// See CaptureTracker::shouldExplore(...).
4140 bool shouldExplore(const Use *U) override {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004141 // Check liveness, if it is used to stop exploring we need a dependence.
4142 if (IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()))) {
4143 A.recordDependence(IsDeadAA, NoCaptureAA, DepClassTy::OPTIONAL);
4144 return false;
4145 }
4146 return true;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004147 }
4148
4149 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
4150 /// \p CapturedInRet, then return the appropriate value for use in the
4151 /// CaptureTracker::captured() interface.
4152 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
4153 bool CapturedInRet) {
4154 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
4155 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
4156 if (CapturedInMem)
4157 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
4158 if (CapturedInInt)
4159 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
4160 if (CapturedInRet)
4161 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
4162 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4163 }
4164
4165private:
4166 /// The attributor providing in-flight abstract attributes.
4167 Attributor &A;
4168
4169 /// The abstract attribute currently updated.
4170 AANoCapture &NoCaptureAA;
4171
4172 /// The abstract liveness state.
4173 const AAIsDead &IsDeadAA;
4174
4175 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05004176 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004177
4178 /// Set of potential copies of the tracked value.
4179 SmallVectorImpl<const Value *> &PotentialCopies;
4180
4181 /// Global counter to limit the number of explored uses.
4182 unsigned &RemainingUsesToExplore;
4183};
4184
4185ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
4186 const IRPosition &IRP = getIRPosition();
4187 const Value *V =
4188 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
4189 if (!V)
4190 return indicatePessimisticFixpoint();
4191
4192 const Function *F =
4193 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
4194 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00004195 const IRPosition &FnPos = IRPosition::function(*F);
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004196 const auto &IsDeadAA =
4197 A.getAAFor<AAIsDead>(*this, FnPos, /* TrackDependence */ false);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004198
4199 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004200
Johannes Doerfert3839b572019-10-21 00:48:42 +00004201 // Readonly means we cannot capture through memory.
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004202 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(
4203 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004204 if (FnMemAA.isAssumedReadOnly()) {
4205 T.addKnownBits(NOT_CAPTURED_IN_MEM);
4206 if (FnMemAA.isKnownReadOnly())
4207 addKnownBits(NOT_CAPTURED_IN_MEM);
4208 }
4209
4210 // Make sure all returned values are different than the underlying value.
4211 // TODO: we could do this in a more sophisticated way inside
4212 // AAReturnedValues, e.g., track all values that escape through returns
4213 // directly somehow.
4214 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
4215 bool SeenConstant = false;
4216 for (auto &It : RVAA.returned_values()) {
4217 if (isa<Constant>(It.first)) {
4218 if (SeenConstant)
4219 return false;
4220 SeenConstant = true;
4221 } else if (!isa<Argument>(It.first) ||
4222 It.first == getAssociatedArgument())
4223 return false;
4224 }
4225 return true;
4226 };
4227
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004228 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(
4229 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004230 if (NoUnwindAA.isAssumedNoUnwind()) {
4231 bool IsVoidTy = F->getReturnType()->isVoidTy();
4232 const AAReturnedValues *RVAA =
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004233 IsVoidTy ? nullptr
4234 : &A.getAAFor<AAReturnedValues>(*this, FnPos,
4235 /* TrackDependence */ true,
4236 DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004237 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
4238 T.addKnownBits(NOT_CAPTURED_IN_RET);
4239 if (T.isKnown(NOT_CAPTURED_IN_MEM))
4240 return ChangeStatus::UNCHANGED;
4241 if (NoUnwindAA.isKnownNoUnwind() &&
4242 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
4243 addKnownBits(NOT_CAPTURED_IN_RET);
4244 if (isKnown(NOT_CAPTURED_IN_MEM))
4245 return indicateOptimisticFixpoint();
4246 }
4247 }
4248 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004249
4250 // Use the CaptureTracker interface and logic with the specialized tracker,
4251 // defined in AACaptureUseTracker, that can look at in-flight abstract
4252 // attributes and directly updates the assumed state.
4253 SmallVector<const Value *, 4> PotentialCopies;
4254 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
4255 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
4256 RemainingUsesToExplore);
4257
4258 // Check all potential copies of the associated value until we can assume
4259 // none will be captured or we have to assume at least one might be.
4260 unsigned Idx = 0;
4261 PotentialCopies.push_back(V);
4262 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
4263 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
4264
Johannes Doerfert1a746452019-10-20 22:28:49 -05004265 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004266 auto Assumed = S.getAssumed();
4267 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05004268 if (!isAssumedNoCaptureMaybeReturned())
4269 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004270 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
4271 : ChangeStatus::CHANGED;
4272}
4273
4274/// NoCapture attribute for function arguments.
4275struct AANoCaptureArgument final : AANoCaptureImpl {
4276 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4277
4278 /// See AbstractAttribute::trackStatistics()
4279 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
4280};
4281
4282/// NoCapture attribute for call site arguments.
4283struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
4284 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4285
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004286 /// See AbstractAttribute::initialize(...).
4287 void initialize(Attributor &A) override {
4288 if (Argument *Arg = getAssociatedArgument())
4289 if (Arg->hasByValAttr())
4290 indicateOptimisticFixpoint();
4291 AANoCaptureImpl::initialize(A);
4292 }
4293
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004294 /// See AbstractAttribute::updateImpl(...).
4295 ChangeStatus updateImpl(Attributor &A) override {
4296 // TODO: Once we have call site specific value information we can provide
4297 // call site specific liveness information and then it makes
4298 // sense to specialize attributes for call sites arguments instead of
4299 // redirecting requests to the callee argument.
4300 Argument *Arg = getAssociatedArgument();
4301 if (!Arg)
4302 return indicatePessimisticFixpoint();
4303 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4304 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
4305 return clampStateAndIndicateChange(
4306 getState(),
4307 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
4308 }
4309
4310 /// See AbstractAttribute::trackStatistics()
4311 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
4312};
4313
4314/// NoCapture attribute for floating values.
4315struct AANoCaptureFloating final : AANoCaptureImpl {
4316 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4317
4318 /// See AbstractAttribute::trackStatistics()
4319 void trackStatistics() const override {
4320 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
4321 }
4322};
4323
4324/// NoCapture attribute for function return value.
4325struct AANoCaptureReturned final : AANoCaptureImpl {
4326 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
4327 llvm_unreachable("NoCapture is not applicable to function returns!");
4328 }
4329
4330 /// See AbstractAttribute::initialize(...).
4331 void initialize(Attributor &A) override {
4332 llvm_unreachable("NoCapture is not applicable to function returns!");
4333 }
4334
4335 /// See AbstractAttribute::updateImpl(...).
4336 ChangeStatus updateImpl(Attributor &A) override {
4337 llvm_unreachable("NoCapture is not applicable to function returns!");
4338 }
4339
4340 /// See AbstractAttribute::trackStatistics()
4341 void trackStatistics() const override {}
4342};
4343
4344/// NoCapture attribute deduction for a call site return value.
4345struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
4346 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4347
4348 /// See AbstractAttribute::trackStatistics()
4349 void trackStatistics() const override {
4350 STATS_DECLTRACK_CSRET_ATTR(nocapture)
4351 }
4352};
4353
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004354/// ------------------ Value Simplify Attribute ----------------------------
4355struct AAValueSimplifyImpl : AAValueSimplify {
4356 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
4357
Johannes Doerfert9dcf8892020-01-11 23:59:36 -06004358 /// See AbstractAttribute::initialize(...).
4359 void initialize(Attributor &A) override {
4360 if (getAssociatedValue().getType()->isVoidTy())
4361 indicatePessimisticFixpoint();
4362 }
4363
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004364 /// See AbstractAttribute::getAsStr().
4365 const std::string getAsStr() const override {
4366 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
4367 : "not-simple";
4368 }
4369
4370 /// See AbstractAttribute::trackStatistics()
4371 void trackStatistics() const override {}
4372
4373 /// See AAValueSimplify::getAssumedSimplifiedValue()
4374 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
4375 if (!getAssumed())
4376 return const_cast<Value *>(&getAssociatedValue());
4377 return SimplifiedAssociatedValue;
4378 }
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004379
4380 /// Helper function for querying AAValueSimplify and updating candicate.
4381 /// \param QueryingValue Value trying to unify with SimplifiedValue
4382 /// \param AccumulatedSimplifiedValue Current simplification result.
4383 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
4384 Value &QueryingValue,
4385 Optional<Value *> &AccumulatedSimplifiedValue) {
4386 // FIXME: Add a typecast support.
4387
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004388 auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004389 QueryingAA, IRPosition::value(QueryingValue));
4390
4391 Optional<Value *> QueryingValueSimplified =
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004392 ValueSimplifyAA.getAssumedSimplifiedValue(A);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004393
4394 if (!QueryingValueSimplified.hasValue())
4395 return true;
4396
4397 if (!QueryingValueSimplified.getValue())
4398 return false;
4399
4400 Value &QueryingValueSimplifiedUnwrapped =
4401 *QueryingValueSimplified.getValue();
4402
4403 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
4404 return true;
4405
4406 if (AccumulatedSimplifiedValue.hasValue())
4407 return AccumulatedSimplifiedValue == QueryingValueSimplified;
4408
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004409 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << QueryingValue
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004410 << " is assumed to be "
4411 << QueryingValueSimplifiedUnwrapped << "\n");
4412
4413 AccumulatedSimplifiedValue = QueryingValueSimplified;
4414 return true;
4415 }
4416
Hideto Ueno188f9a32020-01-15 15:25:52 +09004417 bool askSimplifiedValueForAAValueConstantRange(Attributor &A) {
4418 if (!getAssociatedValue().getType()->isIntegerTy())
4419 return false;
4420
4421 const auto &ValueConstantRangeAA =
4422 A.getAAFor<AAValueConstantRange>(*this, getIRPosition());
4423
4424 Optional<ConstantInt *> COpt =
4425 ValueConstantRangeAA.getAssumedConstantInt(A);
4426 if (COpt.hasValue()) {
4427 if (auto *C = COpt.getValue())
4428 SimplifiedAssociatedValue = C;
4429 else
4430 return false;
4431 } else {
Johannes Doerfert63adbb92020-02-09 20:21:56 -06004432 SimplifiedAssociatedValue = llvm::None;
Hideto Ueno188f9a32020-01-15 15:25:52 +09004433 }
4434 return true;
4435 }
4436
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004437 /// See AbstractAttribute::manifest(...).
4438 ChangeStatus manifest(Attributor &A) override {
4439 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4440
4441 if (!SimplifiedAssociatedValue.hasValue() ||
4442 !SimplifiedAssociatedValue.getValue())
4443 return Changed;
4444
4445 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
4446 // We can replace the AssociatedValue with the constant.
4447 Value &V = getAssociatedValue();
4448 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004449 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *C
4450 << " :: " << *this << "\n");
Johannes Doerfert4c62a352020-01-12 00:17:08 -06004451 if (A.changeValueAfterManifest(V, *C))
4452 Changed = ChangeStatus::CHANGED;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004453 }
4454 }
4455
4456 return Changed | AAValueSimplify::manifest(A);
4457 }
4458
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004459 /// See AbstractState::indicatePessimisticFixpoint(...).
4460 ChangeStatus indicatePessimisticFixpoint() override {
4461 // NOTE: Associated value will be returned in a pessimistic fixpoint and is
4462 // regarded as known. That's why`indicateOptimisticFixpoint` is called.
4463 SimplifiedAssociatedValue = &getAssociatedValue();
Johannes Doerferta4b35882019-12-31 13:25:47 -06004464 indicateOptimisticFixpoint();
4465 return ChangeStatus::CHANGED;
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004466 }
4467
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004468protected:
4469 // An assumed simplified value. Initially, it is set to Optional::None, which
4470 // means that the value is not clear under current assumption. If in the
4471 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4472 // returns orignal associated value.
4473 Optional<Value *> SimplifiedAssociatedValue;
4474};
4475
4476struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
4477 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4478
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004479 void initialize(Attributor &A) override {
4480 AAValueSimplifyImpl::initialize(A);
4481 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
4482 indicatePessimisticFixpoint();
4483 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
4484 /* IgnoreSubsumingPositions */ true))
4485 indicatePessimisticFixpoint();
4486 }
4487
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004488 /// See AbstractAttribute::updateImpl(...).
4489 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004490 // Byval is only replacable if it is readonly otherwise we would write into
4491 // the replaced value and not the copy that byval creates implicitly.
4492 Argument *Arg = getAssociatedArgument();
4493 if (Arg->hasByValAttr()) {
4494 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
4495 if (!MemAA.isAssumedReadOnly())
4496 return indicatePessimisticFixpoint();
4497 }
4498
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004499 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4500
Johannes Doerfert661db042019-10-07 23:14:58 +00004501 auto PredForCallSite = [&](AbstractCallSite ACS) {
4502 // Check if we have an associated argument or not (which can happen for
4503 // callback calls).
Johannes Doerferte360ee62019-11-01 18:45:25 -05004504 Value *ArgOp = ACS.getCallArgOperand(getArgNo());
4505 if (!ArgOp)
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004506 return false;
Johannes Doerferte360ee62019-11-01 18:45:25 -05004507 // We can only propagate thread independent values through callbacks.
4508 // This is different to direct/indirect call sites because for them we
4509 // know the thread executing the caller and callee is the same. For
4510 // callbacks this is not guaranteed, thus a thread dependent value could
4511 // be different for the caller and callee, making it invalid to propagate.
4512 if (ACS.isCallbackCall())
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004513 if (auto *C = dyn_cast<Constant>(ArgOp))
Johannes Doerferte360ee62019-11-01 18:45:25 -05004514 if (C->isThreadDependent())
4515 return false;
4516 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004517 };
4518
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004519 bool AllCallSitesKnown;
4520 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4521 AllCallSitesKnown))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004522 if (!askSimplifiedValueForAAValueConstantRange(A))
4523 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004524
4525 // If a candicate was found in this update, return CHANGED.
4526 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4527 ? ChangeStatus::UNCHANGED
4528 : ChangeStatus ::CHANGED;
4529 }
4530
4531 /// See AbstractAttribute::trackStatistics()
4532 void trackStatistics() const override {
4533 STATS_DECLTRACK_ARG_ATTR(value_simplify)
4534 }
4535};
4536
4537struct AAValueSimplifyReturned : AAValueSimplifyImpl {
4538 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4539
4540 /// See AbstractAttribute::updateImpl(...).
4541 ChangeStatus updateImpl(Attributor &A) override {
4542 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4543
4544 auto PredForReturned = [&](Value &V) {
4545 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4546 };
4547
4548 if (!A.checkForAllReturnedValues(PredForReturned, *this))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004549 if (!askSimplifiedValueForAAValueConstantRange(A))
4550 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004551
4552 // If a candicate was found in this update, return CHANGED.
4553 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4554 ? ChangeStatus::UNCHANGED
4555 : ChangeStatus ::CHANGED;
4556 }
4557 /// See AbstractAttribute::trackStatistics()
4558 void trackStatistics() const override {
4559 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
4560 }
4561};
4562
4563struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4564 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4565
4566 /// See AbstractAttribute::initialize(...).
4567 void initialize(Attributor &A) override {
4568 Value &V = getAnchorValue();
4569
4570 // TODO: add other stuffs
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004571 if (isa<Constant>(V))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004572 indicatePessimisticFixpoint();
4573 }
4574
4575 /// See AbstractAttribute::updateImpl(...).
4576 ChangeStatus updateImpl(Attributor &A) override {
4577 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4578
Johannes Doerfert76843ba2020-01-28 23:51:25 -06004579 auto VisitValueCB = [&](Value &V, bool &, bool Stripped) -> bool {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004580 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
4581 if (!Stripped && this == &AA) {
4582 // TODO: Look the instruction and check recursively.
Hideto Ueno188f9a32020-01-15 15:25:52 +09004583
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004584 LLVM_DEBUG(dbgs() << "[ValueSimplify] Can't be stripped more : " << V
4585 << "\n");
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004586 return false;
4587 }
4588 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4589 };
4590
Johannes Doerfert76843ba2020-01-28 23:51:25 -06004591 bool Dummy = false;
Johannes Doerfert6626d1b2020-01-28 11:49:59 -06004592 if (!genericValueTraversal<AAValueSimplify, bool>(A, getIRPosition(), *this,
4593 Dummy, VisitValueCB))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004594 if (!askSimplifiedValueForAAValueConstantRange(A))
4595 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004596
4597 // If a candicate was found in this update, return CHANGED.
4598
4599 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4600 ? ChangeStatus::UNCHANGED
4601 : ChangeStatus ::CHANGED;
4602 }
4603
4604 /// See AbstractAttribute::trackStatistics()
4605 void trackStatistics() const override {
4606 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
4607 }
4608};
4609
4610struct AAValueSimplifyFunction : AAValueSimplifyImpl {
4611 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4612
4613 /// See AbstractAttribute::initialize(...).
4614 void initialize(Attributor &A) override {
4615 SimplifiedAssociatedValue = &getAnchorValue();
4616 indicateOptimisticFixpoint();
4617 }
4618 /// See AbstractAttribute::initialize(...).
4619 ChangeStatus updateImpl(Attributor &A) override {
4620 llvm_unreachable(
4621 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
4622 }
4623 /// See AbstractAttribute::trackStatistics()
4624 void trackStatistics() const override {
4625 STATS_DECLTRACK_FN_ATTR(value_simplify)
4626 }
4627};
4628
4629struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
4630 AAValueSimplifyCallSite(const IRPosition &IRP)
4631 : AAValueSimplifyFunction(IRP) {}
4632 /// See AbstractAttribute::trackStatistics()
4633 void trackStatistics() const override {
4634 STATS_DECLTRACK_CS_ATTR(value_simplify)
4635 }
4636};
4637
4638struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
4639 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
4640 : AAValueSimplifyReturned(IRP) {}
4641
4642 void trackStatistics() const override {
4643 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
4644 }
4645};
4646struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
4647 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
4648 : AAValueSimplifyFloating(IRP) {}
4649
4650 void trackStatistics() const override {
4651 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
4652 }
4653};
4654
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004655/// ----------------------- Heap-To-Stack Conversion ---------------------------
4656struct AAHeapToStackImpl : public AAHeapToStack {
4657 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
4658
4659 const std::string getAsStr() const override {
4660 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
4661 }
4662
4663 ChangeStatus manifest(Attributor &A) override {
4664 assert(getState().isValidState() &&
4665 "Attempted to manifest an invalid state!");
4666
4667 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4668 Function *F = getAssociatedFunction();
4669 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4670
4671 for (Instruction *MallocCall : MallocCalls) {
4672 // This malloc cannot be replaced.
4673 if (BadMallocCalls.count(MallocCall))
4674 continue;
4675
4676 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
4677 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
4678 A.deleteAfterManifest(*FreeCall);
4679 HasChanged = ChangeStatus::CHANGED;
4680 }
4681
4682 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
4683 << "\n");
4684
4685 Constant *Size;
4686 if (isCallocLikeFn(MallocCall, TLI)) {
4687 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
4688 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
4689 APInt TotalSize = SizeT->getValue() * Num->getValue();
4690 Size =
4691 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
4692 } else {
4693 Size = cast<ConstantInt>(MallocCall->getOperand(0));
4694 }
4695
4696 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
4697 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
4698 Size, "", MallocCall->getNextNode());
4699
4700 if (AI->getType() != MallocCall->getType())
4701 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
4702 AI->getNextNode());
4703
Johannes Doerfert4c62a352020-01-12 00:17:08 -06004704 A.changeValueAfterManifest(*MallocCall, *AI);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004705
4706 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
4707 auto *NBB = II->getNormalDest();
4708 BranchInst::Create(NBB, MallocCall->getParent());
4709 A.deleteAfterManifest(*MallocCall);
4710 } else {
4711 A.deleteAfterManifest(*MallocCall);
4712 }
4713
4714 if (isCallocLikeFn(MallocCall, TLI)) {
4715 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
4716 AI->getNextNode());
4717 Value *Ops[] = {
4718 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
4719 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
4720
4721 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
4722 Module *M = F->getParent();
4723 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
4724 CallInst::Create(Fn, Ops, "", BI->getNextNode());
4725 }
4726 HasChanged = ChangeStatus::CHANGED;
4727 }
4728
4729 return HasChanged;
4730 }
4731
4732 /// Collection of all malloc calls in a function.
4733 SmallSetVector<Instruction *, 4> MallocCalls;
4734
4735 /// Collection of malloc calls that cannot be converted.
4736 DenseSet<const Instruction *> BadMallocCalls;
4737
4738 /// A map for each malloc call to the set of associated free calls.
4739 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
4740
4741 ChangeStatus updateImpl(Attributor &A) override;
4742};
4743
4744ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4745 const Function *F = getAssociatedFunction();
4746 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4747
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004748 MustBeExecutedContextExplorer &Explorer =
4749 A.getInfoCache().getMustBeExecutedContextExplorer();
4750
4751 auto FreeCheck = [&](Instruction &I) {
4752 const auto &Frees = FreesForMalloc.lookup(&I);
4753 if (Frees.size() != 1)
4754 return false;
4755 Instruction *UniqueFree = *Frees.begin();
4756 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
4757 };
4758
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004759 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004760 bool ValidUsesOnly = true;
4761 bool MustUse = true;
Hideto Ueno827bade2019-12-12 12:26:30 +00004762 auto Pred = [&](const Use &U, bool &Follow) -> bool {
4763 Instruction *UserI = cast<Instruction>(U.getUser());
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004764 if (isa<LoadInst>(UserI))
Hideto Ueno827bade2019-12-12 12:26:30 +00004765 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004766 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004767 if (SI->getValueOperand() == U.get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004768 LLVM_DEBUG(dbgs()
4769 << "[H2S] escaping store to memory: " << *UserI << "\n");
4770 ValidUsesOnly = false;
4771 } else {
4772 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004773 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004774 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004775 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004776 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004777 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
4778 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004779 // Record malloc.
4780 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004781 if (MustUse) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004782 FreesForMalloc[&I].insert(UserI);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004783 } else {
4784 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
4785 << *UserI << "\n");
4786 ValidUsesOnly = false;
4787 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004788 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004789 }
4790
Hideto Ueno827bade2019-12-12 12:26:30 +00004791 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004792
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004793 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
4794 *this, IRPosition::callsite_argument(*CB, ArgNo));
4795
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004796 // If a callsite argument use is nofree, we are fine.
4797 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
4798 *this, IRPosition::callsite_argument(*CB, ArgNo));
4799
Hideto Ueno827bade2019-12-12 12:26:30 +00004800 if (!NoCaptureAA.isAssumedNoCapture() ||
4801 !ArgNoFreeAA.isAssumedNoFree()) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004802 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004803 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004804 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004805 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004806 }
4807
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004808 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
4809 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
4810 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Hideto Ueno827bade2019-12-12 12:26:30 +00004811 Follow = true;
4812 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004813 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004814 // Unknown user for which we can not track uses further (in a way that
4815 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004816 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004817 ValidUsesOnly = false;
Hideto Ueno827bade2019-12-12 12:26:30 +00004818 return true;
4819 };
4820 A.checkForAllUses(Pred, *this, I);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004821 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004822 };
4823
4824 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004825 if (BadMallocCalls.count(&I))
4826 return true;
4827
4828 bool IsMalloc = isMallocLikeFn(&I, TLI);
4829 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
4830 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004831 BadMallocCalls.insert(&I);
4832 return true;
4833 }
4834
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004835 if (IsMalloc) {
4836 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004837 if (Size->getValue().ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004838 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004839 MallocCalls.insert(&I);
4840 return true;
4841 }
4842 } else if (IsCalloc) {
4843 bool Overflow = false;
4844 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
4845 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
4846 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004847 .ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004848 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004849 MallocCalls.insert(&I);
4850 return true;
4851 }
4852 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004853
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004854 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004855 return true;
4856 };
4857
4858 size_t NumBadMallocs = BadMallocCalls.size();
4859
4860 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4861
4862 if (NumBadMallocs != BadMallocCalls.size())
4863 return ChangeStatus::CHANGED;
4864
4865 return ChangeStatus::UNCHANGED;
4866}
4867
4868struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4869 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4870
4871 /// See AbstractAttribute::trackStatistics()
4872 void trackStatistics() const override {
4873 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004874 "Number of malloc calls converted to allocas");
4875 for (auto *C : MallocCalls)
4876 if (!BadMallocCalls.count(C))
4877 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004878 }
4879};
4880
Johannes Doerfert89c2e732019-10-30 17:20:20 -05004881/// ----------------------- Privatizable Pointers ------------------------------
4882struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
4883 AAPrivatizablePtrImpl(const IRPosition &IRP)
4884 : AAPrivatizablePtr(IRP), PrivatizableType(llvm::None) {}
4885
4886 ChangeStatus indicatePessimisticFixpoint() override {
4887 AAPrivatizablePtr::indicatePessimisticFixpoint();
4888 PrivatizableType = nullptr;
4889 return ChangeStatus::CHANGED;
4890 }
4891
4892 /// Identify the type we can chose for a private copy of the underlying
4893 /// argument. None means it is not clear yet, nullptr means there is none.
4894 virtual Optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
4895
4896 /// Return a privatizable type that encloses both T0 and T1.
4897 /// TODO: This is merely a stub for now as we should manage a mapping as well.
4898 Optional<Type *> combineTypes(Optional<Type *> T0, Optional<Type *> T1) {
4899 if (!T0.hasValue())
4900 return T1;
4901 if (!T1.hasValue())
4902 return T0;
4903 if (T0 == T1)
4904 return T0;
4905 return nullptr;
4906 }
4907
4908 Optional<Type *> getPrivatizableType() const override {
4909 return PrivatizableType;
4910 }
4911
4912 const std::string getAsStr() const override {
4913 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
4914 }
4915
4916protected:
4917 Optional<Type *> PrivatizableType;
4918};
4919
4920// TODO: Do this for call site arguments (probably also other values) as well.
4921
4922struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
4923 AAPrivatizablePtrArgument(const IRPosition &IRP)
4924 : AAPrivatizablePtrImpl(IRP) {}
4925
4926 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
4927 Optional<Type *> identifyPrivatizableType(Attributor &A) override {
4928 // If this is a byval argument and we know all the call sites (so we can
4929 // rewrite them), there is no need to check them explicitly.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004930 bool AllCallSitesKnown;
Johannes Doerfert89c2e732019-10-30 17:20:20 -05004931 if (getIRPosition().hasAttr(Attribute::ByVal) &&
4932 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004933 true, AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05004934 return getAssociatedValue().getType()->getPointerElementType();
4935
4936 Optional<Type *> Ty;
4937 unsigned ArgNo = getIRPosition().getArgNo();
4938
4939 // Make sure the associated call site argument has the same type at all call
4940 // sites and it is an allocation we know is safe to privatize, for now that
4941 // means we only allow alloca instructions.
4942 // TODO: We can additionally analyze the accesses in the callee to create
4943 // the type from that information instead. That is a little more
4944 // involved and will be done in a follow up patch.
4945 auto CallSiteCheck = [&](AbstractCallSite ACS) {
4946 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
4947 // Check if a coresponding argument was found or if it is one not
4948 // associated (which can happen for callback calls).
4949 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
4950 return false;
4951
4952 // Check that all call sites agree on a type.
4953 auto &PrivCSArgAA = A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos);
4954 Optional<Type *> CSTy = PrivCSArgAA.getPrivatizableType();
4955
4956 LLVM_DEBUG({
4957 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
4958 if (CSTy.hasValue() && CSTy.getValue())
4959 CSTy.getValue()->print(dbgs());
4960 else if (CSTy.hasValue())
4961 dbgs() << "<nullptr>";
4962 else
4963 dbgs() << "<none>";
4964 });
4965
4966 Ty = combineTypes(Ty, CSTy);
4967
4968 LLVM_DEBUG({
4969 dbgs() << " : New Type: ";
4970 if (Ty.hasValue() && Ty.getValue())
4971 Ty.getValue()->print(dbgs());
4972 else if (Ty.hasValue())
4973 dbgs() << "<nullptr>";
4974 else
4975 dbgs() << "<none>";
4976 dbgs() << "\n";
4977 });
4978
4979 return !Ty.hasValue() || Ty.getValue();
4980 };
4981
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004982 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05004983 return nullptr;
4984 return Ty;
4985 }
4986
4987 /// See AbstractAttribute::updateImpl(...).
4988 ChangeStatus updateImpl(Attributor &A) override {
4989 PrivatizableType = identifyPrivatizableType(A);
4990 if (!PrivatizableType.hasValue())
4991 return ChangeStatus::UNCHANGED;
4992 if (!PrivatizableType.getValue())
4993 return indicatePessimisticFixpoint();
4994
4995 // Avoid arguments with padding for now.
4996 if (!getIRPosition().hasAttr(Attribute::ByVal) &&
4997 !ArgumentPromotionPass::isDenselyPacked(PrivatizableType.getValue(),
4998 A.getInfoCache().getDL())) {
4999 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
5000 return indicatePessimisticFixpoint();
5001 }
5002
5003 // Verify callee and caller agree on how the promoted argument would be
5004 // passed.
5005 // TODO: The use of the ArgumentPromotion interface here is ugly, we need a
5006 // specialized form of TargetTransformInfo::areFunctionArgsABICompatible
5007 // which doesn't require the arguments ArgumentPromotion wanted to pass.
5008 Function &Fn = *getIRPosition().getAnchorScope();
5009 SmallPtrSet<Argument *, 1> ArgsToPromote, Dummy;
5010 ArgsToPromote.insert(getAssociatedArgument());
5011 const auto *TTI =
5012 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
5013 if (!TTI ||
5014 !ArgumentPromotionPass::areFunctionArgsABICompatible(
5015 Fn, *TTI, ArgsToPromote, Dummy) ||
5016 ArgsToPromote.empty()) {
5017 LLVM_DEBUG(
5018 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
5019 << Fn.getName() << "\n");
5020 return indicatePessimisticFixpoint();
5021 }
5022
5023 // Collect the types that will replace the privatizable type in the function
5024 // signature.
5025 SmallVector<Type *, 16> ReplacementTypes;
5026 identifyReplacementTypes(PrivatizableType.getValue(), ReplacementTypes);
5027
5028 // Register a rewrite of the argument.
5029 Argument *Arg = getAssociatedArgument();
5030 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
5031 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
5032 return indicatePessimisticFixpoint();
5033 }
5034
5035 unsigned ArgNo = Arg->getArgNo();
5036
5037 // Helper to check if for the given call site the associated argument is
5038 // passed to a callback where the privatization would be different.
5039 auto IsCompatiblePrivArgOfCallback = [&](CallSite CS) {
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005040 SmallVector<const Use *, 4> CBUses;
5041 AbstractCallSite::getCallbackUses(CS, CBUses);
5042 for (const Use *U : CBUses) {
5043 AbstractCallSite CBACS(U);
5044 assert(CBACS && CBACS.isCallbackCall());
5045 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
5046 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
5047
5048 LLVM_DEBUG({
5049 dbgs()
5050 << "[AAPrivatizablePtr] Argument " << *Arg
5051 << "check if can be privatized in the context of its parent ("
5052 << Arg->getParent()->getName()
5053 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5054 "callback ("
5055 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
5056 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
Michael Forster676c2962020-01-30 10:20:49 +01005057 << CBACS.getCallArgOperand(CBArg) << " vs "
5058 << CS.getArgOperand(ArgNo) << "\n"
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005059 << "[AAPrivatizablePtr] " << CBArg << " : "
5060 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
5061 });
5062
5063 if (CBArgNo != int(ArgNo))
5064 continue;
5065 const auto &CBArgPrivAA =
5066 A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(CBArg));
5067 if (CBArgPrivAA.isValidState()) {
5068 auto CBArgPrivTy = CBArgPrivAA.getPrivatizableType();
5069 if (!CBArgPrivTy.hasValue())
5070 continue;
5071 if (CBArgPrivTy.getValue() == PrivatizableType)
5072 continue;
5073 }
5074
5075 LLVM_DEBUG({
5076 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5077 << " cannot be privatized in the context of its parent ("
5078 << Arg->getParent()->getName()
5079 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5080 "callback ("
5081 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
5082 << ").\n[AAPrivatizablePtr] for which the argument "
5083 "privatization is not compatible.\n";
5084 });
5085 return false;
5086 }
5087 }
5088 return true;
5089 };
5090
5091 // Helper to check if for the given call site the associated argument is
5092 // passed to a direct call where the privatization would be different.
5093 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
5094 CallBase *DC = cast<CallBase>(ACS.getInstruction());
5095 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
5096 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->getNumArgOperands() &&
5097 "Expected a direct call operand for callback call operand");
5098
5099 LLVM_DEBUG({
5100 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5101 << " check if be privatized in the context of its parent ("
5102 << Arg->getParent()->getName()
5103 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5104 "direct call of ("
5105 << DCArgNo << "@" << DC->getCalledFunction()->getName()
5106 << ").\n";
5107 });
5108
5109 Function *DCCallee = DC->getCalledFunction();
5110 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
5111 const auto &DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
5112 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)));
5113 if (DCArgPrivAA.isValidState()) {
5114 auto DCArgPrivTy = DCArgPrivAA.getPrivatizableType();
5115 if (!DCArgPrivTy.hasValue())
5116 return true;
5117 if (DCArgPrivTy.getValue() == PrivatizableType)
5118 return true;
5119 }
5120 }
5121
5122 LLVM_DEBUG({
5123 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5124 << " cannot be privatized in the context of its parent ("
5125 << Arg->getParent()->getName()
5126 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5127 "direct call of ("
5128 << ACS.getCallSite().getCalledFunction()->getName()
5129 << ").\n[AAPrivatizablePtr] for which the argument "
5130 "privatization is not compatible.\n";
5131 });
5132 return false;
5133 };
5134
5135 // Helper to check if the associated argument is used at the given abstract
5136 // call site in a way that is incompatible with the privatization assumed
5137 // here.
5138 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
5139 if (ACS.isDirectCall())
5140 return IsCompatiblePrivArgOfCallback(ACS.getCallSite());
5141 if (ACS.isCallbackCall())
5142 return IsCompatiblePrivArgOfDirectCS(ACS);
5143 return false;
5144 };
5145
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005146 bool AllCallSitesKnown;
5147 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
5148 AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005149 return indicatePessimisticFixpoint();
5150
5151 return ChangeStatus::UNCHANGED;
5152 }
5153
5154 /// Given a type to private \p PrivType, collect the constituates (which are
5155 /// used) in \p ReplacementTypes.
5156 static void
5157 identifyReplacementTypes(Type *PrivType,
5158 SmallVectorImpl<Type *> &ReplacementTypes) {
5159 // TODO: For now we expand the privatization type to the fullest which can
5160 // lead to dead arguments that need to be removed later.
5161 assert(PrivType && "Expected privatizable type!");
5162
5163 // Traverse the type, extract constituate types on the outermost level.
5164 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5165 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
5166 ReplacementTypes.push_back(PrivStructType->getElementType(u));
5167 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5168 ReplacementTypes.append(PrivArrayType->getNumElements(),
5169 PrivArrayType->getElementType());
5170 } else {
5171 ReplacementTypes.push_back(PrivType);
5172 }
5173 }
5174
5175 /// Initialize \p Base according to the type \p PrivType at position \p IP.
5176 /// The values needed are taken from the arguments of \p F starting at
5177 /// position \p ArgNo.
5178 static void createInitialization(Type *PrivType, Value &Base, Function &F,
5179 unsigned ArgNo, Instruction &IP) {
5180 assert(PrivType && "Expected privatizable type!");
5181
5182 IRBuilder<NoFolder> IRB(&IP);
5183 const DataLayout &DL = F.getParent()->getDataLayout();
5184
5185 // Traverse the type, build GEPs and stores.
5186 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5187 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
5188 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
5189 Type *PointeeTy = PrivStructType->getElementType(u)->getPointerTo();
5190 Value *Ptr = constructPointer(
5191 PointeeTy, &Base, PrivStructLayout->getElementOffset(u), IRB, DL);
5192 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
5193 }
5194 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5195 Type *PointeePtrTy = PrivArrayType->getElementType()->getPointerTo();
5196 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeePtrTy);
5197 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
5198 Value *Ptr =
5199 constructPointer(PointeePtrTy, &Base, u * PointeeTySize, IRB, DL);
5200 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
5201 }
5202 } else {
5203 new StoreInst(F.getArg(ArgNo), &Base, &IP);
5204 }
5205 }
5206
5207 /// Extract values from \p Base according to the type \p PrivType at the
5208 /// call position \p ACS. The values are appended to \p ReplacementValues.
5209 void createReplacementValues(Type *PrivType, AbstractCallSite ACS,
5210 Value *Base,
5211 SmallVectorImpl<Value *> &ReplacementValues) {
5212 assert(Base && "Expected base value!");
5213 assert(PrivType && "Expected privatizable type!");
5214 Instruction *IP = ACS.getInstruction();
5215
5216 IRBuilder<NoFolder> IRB(IP);
5217 const DataLayout &DL = IP->getModule()->getDataLayout();
5218
5219 if (Base->getType()->getPointerElementType() != PrivType)
5220 Base = BitCastInst::CreateBitOrPointerCast(Base, PrivType->getPointerTo(),
5221 "", ACS.getInstruction());
5222
5223 // TODO: Improve the alignment of the loads.
5224 // Traverse the type, build GEPs and loads.
5225 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5226 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
5227 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
5228 Type *PointeeTy = PrivStructType->getElementType(u);
5229 Value *Ptr =
5230 constructPointer(PointeeTy->getPointerTo(), Base,
5231 PrivStructLayout->getElementOffset(u), IRB, DL);
5232 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP);
5233 L->setAlignment(MaybeAlign(1));
5234 ReplacementValues.push_back(L);
5235 }
5236 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5237 Type *PointeeTy = PrivArrayType->getElementType();
5238 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
5239 Type *PointeePtrTy = PointeeTy->getPointerTo();
5240 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
5241 Value *Ptr =
5242 constructPointer(PointeePtrTy, Base, u * PointeeTySize, IRB, DL);
5243 LoadInst *L = new LoadInst(PointeePtrTy, Ptr, "", IP);
5244 L->setAlignment(MaybeAlign(1));
5245 ReplacementValues.push_back(L);
5246 }
5247 } else {
5248 LoadInst *L = new LoadInst(PrivType, Base, "", IP);
5249 L->setAlignment(MaybeAlign(1));
5250 ReplacementValues.push_back(L);
5251 }
5252 }
5253
5254 /// See AbstractAttribute::manifest(...)
5255 ChangeStatus manifest(Attributor &A) override {
5256 if (!PrivatizableType.hasValue())
5257 return ChangeStatus::UNCHANGED;
5258 assert(PrivatizableType.getValue() && "Expected privatizable type!");
5259
5260 // Collect all tail calls in the function as we cannot allow new allocas to
5261 // escape into tail recursion.
5262 // TODO: Be smarter about new allocas escaping into tail calls.
5263 SmallVector<CallInst *, 16> TailCalls;
5264 if (!A.checkForAllInstructions(
5265 [&](Instruction &I) {
5266 CallInst &CI = cast<CallInst>(I);
5267 if (CI.isTailCall())
5268 TailCalls.push_back(&CI);
5269 return true;
5270 },
5271 *this, {Instruction::Call}))
5272 return ChangeStatus::UNCHANGED;
5273
5274 Argument *Arg = getAssociatedArgument();
5275
5276 // Callback to repair the associated function. A new alloca is placed at the
5277 // beginning and initialized with the values passed through arguments. The
5278 // new alloca replaces the use of the old pointer argument.
5279 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB =
5280 [=](const Attributor::ArgumentReplacementInfo &ARI,
5281 Function &ReplacementFn, Function::arg_iterator ArgIt) {
5282 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
5283 Instruction *IP = &*EntryBB.getFirstInsertionPt();
5284 auto *AI = new AllocaInst(PrivatizableType.getValue(), 0,
5285 Arg->getName() + ".priv", IP);
5286 createInitialization(PrivatizableType.getValue(), *AI, ReplacementFn,
5287 ArgIt->getArgNo(), *IP);
5288 Arg->replaceAllUsesWith(AI);
5289
5290 for (CallInst *CI : TailCalls)
5291 CI->setTailCall(false);
5292 };
5293
5294 // Callback to repair a call site of the associated function. The elements
5295 // of the privatizable type are loaded prior to the call and passed to the
5296 // new function version.
5297 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB =
5298 [=](const Attributor::ArgumentReplacementInfo &ARI,
5299 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
5300 createReplacementValues(
5301 PrivatizableType.getValue(), ACS,
5302 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
5303 NewArgOperands);
5304 };
5305
5306 // Collect the types that will replace the privatizable type in the function
5307 // signature.
5308 SmallVector<Type *, 16> ReplacementTypes;
5309 identifyReplacementTypes(PrivatizableType.getValue(), ReplacementTypes);
5310
5311 // Register a rewrite of the argument.
5312 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
5313 std::move(FnRepairCB),
5314 std::move(ACSRepairCB)))
5315 return ChangeStatus::CHANGED;
5316 return ChangeStatus::UNCHANGED;
5317 }
5318
5319 /// See AbstractAttribute::trackStatistics()
5320 void trackStatistics() const override {
5321 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
5322 }
5323};
5324
5325struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
5326 AAPrivatizablePtrFloating(const IRPosition &IRP)
5327 : AAPrivatizablePtrImpl(IRP) {}
5328
5329 /// See AbstractAttribute::initialize(...).
5330 virtual void initialize(Attributor &A) override {
5331 // TODO: We can privatize more than arguments.
5332 indicatePessimisticFixpoint();
5333 }
5334
5335 ChangeStatus updateImpl(Attributor &A) override {
5336 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
5337 "updateImpl will not be called");
5338 }
5339
5340 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
5341 Optional<Type *> identifyPrivatizableType(Attributor &A) override {
5342 Value *Obj =
5343 GetUnderlyingObject(&getAssociatedValue(), A.getInfoCache().getDL());
5344 if (!Obj) {
5345 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
5346 return nullptr;
5347 }
5348
5349 if (auto *AI = dyn_cast<AllocaInst>(Obj))
5350 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
5351 if (CI->isOne())
5352 return Obj->getType()->getPointerElementType();
5353 if (auto *Arg = dyn_cast<Argument>(Obj)) {
5354 auto &PrivArgAA =
5355 A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(*Arg));
5356 if (PrivArgAA.isAssumedPrivatizablePtr())
5357 return Obj->getType()->getPointerElementType();
5358 }
5359
5360 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
5361 "alloca nor privatizable argument: "
5362 << *Obj << "!\n");
5363 return nullptr;
5364 }
5365
5366 /// See AbstractAttribute::trackStatistics()
5367 void trackStatistics() const override {
5368 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
5369 }
5370};
5371
5372struct AAPrivatizablePtrCallSiteArgument final
5373 : public AAPrivatizablePtrFloating {
5374 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP)
5375 : AAPrivatizablePtrFloating(IRP) {}
5376
5377 /// See AbstractAttribute::initialize(...).
5378 void initialize(Attributor &A) override {
5379 if (getIRPosition().hasAttr(Attribute::ByVal))
5380 indicateOptimisticFixpoint();
5381 }
5382
5383 /// See AbstractAttribute::updateImpl(...).
5384 ChangeStatus updateImpl(Attributor &A) override {
5385 PrivatizableType = identifyPrivatizableType(A);
5386 if (!PrivatizableType.hasValue())
5387 return ChangeStatus::UNCHANGED;
5388 if (!PrivatizableType.getValue())
5389 return indicatePessimisticFixpoint();
5390
5391 const IRPosition &IRP = getIRPosition();
5392 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
5393 if (!NoCaptureAA.isAssumedNoCapture()) {
5394 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
5395 return indicatePessimisticFixpoint();
5396 }
5397
5398 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
5399 if (!NoAliasAA.isAssumedNoAlias()) {
5400 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
5401 return indicatePessimisticFixpoint();
5402 }
5403
5404 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, IRP);
5405 if (!MemBehaviorAA.isAssumedReadOnly()) {
5406 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
5407 return indicatePessimisticFixpoint();
5408 }
5409
5410 return ChangeStatus::UNCHANGED;
5411 }
5412
5413 /// See AbstractAttribute::trackStatistics()
5414 void trackStatistics() const override {
5415 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
5416 }
5417};
5418
5419struct AAPrivatizablePtrCallSiteReturned final
5420 : public AAPrivatizablePtrFloating {
5421 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP)
5422 : AAPrivatizablePtrFloating(IRP) {}
5423
5424 /// See AbstractAttribute::initialize(...).
5425 void initialize(Attributor &A) override {
5426 // TODO: We can privatize more than arguments.
5427 indicatePessimisticFixpoint();
5428 }
5429
5430 /// See AbstractAttribute::trackStatistics()
5431 void trackStatistics() const override {
5432 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
5433 }
5434};
5435
5436struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
5437 AAPrivatizablePtrReturned(const IRPosition &IRP)
5438 : AAPrivatizablePtrFloating(IRP) {}
5439
5440 /// See AbstractAttribute::initialize(...).
5441 void initialize(Attributor &A) override {
5442 // TODO: We can privatize more than arguments.
5443 indicatePessimisticFixpoint();
5444 }
5445
5446 /// See AbstractAttribute::trackStatistics()
5447 void trackStatistics() const override {
5448 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
5449 }
5450};
5451
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005452/// -------------------- Memory Behavior Attributes ----------------------------
5453/// Includes read-none, read-only, and write-only.
5454/// ----------------------------------------------------------------------------
5455struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
5456 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
5457
5458 /// See AbstractAttribute::initialize(...).
5459 void initialize(Attributor &A) override {
5460 intersectAssumedBits(BEST_STATE);
5461 getKnownStateFromValue(getIRPosition(), getState());
5462 IRAttribute::initialize(A);
5463 }
5464
5465 /// Return the memory behavior information encoded in the IR for \p IRP.
5466 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005467 BitIntegerState &State,
5468 bool IgnoreSubsumingPositions = false) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005469 SmallVector<Attribute, 2> Attrs;
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005470 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005471 for (const Attribute &Attr : Attrs) {
5472 switch (Attr.getKindAsEnum()) {
5473 case Attribute::ReadNone:
5474 State.addKnownBits(NO_ACCESSES);
5475 break;
5476 case Attribute::ReadOnly:
5477 State.addKnownBits(NO_WRITES);
5478 break;
5479 case Attribute::WriteOnly:
5480 State.addKnownBits(NO_READS);
5481 break;
5482 default:
5483 llvm_unreachable("Unexpcted attribute!");
5484 }
5485 }
5486
5487 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
5488 if (!I->mayReadFromMemory())
5489 State.addKnownBits(NO_READS);
5490 if (!I->mayWriteToMemory())
5491 State.addKnownBits(NO_WRITES);
5492 }
5493 }
5494
5495 /// See AbstractAttribute::getDeducedAttributes(...).
5496 void getDeducedAttributes(LLVMContext &Ctx,
5497 SmallVectorImpl<Attribute> &Attrs) const override {
5498 assert(Attrs.size() == 0);
5499 if (isAssumedReadNone())
5500 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
5501 else if (isAssumedReadOnly())
5502 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
5503 else if (isAssumedWriteOnly())
5504 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
5505 assert(Attrs.size() <= 1);
5506 }
5507
5508 /// See AbstractAttribute::manifest(...).
5509 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05005510 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005511
5512 // Check if we would improve the existing attributes first.
5513 SmallVector<Attribute, 4> DeducedAttrs;
5514 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
5515 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
5516 return IRP.hasAttr(Attr.getKindAsEnum(),
5517 /* IgnoreSubsumingPositions */ true);
5518 }))
5519 return ChangeStatus::UNCHANGED;
5520
5521 // Clear existing attributes.
5522 IRP.removeAttrs(AttrKinds);
5523
5524 // Use the generic manifest method.
5525 return IRAttribute::manifest(A);
5526 }
5527
5528 /// See AbstractState::getAsStr().
5529 const std::string getAsStr() const override {
5530 if (isAssumedReadNone())
5531 return "readnone";
5532 if (isAssumedReadOnly())
5533 return "readonly";
5534 if (isAssumedWriteOnly())
5535 return "writeonly";
5536 return "may-read/write";
5537 }
5538
5539 /// The set of IR attributes AAMemoryBehavior deals with.
5540 static const Attribute::AttrKind AttrKinds[3];
5541};
5542
5543const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
5544 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
5545
5546/// Memory behavior attribute for a floating value.
5547struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
5548 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5549
5550 /// See AbstractAttribute::initialize(...).
5551 void initialize(Attributor &A) override {
5552 AAMemoryBehaviorImpl::initialize(A);
5553 // Initialize the use vector with all direct uses of the associated value.
5554 for (const Use &U : getAssociatedValue().uses())
5555 Uses.insert(&U);
5556 }
5557
5558 /// See AbstractAttribute::updateImpl(...).
5559 ChangeStatus updateImpl(Attributor &A) override;
5560
5561 /// See AbstractAttribute::trackStatistics()
5562 void trackStatistics() const override {
5563 if (isAssumedReadNone())
5564 STATS_DECLTRACK_FLOATING_ATTR(readnone)
5565 else if (isAssumedReadOnly())
5566 STATS_DECLTRACK_FLOATING_ATTR(readonly)
5567 else if (isAssumedWriteOnly())
5568 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
5569 }
5570
5571private:
5572 /// Return true if users of \p UserI might access the underlying
5573 /// variable/location described by \p U and should therefore be analyzed.
5574 bool followUsersOfUseIn(Attributor &A, const Use *U,
5575 const Instruction *UserI);
5576
5577 /// Update the state according to the effect of use \p U in \p UserI.
5578 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
5579
5580protected:
5581 /// Container for (transitive) uses of the associated argument.
5582 SetVector<const Use *> Uses;
5583};
5584
5585/// Memory behavior attribute for function argument.
5586struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
5587 AAMemoryBehaviorArgument(const IRPosition &IRP)
5588 : AAMemoryBehaviorFloating(IRP) {}
5589
5590 /// See AbstractAttribute::initialize(...).
5591 void initialize(Attributor &A) override {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005592 intersectAssumedBits(BEST_STATE);
5593 const IRPosition &IRP = getIRPosition();
5594 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
5595 // can query it when we use has/getAttr. That would allow us to reuse the
5596 // initialize of the base class here.
5597 bool HasByVal =
5598 IRP.hasAttr({Attribute::ByVal}, /* IgnoreSubsumingPositions */ true);
5599 getKnownStateFromValue(IRP, getState(),
5600 /* IgnoreSubsumingPositions */ HasByVal);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005601
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005602 // Initialize the use vector with all direct uses of the associated value.
5603 Argument *Arg = getAssociatedArgument();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005604 if (!Arg || !Arg->getParent()->hasExactDefinition()) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005605 indicatePessimisticFixpoint();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005606 } else {
5607 // Initialize the use vector with all direct uses of the associated value.
5608 for (const Use &U : Arg->uses())
5609 Uses.insert(&U);
5610 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005611 }
5612
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005613 ChangeStatus manifest(Attributor &A) override {
5614 // TODO: From readattrs.ll: "inalloca parameters are always
5615 // considered written"
5616 if (hasAttr({Attribute::InAlloca})) {
5617 removeKnownBits(NO_WRITES);
5618 removeAssumedBits(NO_WRITES);
5619 }
5620 return AAMemoryBehaviorFloating::manifest(A);
5621 }
5622
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005623 /// See AbstractAttribute::trackStatistics()
5624 void trackStatistics() const override {
5625 if (isAssumedReadNone())
5626 STATS_DECLTRACK_ARG_ATTR(readnone)
5627 else if (isAssumedReadOnly())
5628 STATS_DECLTRACK_ARG_ATTR(readonly)
5629 else if (isAssumedWriteOnly())
5630 STATS_DECLTRACK_ARG_ATTR(writeonly)
5631 }
5632};
5633
5634struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
5635 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
5636 : AAMemoryBehaviorArgument(IRP) {}
5637
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005638 /// See AbstractAttribute::initialize(...).
5639 void initialize(Attributor &A) override {
5640 if (Argument *Arg = getAssociatedArgument()) {
5641 if (Arg->hasByValAttr()) {
5642 addKnownBits(NO_WRITES);
5643 removeKnownBits(NO_READS);
5644 removeAssumedBits(NO_READS);
5645 }
5646 } else {
5647 }
5648 AAMemoryBehaviorArgument::initialize(A);
5649 }
5650
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005651 /// See AbstractAttribute::updateImpl(...).
5652 ChangeStatus updateImpl(Attributor &A) override {
5653 // TODO: Once we have call site specific value information we can provide
5654 // call site specific liveness liveness information and then it makes
5655 // sense to specialize attributes for call sites arguments instead of
5656 // redirecting requests to the callee argument.
5657 Argument *Arg = getAssociatedArgument();
5658 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5659 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
5660 return clampStateAndIndicateChange(
5661 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05005662 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005663 }
5664
5665 /// See AbstractAttribute::trackStatistics()
5666 void trackStatistics() const override {
5667 if (isAssumedReadNone())
5668 STATS_DECLTRACK_CSARG_ATTR(readnone)
5669 else if (isAssumedReadOnly())
5670 STATS_DECLTRACK_CSARG_ATTR(readonly)
5671 else if (isAssumedWriteOnly())
5672 STATS_DECLTRACK_CSARG_ATTR(writeonly)
5673 }
5674};
5675
5676/// Memory behavior attribute for a call site return position.
5677struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
5678 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
5679 : AAMemoryBehaviorFloating(IRP) {}
5680
5681 /// See AbstractAttribute::manifest(...).
5682 ChangeStatus manifest(Attributor &A) override {
5683 // We do not annotate returned values.
5684 return ChangeStatus::UNCHANGED;
5685 }
5686
5687 /// See AbstractAttribute::trackStatistics()
5688 void trackStatistics() const override {}
5689};
5690
5691/// An AA to represent the memory behavior function attributes.
5692struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
5693 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5694
5695 /// See AbstractAttribute::updateImpl(Attributor &A).
5696 virtual ChangeStatus updateImpl(Attributor &A) override;
5697
5698 /// See AbstractAttribute::manifest(...).
5699 ChangeStatus manifest(Attributor &A) override {
5700 Function &F = cast<Function>(getAnchorValue());
5701 if (isAssumedReadNone()) {
5702 F.removeFnAttr(Attribute::ArgMemOnly);
5703 F.removeFnAttr(Attribute::InaccessibleMemOnly);
5704 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
5705 }
5706 return AAMemoryBehaviorImpl::manifest(A);
5707 }
5708
5709 /// See AbstractAttribute::trackStatistics()
5710 void trackStatistics() const override {
5711 if (isAssumedReadNone())
5712 STATS_DECLTRACK_FN_ATTR(readnone)
5713 else if (isAssumedReadOnly())
5714 STATS_DECLTRACK_FN_ATTR(readonly)
5715 else if (isAssumedWriteOnly())
5716 STATS_DECLTRACK_FN_ATTR(writeonly)
5717 }
5718};
5719
5720/// AAMemoryBehavior attribute for call sites.
5721struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
5722 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5723
5724 /// See AbstractAttribute::initialize(...).
5725 void initialize(Attributor &A) override {
5726 AAMemoryBehaviorImpl::initialize(A);
5727 Function *F = getAssociatedFunction();
5728 if (!F || !F->hasExactDefinition())
5729 indicatePessimisticFixpoint();
5730 }
5731
5732 /// See AbstractAttribute::updateImpl(...).
5733 ChangeStatus updateImpl(Attributor &A) override {
5734 // TODO: Once we have call site specific value information we can provide
5735 // call site specific liveness liveness information and then it makes
5736 // sense to specialize attributes for call sites arguments instead of
5737 // redirecting requests to the callee argument.
5738 Function *F = getAssociatedFunction();
5739 const IRPosition &FnPos = IRPosition::function(*F);
5740 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
5741 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05005742 getState(),
5743 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005744 }
5745
5746 /// See AbstractAttribute::trackStatistics()
5747 void trackStatistics() const override {
5748 if (isAssumedReadNone())
5749 STATS_DECLTRACK_CS_ATTR(readnone)
5750 else if (isAssumedReadOnly())
5751 STATS_DECLTRACK_CS_ATTR(readonly)
5752 else if (isAssumedWriteOnly())
5753 STATS_DECLTRACK_CS_ATTR(writeonly)
5754 }
5755};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00005756} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005757
5758ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
5759
5760 // The current assumed state used to determine a change.
5761 auto AssumedState = getAssumed();
5762
5763 auto CheckRWInst = [&](Instruction &I) {
5764 // If the instruction has an own memory behavior state, use it to restrict
5765 // the local state. No further analysis is required as the other memory
5766 // state is as optimistic as it gets.
5767 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
5768 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
5769 *this, IRPosition::callsite_function(ICS));
5770 intersectAssumedBits(MemBehaviorAA.getAssumed());
5771 return !isAtFixpoint();
5772 }
5773
5774 // Remove access kind modifiers if necessary.
5775 if (I.mayReadFromMemory())
5776 removeAssumedBits(NO_READS);
5777 if (I.mayWriteToMemory())
5778 removeAssumedBits(NO_WRITES);
5779 return !isAtFixpoint();
5780 };
5781
5782 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
5783 return indicatePessimisticFixpoint();
5784
5785 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5786 : ChangeStatus::UNCHANGED;
5787}
5788
5789ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
5790
5791 const IRPosition &IRP = getIRPosition();
5792 const IRPosition &FnPos = IRPosition::function_scope(IRP);
5793 AAMemoryBehavior::StateType &S = getState();
5794
5795 // First, check the function scope. We take the known information and we avoid
5796 // work if the assumed information implies the current assumed information for
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005797 // this attribute. This is a valid for all but byval arguments.
5798 Argument *Arg = IRP.getAssociatedArgument();
5799 AAMemoryBehavior::base_t FnMemAssumedState =
5800 AAMemoryBehavior::StateType::getWorstState();
5801 if (!Arg || !Arg->hasByValAttr()) {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005802 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(
5803 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005804 FnMemAssumedState = FnMemAA.getAssumed();
5805 S.addKnownBits(FnMemAA.getKnown());
5806 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
5807 return ChangeStatus::UNCHANGED;
5808 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005809
5810 // Make sure the value is not captured (except through "return"), if
5811 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005812 // check the potential aliases introduced by the capture. However, no need
5813 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert28880192019-12-31 00:57:00 -06005814 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
5815 *this, IRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005816 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005817 S.intersectAssumedBits(FnMemAssumedState);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005818 return ChangeStatus::CHANGED;
5819 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005820
5821 // The current assumed state used to determine a change.
5822 auto AssumedState = S.getAssumed();
5823
5824 // Liveness information to exclude dead users.
5825 // TODO: Take the FnPos once we have call site specific liveness information.
5826 const auto &LivenessAA = A.getAAFor<AAIsDead>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005827 *this, IRPosition::function(*IRP.getAssociatedFunction()),
5828 /* TrackDependence */ false);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005829
5830 // Visit and expand uses until all are analyzed or a fixpoint is reached.
5831 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
5832 const Use *U = Uses[i];
5833 Instruction *UserI = cast<Instruction>(U->getUser());
5834 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
5835 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
5836 << "]\n");
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005837 if (LivenessAA.isAssumedDead(UserI)) {
5838 A.recordDependence(LivenessAA, *this, DepClassTy::OPTIONAL);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005839 continue;
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005840 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005841
5842 // Check if the users of UserI should also be visited.
5843 if (followUsersOfUseIn(A, U, UserI))
5844 for (const Use &UserIUse : UserI->uses())
5845 Uses.insert(&UserIUse);
5846
5847 // If UserI might touch memory we analyze the use in detail.
5848 if (UserI->mayReadOrWriteMemory())
5849 analyzeUseIn(A, U, UserI);
5850 }
5851
5852 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5853 : ChangeStatus::UNCHANGED;
5854}
5855
5856bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
5857 const Instruction *UserI) {
5858 // The loaded value is unrelated to the pointer argument, no need to
5859 // follow the users of the load.
5860 if (isa<LoadInst>(UserI))
5861 return false;
5862
5863 // By default we follow all uses assuming UserI might leak information on U,
5864 // we have special handling for call sites operands though.
5865 ImmutableCallSite ICS(UserI);
5866 if (!ICS || !ICS.isArgOperand(U))
5867 return true;
5868
5869 // If the use is a call argument known not to be captured, the users of
5870 // the call do not need to be visited because they have to be unrelated to
5871 // the input. Note that this check is not trivial even though we disallow
5872 // general capturing of the underlying argument. The reason is that the
5873 // call might the argument "through return", which we allow and for which we
5874 // need to check call users.
Johannes Doerfertff6254d2020-01-10 12:32:24 -06005875 if (U->get()->getType()->isPointerTy()) {
5876 unsigned ArgNo = ICS.getArgumentNo(U);
5877 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005878 *this, IRPosition::callsite_argument(ICS, ArgNo),
5879 /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfertff6254d2020-01-10 12:32:24 -06005880 return !ArgNoCaptureAA.isAssumedNoCapture();
5881 }
5882
5883 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005884}
5885
5886void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
5887 const Instruction *UserI) {
5888 assert(UserI->mayReadOrWriteMemory());
5889
5890 switch (UserI->getOpcode()) {
5891 default:
5892 // TODO: Handle all atomics and other side-effect operations we know of.
5893 break;
5894 case Instruction::Load:
5895 // Loads cause the NO_READS property to disappear.
5896 removeAssumedBits(NO_READS);
5897 return;
5898
5899 case Instruction::Store:
5900 // Stores cause the NO_WRITES property to disappear if the use is the
5901 // pointer operand. Note that we do assume that capturing was taken care of
5902 // somewhere else.
5903 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
5904 removeAssumedBits(NO_WRITES);
5905 return;
5906
5907 case Instruction::Call:
5908 case Instruction::CallBr:
5909 case Instruction::Invoke: {
5910 // For call sites we look at the argument memory behavior attribute (this
5911 // could be recursive!) in order to restrict our own state.
5912 ImmutableCallSite ICS(UserI);
5913
5914 // Give up on operand bundles.
5915 if (ICS.isBundleOperand(U)) {
5916 indicatePessimisticFixpoint();
5917 return;
5918 }
5919
5920 // Calling a function does read the function pointer, maybe write it if the
5921 // function is self-modifying.
5922 if (ICS.isCallee(U)) {
5923 removeAssumedBits(NO_READS);
5924 break;
5925 }
5926
5927 // Adjust the possible access behavior based on the information on the
5928 // argument.
Johannes Doerfertff6254d2020-01-10 12:32:24 -06005929 IRPosition Pos;
5930 if (U->get()->getType()->isPointerTy())
5931 Pos = IRPosition::callsite_argument(ICS, ICS.getArgumentNo(U));
5932 else
5933 Pos = IRPosition::callsite_function(ICS);
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005934 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
5935 *this, Pos,
5936 /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005937 // "assumed" has at most the same bits as the MemBehaviorAA assumed
5938 // and at least "known".
5939 intersectAssumedBits(MemBehaviorAA.getAssumed());
5940 return;
5941 }
5942 };
5943
5944 // Generally, look at the "may-properties" and adjust the assumed state if we
5945 // did not trigger special handling before.
5946 if (UserI->mayReadFromMemory())
5947 removeAssumedBits(NO_READS);
5948 if (UserI->mayWriteToMemory())
5949 removeAssumedBits(NO_WRITES);
5950}
Hideto Ueno188f9a32020-01-15 15:25:52 +09005951/// ------------------ Value Constant Range Attribute -------------------------
Hideto Uenoe9963032020-01-01 15:25:19 +09005952
Hideto Ueno188f9a32020-01-15 15:25:52 +09005953struct AAValueConstantRangeImpl : AAValueConstantRange {
5954 using StateType = IntegerRangeState;
5955 AAValueConstantRangeImpl(const IRPosition &IRP) : AAValueConstantRange(IRP) {}
5956
5957 /// See AbstractAttribute::getAsStr().
5958 const std::string getAsStr() const override {
5959 std::string Str;
5960 llvm::raw_string_ostream OS(Str);
5961 OS << "range(" << getBitWidth() << ")<";
5962 getKnown().print(OS);
5963 OS << " / ";
5964 getAssumed().print(OS);
5965 OS << ">";
5966 return OS.str();
5967 }
5968
5969 /// Helper function to get a SCEV expr for the associated value at program
5970 /// point \p I.
5971 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
5972 if (!getAnchorScope())
5973 return nullptr;
5974
5975 ScalarEvolution *SE =
5976 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
5977 *getAnchorScope());
5978
5979 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
5980 *getAnchorScope());
5981
5982 if (!SE || !LI)
5983 return nullptr;
5984
5985 const SCEV *S = SE->getSCEV(&getAssociatedValue());
5986 if (!I)
5987 return S;
5988
5989 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
5990 }
5991
5992 /// Helper function to get a range from SCEV for the associated value at
5993 /// program point \p I.
5994 ConstantRange getConstantRangeFromSCEV(Attributor &A,
5995 const Instruction *I = nullptr) const {
5996 if (!getAnchorScope())
5997 return getWorstState(getBitWidth());
5998
5999 ScalarEvolution *SE =
6000 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
6001 *getAnchorScope());
6002
6003 const SCEV *S = getSCEV(A, I);
6004 if (!SE || !S)
6005 return getWorstState(getBitWidth());
6006
6007 return SE->getUnsignedRange(S);
6008 }
6009
6010 /// Helper function to get a range from LVI for the associated value at
6011 /// program point \p I.
6012 ConstantRange
6013 getConstantRangeFromLVI(Attributor &A,
6014 const Instruction *CtxI = nullptr) const {
6015 if (!getAnchorScope())
6016 return getWorstState(getBitWidth());
6017
6018 LazyValueInfo *LVI =
6019 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
6020 *getAnchorScope());
6021
6022 if (!LVI || !CtxI)
6023 return getWorstState(getBitWidth());
6024 return LVI->getConstantRange(&getAssociatedValue(),
6025 const_cast<BasicBlock *>(CtxI->getParent()),
6026 const_cast<Instruction *>(CtxI));
6027 }
6028
6029 /// See AAValueConstantRange::getKnownConstantRange(..).
6030 ConstantRange
6031 getKnownConstantRange(Attributor &A,
6032 const Instruction *CtxI = nullptr) const override {
6033 if (!CtxI || CtxI == getCtxI())
6034 return getKnown();
6035
6036 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
6037 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
6038 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
6039 }
6040
6041 /// See AAValueConstantRange::getAssumedConstantRange(..).
6042 ConstantRange
6043 getAssumedConstantRange(Attributor &A,
6044 const Instruction *CtxI = nullptr) const override {
6045 // TODO: Make SCEV use Attributor assumption.
6046 // We may be able to bound a variable range via assumptions in
6047 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
6048 // evolve to x^2 + x, then we can say that y is in [2, 12].
6049
6050 if (!CtxI || CtxI == getCtxI())
6051 return getAssumed();
6052
6053 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
6054 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
6055 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
6056 }
6057
6058 /// See AbstractAttribute::initialize(..).
6059 void initialize(Attributor &A) override {
6060 // Intersect a range given by SCEV.
6061 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
6062
6063 // Intersect a range given by LVI.
6064 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
6065 }
6066
6067 /// Helper function to create MDNode for range metadata.
6068 static MDNode *
6069 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
6070 const ConstantRange &AssumedConstantRange) {
6071 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
6072 Ty, AssumedConstantRange.getLower())),
6073 ConstantAsMetadata::get(ConstantInt::get(
6074 Ty, AssumedConstantRange.getUpper()))};
6075 return MDNode::get(Ctx, LowAndHigh);
6076 }
6077
6078 /// Return true if \p Assumed is included in \p KnownRanges.
6079 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) {
6080
6081 if (Assumed.isFullSet())
6082 return false;
6083
6084 if (!KnownRanges)
6085 return true;
6086
6087 // If multiple ranges are annotated in IR, we give up to annotate assumed
6088 // range for now.
6089
6090 // TODO: If there exists a known range which containts assumed range, we
6091 // can say assumed range is better.
6092 if (KnownRanges->getNumOperands() > 2)
6093 return false;
6094
6095 ConstantInt *Lower =
6096 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
6097 ConstantInt *Upper =
6098 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
6099
6100 ConstantRange Known(Lower->getValue(), Upper->getValue());
6101 return Known.contains(Assumed) && Known != Assumed;
6102 }
6103
6104 /// Helper function to set range metadata.
6105 static bool
6106 setRangeMetadataIfisBetterRange(Instruction *I,
6107 const ConstantRange &AssumedConstantRange) {
6108 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range);
6109 if (isBetterRange(AssumedConstantRange, OldRangeMD)) {
6110 if (!AssumedConstantRange.isEmptySet()) {
6111 I->setMetadata(LLVMContext::MD_range,
6112 getMDNodeForConstantRange(I->getType(), I->getContext(),
6113 AssumedConstantRange));
6114 return true;
6115 }
6116 }
6117 return false;
6118 }
6119
6120 /// See AbstractAttribute::manifest()
6121 ChangeStatus manifest(Attributor &A) override {
6122 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6123 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
6124 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
6125
6126 auto &V = getAssociatedValue();
6127 if (!AssumedConstantRange.isEmptySet() &&
6128 !AssumedConstantRange.isSingleElement()) {
6129 if (Instruction *I = dyn_cast<Instruction>(&V))
6130 if (isa<CallInst>(I) || isa<LoadInst>(I))
6131 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
6132 Changed = ChangeStatus::CHANGED;
6133 }
6134
6135 return Changed;
6136 }
6137};
6138
Johannes Doerfertea5fabe2020-01-28 09:46:15 -06006139struct AAValueConstantRangeArgument final
6140 : AAArgumentFromCallSiteArguments<
6141 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState> {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006142 AAValueConstantRangeArgument(const IRPosition &IRP)
Johannes Doerfertea5fabe2020-01-28 09:46:15 -06006143 : AAArgumentFromCallSiteArguments<
6144 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState>(
6145 IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006146
6147 /// See AbstractAttribute::trackStatistics()
6148 void trackStatistics() const override {
6149 STATS_DECLTRACK_ARG_ATTR(value_range)
6150 }
6151};
6152
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006153struct AAValueConstantRangeReturned
6154 : AAReturnedFromReturnedValues<AAValueConstantRange,
6155 AAValueConstantRangeImpl> {
6156 using Base = AAReturnedFromReturnedValues<AAValueConstantRange,
6157 AAValueConstantRangeImpl>;
6158 AAValueConstantRangeReturned(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006159
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006160 /// See AbstractAttribute::initialize(...).
6161 void initialize(Attributor &A) override {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006162
6163 /// See AbstractAttribute::trackStatistics()
6164 void trackStatistics() const override {
6165 STATS_DECLTRACK_FNRET_ATTR(value_range)
6166 }
6167};
6168
6169struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
6170 AAValueConstantRangeFloating(const IRPosition &IRP)
6171 : AAValueConstantRangeImpl(IRP) {}
6172
6173 /// See AbstractAttribute::initialize(...).
6174 void initialize(Attributor &A) override {
Johannes Doerfert028db8c42020-02-09 19:05:15 -06006175 AAValueConstantRangeImpl::initialize(A);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006176 Value &V = getAssociatedValue();
6177
6178 if (auto *C = dyn_cast<ConstantInt>(&V)) {
6179 unionAssumed(ConstantRange(C->getValue()));
6180 indicateOptimisticFixpoint();
6181 return;
6182 }
6183
6184 if (isa<UndefValue>(&V)) {
6185 indicateOptimisticFixpoint();
6186 return;
6187 }
6188
6189 if (auto *I = dyn_cast<Instruction>(&V))
6190 if (isa<BinaryOperator>(I) || isa<CmpInst>(I)) {
6191 Value *LHS = I->getOperand(0);
6192 Value *RHS = I->getOperand(1);
6193
6194 if (LHS->getType()->isIntegerTy() && RHS->getType()->isIntegerTy())
6195 return;
6196 }
6197
6198 // If it is a load instruction with range metadata, use it.
6199 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
6200 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
6201 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
6202 return;
6203 }
6204
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006205 // We handle casts in the updateImpl.
6206 // TODO: Allow non integers as well.
6207 if (CastInst *CI = dyn_cast<CastInst>(&V))
6208 if (CI->getOperand(0)->getType()->isIntegerTy())
6209 return;
6210
Johannes Doerfert81554392020-02-09 20:14:35 -06006211 // We can work with PHI and select instruction as we traverse their operands
Johannes Doerfert7e7e6592020-02-09 19:08:04 -06006212 // during update.
Johannes Doerfert81554392020-02-09 20:14:35 -06006213 if (isa<SelectInst>(V) || isa<PHINode>(V))
Johannes Doerfert7e7e6592020-02-09 19:08:04 -06006214 return;
6215
Hideto Ueno188f9a32020-01-15 15:25:52 +09006216 // Otherwise we give up.
6217 indicatePessimisticFixpoint();
6218
Johannes Doerfert02bd8182020-01-28 11:49:35 -06006219 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
6220 << getAssociatedValue() << "\n");
Hideto Ueno188f9a32020-01-15 15:25:52 +09006221 }
6222
Johannes Doerfert81554392020-02-09 20:14:35 -06006223 bool calculateBinaryOperator(
6224 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
6225 Instruction *CtxI,
6226 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006227 Value *LHS = BinOp->getOperand(0);
6228 Value *RHS = BinOp->getOperand(1);
6229
6230 auto &LHSAA =
6231 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006232 QuerriedAAs.push_back(&LHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006233 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
6234
6235 auto &RHSAA =
6236 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006237 QuerriedAAs.push_back(&RHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006238 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
6239
6240 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
6241
6242 T.unionAssumed(AssumedRange);
6243
6244 // TODO: Track a known state too.
6245
6246 return T.isValidState();
6247 }
6248
Johannes Doerfert81554392020-02-09 20:14:35 -06006249 bool calculateCastInst(
6250 Attributor &A, CastInst *CastI, IntegerRangeState &T, Instruction *CtxI,
6251 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006252 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
6253 // TODO: Allow non integers as well.
6254 Value &OpV = *CastI->getOperand(0);
6255 assert(OpV.getType()->isIntegerTy() && "Expected integer cast");
6256
6257 auto &OpAA =
6258 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV));
Johannes Doerfert81554392020-02-09 20:14:35 -06006259 QuerriedAAs.push_back(&OpAA);
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006260 T.unionAssumed(
6261 OpAA.getAssumed().castOp(CastI->getOpcode(), getState().getBitWidth()));
6262 return T.isValidState();
6263 }
6264
Johannes Doerfert81554392020-02-09 20:14:35 -06006265 bool
6266 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
6267 Instruction *CtxI,
6268 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006269 Value *LHS = CmpI->getOperand(0);
6270 Value *RHS = CmpI->getOperand(1);
6271
6272 auto &LHSAA =
6273 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006274 QuerriedAAs.push_back(&LHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006275 auto &RHSAA =
6276 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006277 QuerriedAAs.push_back(&RHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006278
6279 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
6280 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
6281
6282 // If one of them is empty set, we can't decide.
6283 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
6284 return true;
6285
6286 bool MustTrue = false, MustFalse = false;
6287
6288 auto AllowedRegion =
6289 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange);
6290
6291 auto SatisfyingRegion = ConstantRange::makeSatisfyingICmpRegion(
6292 CmpI->getPredicate(), RHSAARange);
6293
6294 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
6295 MustFalse = true;
6296
6297 if (SatisfyingRegion.contains(LHSAARange))
6298 MustTrue = true;
6299
6300 assert((!MustTrue || !MustFalse) &&
6301 "Either MustTrue or MustFalse should be false!");
6302
6303 if (MustTrue)
6304 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
6305 else if (MustFalse)
6306 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
6307 else
6308 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
6309
6310 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " " << LHSAA
6311 << " " << RHSAA << "\n");
6312
6313 // TODO: Track a known state too.
6314 return T.isValidState();
6315 }
6316
6317 /// See AbstractAttribute::updateImpl(...).
6318 ChangeStatus updateImpl(Attributor &A) override {
6319 Instruction *CtxI = getCtxI();
6320 auto VisitValueCB = [&](Value &V, IntegerRangeState &T,
6321 bool Stripped) -> bool {
6322 Instruction *I = dyn_cast<Instruction>(&V);
6323 if (!I) {
6324
6325 // If the value is not instruction, we query AA to Attributor.
6326 const auto &AA =
6327 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(V));
6328
6329 // Clamp operator is not used to utilize a program point CtxI.
6330 T.unionAssumed(AA.getAssumedConstantRange(A, CtxI));
6331
6332 return T.isValidState();
6333 }
6334
Johannes Doerfert81554392020-02-09 20:14:35 -06006335 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs;
6336 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
6337 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
6338 return false;
6339 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
6340 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
6341 return false;
6342 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
6343 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
6344 return false;
6345 } else {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006346 // Give up with other instructions.
6347 // TODO: Add other instructions
6348
6349 T.indicatePessimisticFixpoint();
6350 return false;
6351 }
Johannes Doerfert81554392020-02-09 20:14:35 -06006352
6353 // Catch circular reasoning in a pessimistic way for now.
6354 // TODO: Check how the range evolves and if we stripped anything, see also
6355 // AADereferenceable or AAAlign for similar situations.
6356 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
6357 if (QueriedAA != this)
6358 continue;
6359 // If we are in a stady state we do not need to worry.
6360 if (T.getAssumed() == getState().getAssumed())
6361 continue;
6362 T.indicatePessimisticFixpoint();
6363 }
6364
6365 return T.isValidState();
Hideto Ueno188f9a32020-01-15 15:25:52 +09006366 };
6367
6368 IntegerRangeState T(getBitWidth());
6369
6370 if (!genericValueTraversal<AAValueConstantRange, IntegerRangeState>(
6371 A, getIRPosition(), *this, T, VisitValueCB))
6372 return indicatePessimisticFixpoint();
6373
6374 return clampStateAndIndicateChange(getState(), T);
6375 }
6376
6377 /// See AbstractAttribute::trackStatistics()
6378 void trackStatistics() const override {
6379 STATS_DECLTRACK_FLOATING_ATTR(value_range)
6380 }
6381};
6382
6383struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
6384 AAValueConstantRangeFunction(const IRPosition &IRP)
6385 : AAValueConstantRangeImpl(IRP) {}
6386
6387 /// See AbstractAttribute::initialize(...).
6388 ChangeStatus updateImpl(Attributor &A) override {
6389 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
6390 "not be called");
6391 }
6392
6393 /// See AbstractAttribute::trackStatistics()
6394 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
6395};
6396
6397struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
6398 AAValueConstantRangeCallSite(const IRPosition &IRP)
6399 : AAValueConstantRangeFunction(IRP) {}
6400
6401 /// See AbstractAttribute::trackStatistics()
6402 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
6403};
6404
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006405struct AAValueConstantRangeCallSiteReturned
6406 : AACallSiteReturnedFromReturned<AAValueConstantRange,
6407 AAValueConstantRangeImpl> {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006408 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP)
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006409 : AACallSiteReturnedFromReturned<AAValueConstantRange,
6410 AAValueConstantRangeImpl>(IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006411
6412 /// See AbstractAttribute::initialize(...).
6413 void initialize(Attributor &A) override {
6414 // If it is a load instruction with range metadata, use the metadata.
6415 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue()))
6416 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range))
6417 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
6418
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006419 AAValueConstantRangeImpl::initialize(A);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006420 }
6421
6422 /// See AbstractAttribute::trackStatistics()
6423 void trackStatistics() const override {
6424 STATS_DECLTRACK_CSRET_ATTR(value_range)
6425 }
6426};
6427struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
6428 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP)
6429 : AAValueConstantRangeFloating(IRP) {}
6430
6431 /// See AbstractAttribute::trackStatistics()
6432 void trackStatistics() const override {
6433 STATS_DECLTRACK_CSARG_ATTR(value_range)
6434 }
6435};
Johannes Doerfertaade7822019-06-05 03:02:24 +00006436/// ----------------------------------------------------------------------------
6437/// Attributor
6438/// ----------------------------------------------------------------------------
6439
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006440bool Attributor::isAssumedDead(const AbstractAttribute &AA,
6441 const AAIsDead *LivenessAA) {
6442 const Instruction *CtxI = AA.getIRPosition().getCtxI();
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006443 if (!CtxI || !Functions.count(const_cast<Function *>(CtxI->getFunction())))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006444 return false;
6445
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006446 // TODO: Find a good way to utilize fine and coarse grained liveness
6447 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006448 if (!LivenessAA)
6449 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00006450 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
6451 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00006452
6453 // Don't check liveness for AAIsDead.
6454 if (&AA == LivenessAA)
6455 return false;
6456
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006457 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006458 return false;
6459
Johannes Doerfert19b00432019-08-26 17:48:05 +00006460 // We actually used liveness information so we have to record a dependence.
Johannes Doerfert680f6382019-11-02 02:48:05 -05006461 recordDependence(*LivenessAA, AA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006462
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006463 return true;
6464}
6465
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006466bool Attributor::checkForAllUses(
6467 const function_ref<bool(const Use &, bool &)> &Pred,
6468 const AbstractAttribute &QueryingAA, const Value &V) {
6469 const IRPosition &IRP = QueryingAA.getIRPosition();
6470 SmallVector<const Use *, 16> Worklist;
6471 SmallPtrSet<const Use *, 16> Visited;
6472
6473 for (const Use &U : V.uses())
6474 Worklist.push_back(&U);
6475
6476 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
6477 << " initial uses to check\n");
6478
6479 if (Worklist.empty())
6480 return true;
6481
6482 bool AnyDead = false;
6483 const Function *ScopeFn = IRP.getAnchorScope();
6484 const auto *LivenessAA =
6485 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
6486 /* TrackDependence */ false)
6487 : nullptr;
6488
6489 while (!Worklist.empty()) {
6490 const Use *U = Worklist.pop_back_val();
6491 if (!Visited.insert(U).second)
6492 continue;
Johannes Doerfert8e629682020-02-11 00:10:35 -06006493 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << " [" << LivenessAA
6494 << "]\n");
6495 if (LivenessAA) {
6496 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
6497 if (LivenessAA->isAssumedDead(UserI)) {
6498 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
6499 << *LivenessAA << "\n");
6500 AnyDead = true;
6501 continue;
6502 }
6503 if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
6504 BasicBlock *IncomingBB = PHI->getIncomingBlock(*U);
6505 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
6506 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
6507 << *LivenessAA << "\n");
6508 AnyDead = true;
6509 continue;
6510 }
6511 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006512 }
Johannes Doerfert8e629682020-02-11 00:10:35 -06006513 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006514
6515 bool Follow = false;
6516 if (!Pred(*U, Follow))
6517 return false;
6518 if (!Follow)
6519 continue;
6520 for (const Use &UU : U->getUser()->uses())
6521 Worklist.push_back(&UU);
6522 }
6523
6524 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05006525 recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006526
6527 return true;
6528}
6529
Johannes Doerfert661db042019-10-07 23:14:58 +00006530bool Attributor::checkForAllCallSites(
6531 const function_ref<bool(AbstractCallSite)> &Pred,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006532 const AbstractAttribute &QueryingAA, bool RequireAllCallSites,
6533 bool &AllCallSitesKnown) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006534 // We can try to determine information from
6535 // the call sites. However, this is only possible all call sites are known,
6536 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006537 const IRPosition &IRP = QueryingAA.getIRPosition();
6538 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00006539 if (!AssociatedFunction) {
6540 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
6541 << "\n");
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006542 AllCallSitesKnown = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006543 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00006544 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006545
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006546 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006547 &QueryingAA, AllCallSitesKnown);
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006548}
6549
6550bool Attributor::checkForAllCallSites(
6551 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006552 bool RequireAllCallSites, const AbstractAttribute *QueryingAA,
6553 bool &AllCallSitesKnown) {
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006554 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006555 LLVM_DEBUG(
6556 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006557 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00006558 << " has no internal linkage, hence not all call sites are known\n");
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006559 AllCallSitesKnown = false;
Hideto Ueno54869ec2019-07-15 06:49:04 +00006560 return false;
6561 }
6562
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006563 // If we do not require all call sites we might not see all.
6564 AllCallSitesKnown = RequireAllCallSites;
6565
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006566 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00006567 AbstractCallSite ACS(&U);
6568 if (!ACS) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006569 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00006570 << " has non call site use " << *U.get() << " in "
6571 << *U.getUser() << "\n");
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05006572 // BlockAddress users are allowed.
6573 if (isa<BlockAddress>(U.getUser()))
6574 continue;
Johannes Doerfertd98f9752019-08-21 21:48:56 +00006575 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00006576 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00006577
Johannes Doerfert661db042019-10-07 23:14:58 +00006578 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006579 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00006580
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006581 const auto *LivenessAA =
6582 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006583 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00006584
6585 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006586 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00006587 // We actually used liveness information so we have to record a
6588 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006589 if (QueryingAA)
Johannes Doerfert680f6382019-11-02 02:48:05 -05006590 recordDependence(*LivenessAA, *QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006591 AllCallSitesKnown = false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00006592 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00006593 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00006594
Johannes Doerfert661db042019-10-07 23:14:58 +00006595 const Use *EffectiveUse =
6596 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
6597 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006598 if (!RequireAllCallSites)
6599 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00006600 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006601 << " is an invalid use of " << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00006602 return false;
6603 }
6604
Johannes Doerfert661db042019-10-07 23:14:58 +00006605 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00006606 continue;
6607
Johannes Doerfert5304b722019-08-14 22:04:28 +00006608 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00006609 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00006610 return false;
6611 }
6612
6613 return true;
6614}
6615
Johannes Doerfert14a04932019-08-07 22:27:24 +00006616bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00006617 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00006618 &Pred,
6619 const AbstractAttribute &QueryingAA) {
6620
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006621 const IRPosition &IRP = QueryingAA.getIRPosition();
6622 // Since we need to provide return instructions we have to have an exact
6623 // definition.
6624 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006625 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00006626 return false;
6627
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006628 // If this is a call site query we use the call site specific return values
6629 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00006630 // TODO: use the function scope once we have call site AAReturnedValues.
6631 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006632 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006633 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006634 return false;
6635
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006636 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00006637}
6638
6639bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006640 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00006641 const AbstractAttribute &QueryingAA) {
6642
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006643 const IRPosition &IRP = QueryingAA.getIRPosition();
6644 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006645 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00006646 return false;
6647
Johannes Doerfert07a5c122019-08-28 14:09:14 +00006648 // TODO: use the function scope once we have call site AAReturnedValues.
6649 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006650 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006651 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006652 return false;
6653
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006654 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00006655 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00006656 return Pred(RV);
6657 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00006658}
6659
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006660static bool
6661checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
6662 const function_ref<bool(Instruction &)> &Pred,
6663 const AAIsDead *LivenessAA, bool &AnyDead,
6664 const ArrayRef<unsigned> &Opcodes) {
6665 for (unsigned Opcode : Opcodes) {
6666 for (Instruction *I : OpcodeInstMap[Opcode]) {
6667 // Skip dead instructions.
6668 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
6669 AnyDead = true;
6670 continue;
6671 }
6672
6673 if (!Pred(*I))
6674 return false;
6675 }
6676 }
6677 return true;
6678}
6679
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006680bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006681 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00006682 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006683
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006684 const IRPosition &IRP = QueryingAA.getIRPosition();
6685 // Since we need to provide instructions we have to have an exact definition.
6686 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006687 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006688 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006689
Johannes Doerfert07a5c122019-08-28 14:09:14 +00006690 // TODO: use the function scope once we have call site AAReturnedValues.
6691 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006692 const auto &LivenessAA =
6693 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
6694 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006695
6696 auto &OpcodeInstMap =
6697 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006698 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
6699 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006700 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006701
Johannes Doerfert19b00432019-08-26 17:48:05 +00006702 // If we actually used liveness information so we have to record a dependence.
6703 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05006704 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006705
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006706 return true;
6707}
6708
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006709bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006710 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00006711 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006712
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006713 const Function *AssociatedFunction =
6714 QueryingAA.getIRPosition().getAssociatedFunction();
6715 if (!AssociatedFunction)
6716 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006717
Johannes Doerfert07a5c122019-08-28 14:09:14 +00006718 // TODO: use the function scope once we have call site AAReturnedValues.
6719 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
6720 const auto &LivenessAA =
6721 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006722 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006723
6724 for (Instruction *I :
6725 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006726 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00006727 if (LivenessAA.isAssumedDead(I)) {
6728 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006729 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00006730 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006731
6732 if (!Pred(*I))
6733 return false;
6734 }
6735
Johannes Doerfert19b00432019-08-26 17:48:05 +00006736 // If we actually used liveness information so we have to record a dependence.
6737 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05006738 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006739
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006740 return true;
6741}
6742
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006743ChangeStatus Attributor::run() {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006744 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
6745 << AllAbstractAttributes.size()
6746 << " abstract attributes.\n");
6747
Stefan Stipanovic53605892019-06-27 11:27:54 +00006748 // Now that all abstract attributes are collected and initialized we start
6749 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00006750
6751 unsigned IterationCounter = 1;
6752
6753 SmallVector<AbstractAttribute *, 64> ChangedAAs;
Johannes Doerfert680f6382019-11-02 02:48:05 -05006754 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006755 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
6756
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006757 bool RecomputeDependences = false;
6758
Johannes Doerfertaade7822019-06-05 03:02:24 +00006759 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006760 // Remember the size to determine new attributes.
6761 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00006762 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
6763 << ", Worklist size: " << Worklist.size() << "\n");
6764
Johannes Doerfert680f6382019-11-02 02:48:05 -05006765 // For invalid AAs we can fix dependent AAs that have a required dependence,
6766 // thereby folding long dependence chains in a single step without the need
6767 // to run updates.
6768 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
6769 AbstractAttribute *InvalidAA = InvalidAAs[u];
6770 auto &QuerriedAAs = QueryMap[InvalidAA];
6771 LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
6772 << QuerriedAAs.RequiredAAs.size() << "/"
6773 << QuerriedAAs.OptionalAAs.size()
6774 << " required/optional dependences\n");
6775 for (AbstractAttribute *DepOnInvalidAA : QuerriedAAs.RequiredAAs) {
6776 AbstractState &DOIAAState = DepOnInvalidAA->getState();
6777 DOIAAState.indicatePessimisticFixpoint();
6778 ++NumAttributesFixedDueToRequiredDependences;
6779 assert(DOIAAState.isAtFixpoint() && "Expected fixpoint state!");
6780 if (!DOIAAState.isValidState())
6781 InvalidAAs.insert(DepOnInvalidAA);
Johannes Doerfert22408542020-01-28 09:38:07 -06006782 else
6783 ChangedAAs.push_back(DepOnInvalidAA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05006784 }
6785 if (!RecomputeDependences)
6786 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
6787 QuerriedAAs.OptionalAAs.end());
6788 }
6789
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006790 // If dependences (=QueryMap) are recomputed we have to look at all abstract
6791 // attributes again, regardless of what changed in the last iteration.
6792 if (RecomputeDependences) {
6793 LLVM_DEBUG(
6794 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
6795 QueryMap.clear();
6796 ChangedAAs.clear();
6797 Worklist.insert(AllAbstractAttributes.begin(),
6798 AllAbstractAttributes.end());
6799 }
6800
Johannes Doerfertaade7822019-06-05 03:02:24 +00006801 // Add all abstract attributes that are potentially dependent on one that
6802 // changed to the work list.
6803 for (AbstractAttribute *ChangedAA : ChangedAAs) {
6804 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05006805 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
6806 QuerriedAAs.OptionalAAs.end());
6807 Worklist.insert(QuerriedAAs.RequiredAAs.begin(),
6808 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00006809 }
6810
Johannes Doerfertb504eb82019-08-26 18:55:47 +00006811 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
6812 << ", Worklist+Dependent size: " << Worklist.size()
6813 << "\n");
6814
Johannes Doerfert680f6382019-11-02 02:48:05 -05006815 // Reset the changed and invalid set.
Johannes Doerfertaade7822019-06-05 03:02:24 +00006816 ChangedAAs.clear();
Johannes Doerfert680f6382019-11-02 02:48:05 -05006817 InvalidAAs.clear();
Johannes Doerfertaade7822019-06-05 03:02:24 +00006818
6819 // Update all abstract attribute in the work list and record the ones that
6820 // changed.
6821 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006822 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
6823 QueriedNonFixAA = false;
6824 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006825 ChangedAAs.push_back(AA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05006826 if (!AA->getState().isValidState())
6827 InvalidAAs.insert(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006828 } else if (!QueriedNonFixAA) {
6829 // If the attribute did not query any non-fix information, the state
6830 // will not change and we can indicate that right away.
6831 AA->getState().indicateOptimisticFixpoint();
6832 }
6833 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00006834
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006835 // Check if we recompute the dependences in the next iteration.
6836 RecomputeDependences = (DepRecomputeInterval > 0 &&
6837 IterationCounter % DepRecomputeInterval == 0);
6838
Johannes Doerfert9543f142019-08-23 15:24:57 +00006839 // Add attributes to the changed set if they have been created in the last
6840 // iteration.
6841 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
6842 AllAbstractAttributes.end());
6843
Johannes Doerfertaade7822019-06-05 03:02:24 +00006844 // Reset the work list and repopulate with the changed abstract attributes.
6845 // Note that dependent ones are added above.
6846 Worklist.clear();
6847 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
6848
Johannes Doerfertbf112132019-08-29 01:29:44 +00006849 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
6850 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006851
Johannes Doerfertaade7822019-06-05 03:02:24 +00006852 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
6853 << IterationCounter << "/" << MaxFixpointIterations
6854 << " iterations\n");
6855
Johannes Doerfertbf112132019-08-29 01:29:44 +00006856 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00006857
Johannes Doerfertaade7822019-06-05 03:02:24 +00006858 // Reset abstract arguments not settled in a sound fixpoint by now. This
6859 // happens when we stopped the fixpoint iteration early. Note that only the
6860 // ones marked as "changed" *and* the ones transitively depending on them
6861 // need to be reverted to a pessimistic state. Others might not be in a
6862 // fixpoint state but we can use the optimistic results for them anyway.
6863 SmallPtrSet<AbstractAttribute *, 32> Visited;
6864 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
6865 AbstractAttribute *ChangedAA = ChangedAAs[u];
6866 if (!Visited.insert(ChangedAA).second)
6867 continue;
6868
6869 AbstractState &State = ChangedAA->getState();
6870 if (!State.isAtFixpoint()) {
6871 State.indicatePessimisticFixpoint();
6872
6873 NumAttributesTimedOut++;
6874 }
6875
6876 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05006877 ChangedAAs.append(QuerriedAAs.OptionalAAs.begin(),
6878 QuerriedAAs.OptionalAAs.end());
6879 ChangedAAs.append(QuerriedAAs.RequiredAAs.begin(),
6880 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00006881 }
6882
6883 LLVM_DEBUG({
6884 if (!Visited.empty())
6885 dbgs() << "\n[Attributor] Finalized " << Visited.size()
6886 << " abstract attributes.\n";
6887 });
6888
6889 unsigned NumManifested = 0;
6890 unsigned NumAtFixpoint = 0;
6891 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
6892 for (AbstractAttribute *AA : AllAbstractAttributes) {
6893 AbstractState &State = AA->getState();
6894
6895 // If there is not already a fixpoint reached, we can now take the
6896 // optimistic state. This is correct because we enforced a pessimistic one
6897 // on abstract attributes that were transitively dependent on a changed one
6898 // already above.
6899 if (!State.isAtFixpoint())
6900 State.indicateOptimisticFixpoint();
6901
6902 // If the state is invalid, we do not try to manifest it.
6903 if (!State.isValidState())
6904 continue;
6905
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006906 // Skip dead code.
6907 if (isAssumedDead(*AA, nullptr))
6908 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006909 // Manifest the state and record if we changed the IR.
6910 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00006911 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
6912 AA->trackStatistics();
6913
Johannes Doerfertaade7822019-06-05 03:02:24 +00006914 ManifestChange = ManifestChange | LocalChange;
6915
6916 NumAtFixpoint++;
6917 NumManifested += (LocalChange == ChangeStatus::CHANGED);
6918 }
6919
6920 (void)NumManifested;
6921 (void)NumAtFixpoint;
6922 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
6923 << " arguments while " << NumAtFixpoint
6924 << " were in a valid fixpoint state\n");
6925
Johannes Doerfertaade7822019-06-05 03:02:24 +00006926 NumAttributesManifested += NumManifested;
6927 NumAttributesValidFixpoint += NumAtFixpoint;
6928
Fangrui Songf1826172019-08-20 07:21:43 +00006929 (void)NumFinalAAs;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006930 assert(NumFinalAAs == AllAbstractAttributes.size() &&
6931 "Expected the final number of abstract attributes to remain "
6932 "unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00006933
6934 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00006935 {
6936 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
6937 << ToBeDeletedFunctions.size() << " functions and "
6938 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006939 << ToBeDeletedInsts.size() << " instructions and "
6940 << ToBeChangedUses.size() << " uses\n");
6941
Alina Sbirlea9e66c4e2020-01-23 14:21:08 -08006942 SmallVector<WeakTrackingVH, 32> DeadInsts;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006943 SmallVector<Instruction *, 32> TerminatorsToFold;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006944
6945 for (auto &It : ToBeChangedUses) {
6946 Use *U = It.first;
6947 Value *NewV = It.second;
6948 Value *OldV = U->get();
6949 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
6950 << " instead of " << *OldV << "\n");
6951 U->set(NewV);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006952 if (Instruction *I = dyn_cast<Instruction>(OldV)) {
6953 CGModifiedFunctions.insert(I->getFunction());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006954 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006955 isInstructionTriviallyDead(I))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006956 DeadInsts.push_back(I);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006957 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006958 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
6959 Instruction *UserI = cast<Instruction>(U->getUser());
6960 if (isa<UndefValue>(NewV)) {
Hideto Uenocb5eb132019-12-27 02:39:37 +09006961 ToBeChangedToUnreachableInsts.insert(UserI);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006962 } else {
6963 TerminatorsToFold.push_back(UserI);
6964 }
6965 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00006966 }
Johannes Doerferta4088c72020-01-07 16:01:57 -06006967 for (auto &V : InvokeWithDeadSuccessor)
6968 if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
6969 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
6970 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
6971 bool Invoke2CallAllowed =
6972 !AAIsDeadFunction::mayCatchAsynchronousExceptions(
6973 *II->getFunction());
6974 assert((UnwindBBIsDead || NormalBBIsDead) &&
6975 "Invoke does not have dead successors!");
6976 BasicBlock *BB = II->getParent();
6977 BasicBlock *NormalDestBB = II->getNormalDest();
6978 if (UnwindBBIsDead) {
6979 Instruction *NormalNextIP = &NormalDestBB->front();
6980 if (Invoke2CallAllowed) {
6981 changeToCall(II);
6982 NormalNextIP = BB->getTerminator();
6983 }
6984 if (NormalBBIsDead)
6985 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
6986 } else {
6987 assert(NormalBBIsDead && "Broken invariant!");
6988 if (!NormalDestBB->getUniquePredecessor())
6989 NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
6990 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
6991 }
6992 }
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06006993 for (auto &V : ToBeChangedToUnreachableInsts)
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006994 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
6995 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06006996 changeToUnreachable(I, /* UseLLVMTrap */ false);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006997 }
6998 for (Instruction *I : TerminatorsToFold) {
6999 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007000 ConstantFoldTerminator(I->getParent());
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007001 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007002
Johannes Doerfert5429c822020-01-11 23:30:36 -06007003 for (auto &V : ToBeDeletedInsts) {
7004 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007005 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfert5429c822020-01-11 23:30:36 -06007006 I->replaceAllUsesWith(UndefValue::get(I->getType()));
7007 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
7008 DeadInsts.push_back(I);
7009 else
7010 I->eraseFromParent();
7011 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007012 }
7013
7014 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00007015
Johannes Doerfert2f622062019-09-04 16:35:20 +00007016 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
7017 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
7018 ToBeDeletedBBs.reserve(NumDeadBlocks);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007019 for (BasicBlock *BB : ToBeDeletedBlocks) {
7020 CGModifiedFunctions.insert(BB->getParent());
7021 ToBeDeletedBBs.push_back(BB);
7022 }
Johannes Doerfert5e442a52019-10-30 17:34:59 -05007023 // Actually we do not delete the blocks but squash them into a single
7024 // unreachable but untangling branches that jump here is something we need
7025 // to do in a more generic way.
7026 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
7027 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
7028 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00007029 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00007030
Johannes Doerfert2f622062019-09-04 16:35:20 +00007031 // Identify dead internal functions and delete them. This happens outside
7032 // the other fixpoint analysis as we might treat potentially dead functions
7033 // as live to lower the number of iterations. If they happen to be dead, the
7034 // below fixpoint loop will identify and eliminate them.
7035 SmallVector<Function *, 8> InternalFns;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007036 for (Function *F : Functions)
7037 if (F->hasLocalLinkage())
7038 InternalFns.push_back(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00007039
7040 bool FoundDeadFn = true;
7041 while (FoundDeadFn) {
7042 FoundDeadFn = false;
7043 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
7044 Function *F = InternalFns[u];
7045 if (!F)
7046 continue;
7047
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007048 bool AllCallSitesKnown;
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06007049 if (!checkForAllCallSites(
7050 [this](AbstractCallSite ACS) {
7051 return ToBeDeletedFunctions.count(
7052 ACS.getInstruction()->getFunction());
7053 },
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007054 *F, true, nullptr, AllCallSitesKnown))
Johannes Doerfert2f622062019-09-04 16:35:20 +00007055 continue;
7056
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007057 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00007058 InternalFns[u] = nullptr;
7059 FoundDeadFn = true;
7060 }
7061 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00007062 }
7063
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007064 // Rewrite the functions as requested during manifest.
7065 ManifestChange =
7066 ManifestChange | rewriteFunctionSignatures(CGModifiedFunctions);
7067
7068 for (Function *Fn : CGModifiedFunctions)
7069 CGUpdater.reanalyzeFunction(*Fn);
7070
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007071 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
7072 BUILD_STAT_NAME(AAIsDead, Function) += ToBeDeletedFunctions.size();
7073
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007074 for (Function *Fn : ToBeDeletedFunctions)
7075 CGUpdater.removeFunction(*Fn);
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06007076
Johannes Doerfertbf112132019-08-29 01:29:44 +00007077 if (VerifyMaxFixpointIterations &&
7078 IterationCounter != MaxFixpointIterations) {
7079 errs() << "\n[Attributor] Fixpoint iteration done after: "
7080 << IterationCounter << "/" << MaxFixpointIterations
7081 << " iterations\n";
7082 llvm_unreachable("The fixpoint was not reached with exactly the number of "
7083 "specified iterations!");
7084 }
7085
Johannes Doerfertaade7822019-06-05 03:02:24 +00007086 return ManifestChange;
7087}
7088
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007089bool Attributor::isValidFunctionSignatureRewrite(
7090 Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007091
7092 auto CallSiteCanBeChanged = [](AbstractCallSite ACS) {
7093 // Forbid must-tail calls for now.
7094 return !ACS.isCallbackCall() && !ACS.getCallSite().isMustTailCall();
7095 };
7096
7097 Function *Fn = Arg.getParent();
7098 // Avoid var-arg functions for now.
7099 if (Fn->isVarArg()) {
7100 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
7101 return false;
7102 }
7103
7104 // Avoid functions with complicated argument passing semantics.
7105 AttributeList FnAttributeList = Fn->getAttributes();
7106 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
7107 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
7108 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca)) {
7109 LLVM_DEBUG(
7110 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
7111 return false;
7112 }
7113
7114 // Avoid callbacks for now.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007115 bool AllCallSitesKnown;
7116 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,
7117 AllCallSitesKnown)) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007118 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
7119 return false;
7120 }
7121
7122 auto InstPred = [](Instruction &I) {
7123 if (auto *CI = dyn_cast<CallInst>(&I))
7124 return !CI->isMustTailCall();
7125 return true;
7126 };
7127
7128 // Forbid must-tail calls for now.
7129 // TODO:
7130 bool AnyDead;
7131 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
7132 if (!checkForAllInstructionsImpl(OpcodeInstMap, InstPred, nullptr, AnyDead,
7133 {Instruction::Call})) {
7134 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
7135 return false;
7136 }
7137
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007138 return true;
7139}
7140
7141bool Attributor::registerFunctionSignatureRewrite(
7142 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
7143 ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,
7144 ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {
7145 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
7146 << Arg.getParent()->getName() << " with "
7147 << ReplacementTypes.size() << " replacements\n");
7148 assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&
7149 "Cannot register an invalid rewrite");
7150
7151 Function *Fn = Arg.getParent();
Johannes Doerfert75133632019-10-10 01:39:16 -05007152 SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = ArgumentReplacementMap[Fn];
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007153 if (ARIs.empty())
Johannes Doerfert75133632019-10-10 01:39:16 -05007154 ARIs.resize(Fn->arg_size());
7155
7156 // If we have a replacement already with less than or equal new arguments,
7157 // ignore this request.
7158 ArgumentReplacementInfo *&ARI = ARIs[Arg.getArgNo()];
7159 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
7160 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
7161 return false;
7162 }
7163
7164 // If we have a replacement already but we like the new one better, delete
7165 // the old.
7166 if (ARI)
7167 delete ARI;
7168
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007169 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
7170 << Arg.getParent()->getName() << " with "
7171 << ReplacementTypes.size() << " replacements\n");
7172
Johannes Doerfert75133632019-10-10 01:39:16 -05007173 // Remember the replacement.
7174 ARI = new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
7175 std::move(CalleeRepairCB),
7176 std::move(ACSRepairCB));
7177
7178 return true;
7179}
7180
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007181ChangeStatus Attributor::rewriteFunctionSignatures(
7182 SmallPtrSetImpl<Function *> &ModifiedFns) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007183 ChangeStatus Changed = ChangeStatus::UNCHANGED;
7184
7185 for (auto &It : ArgumentReplacementMap) {
7186 Function *OldFn = It.getFirst();
7187
7188 // Deleted functions do not require rewrites.
7189 if (ToBeDeletedFunctions.count(OldFn))
7190 continue;
7191
7192 const SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = It.getSecond();
7193 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
7194
7195 SmallVector<Type *, 16> NewArgumentTypes;
7196 SmallVector<AttributeSet, 16> NewArgumentAttributes;
7197
7198 // Collect replacement argument types and copy over existing attributes.
7199 AttributeList OldFnAttributeList = OldFn->getAttributes();
7200 for (Argument &Arg : OldFn->args()) {
7201 if (ArgumentReplacementInfo *ARI = ARIs[Arg.getArgNo()]) {
7202 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
7203 ARI->ReplacementTypes.end());
7204 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
7205 AttributeSet());
7206 } else {
7207 NewArgumentTypes.push_back(Arg.getType());
7208 NewArgumentAttributes.push_back(
7209 OldFnAttributeList.getParamAttributes(Arg.getArgNo()));
7210 }
7211 }
7212
7213 FunctionType *OldFnTy = OldFn->getFunctionType();
7214 Type *RetTy = OldFnTy->getReturnType();
7215
7216 // Construct the new function type using the new arguments types.
7217 FunctionType *NewFnTy =
7218 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
7219
7220 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
7221 << "' from " << *OldFn->getFunctionType() << " to "
7222 << *NewFnTy << "\n");
7223
7224 // Create the new function body and insert it into the module.
7225 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
7226 OldFn->getAddressSpace(), "");
7227 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
7228 NewFn->takeName(OldFn);
7229 NewFn->copyAttributesFrom(OldFn);
7230
7231 // Patch the pointer to LLVM function in debug info descriptor.
7232 NewFn->setSubprogram(OldFn->getSubprogram());
7233 OldFn->setSubprogram(nullptr);
7234
7235 // Recompute the parameter attributes list based on the new arguments for
7236 // the function.
7237 LLVMContext &Ctx = OldFn->getContext();
7238 NewFn->setAttributes(AttributeList::get(
7239 Ctx, OldFnAttributeList.getFnAttributes(),
7240 OldFnAttributeList.getRetAttributes(), NewArgumentAttributes));
7241
7242 // Since we have now created the new function, splice the body of the old
7243 // function right into the new function, leaving the old rotting hulk of the
7244 // function empty.
7245 NewFn->getBasicBlockList().splice(NewFn->begin(),
7246 OldFn->getBasicBlockList());
7247
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007248 // Set of all "call-like" instructions that invoke the old function mapped
7249 // to their new replacements.
7250 SmallVector<std::pair<CallBase *, CallBase *>, 8> CallSitePairs;
Johannes Doerfert75133632019-10-10 01:39:16 -05007251
7252 // Callback to create a new "call-like" instruction for a given one.
7253 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
7254 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
7255 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
7256
7257 // Collect the new argument operands for the replacement call site.
7258 SmallVector<Value *, 16> NewArgOperands;
7259 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
7260 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
7261 unsigned NewFirstArgNum = NewArgOperands.size();
Ilya Biryukov4f82af82019-12-31 10:21:52 +01007262 (void)NewFirstArgNum; // only used inside assert.
Johannes Doerfert75133632019-10-10 01:39:16 -05007263 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
7264 if (ARI->ACSRepairCB)
7265 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
7266 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
7267 NewArgOperands.size() &&
7268 "ACS repair callback did not provide as many operand as new "
7269 "types were registered!");
7270 // TODO: Exose the attribute set to the ACS repair callback
7271 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
7272 AttributeSet());
7273 } else {
7274 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
7275 NewArgOperandAttributes.push_back(
7276 OldCallAttributeList.getParamAttributes(OldArgNum));
7277 }
7278 }
7279
7280 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
7281 "Mismatch # argument operands vs. # argument operand attributes!");
7282 assert(NewArgOperands.size() == NewFn->arg_size() &&
7283 "Mismatch # argument operands vs. # function arguments!");
7284
7285 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
7286 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
7287
7288 // Create a new call or invoke instruction to replace the old one.
7289 CallBase *NewCB;
7290 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
7291 NewCB =
7292 InvokeInst::Create(NewFn, II->getNormalDest(), II->getUnwindDest(),
7293 NewArgOperands, OperandBundleDefs, "", OldCB);
7294 } else {
7295 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
7296 "", OldCB);
7297 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
7298 NewCB = NewCI;
7299 }
7300
7301 // Copy over various properties and the new attributes.
Johannes Doerfert75133632019-10-10 01:39:16 -05007302 uint64_t W;
7303 if (OldCB->extractProfTotalWeight(W))
7304 NewCB->setProfWeight(W);
7305 NewCB->setCallingConv(OldCB->getCallingConv());
7306 NewCB->setDebugLoc(OldCB->getDebugLoc());
7307 NewCB->takeName(OldCB);
7308 NewCB->setAttributes(AttributeList::get(
7309 Ctx, OldCallAttributeList.getFnAttributes(),
7310 OldCallAttributeList.getRetAttributes(), NewArgOperandAttributes));
7311
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007312 CallSitePairs.push_back({OldCB, NewCB});
Johannes Doerfert75133632019-10-10 01:39:16 -05007313 return true;
7314 };
7315
7316 // Use the CallSiteReplacementCreator to create replacement call sites.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007317 bool AllCallSitesKnown;
7318 bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,
7319 true, nullptr, AllCallSitesKnown);
Ilya Biryukov4f82af82019-12-31 10:21:52 +01007320 (void)Success;
Johannes Doerfert75133632019-10-10 01:39:16 -05007321 assert(Success && "Assumed call site replacement to succeed!");
7322
7323 // Rewire the arguments.
7324 auto OldFnArgIt = OldFn->arg_begin();
7325 auto NewFnArgIt = NewFn->arg_begin();
7326 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
7327 ++OldArgNum, ++OldFnArgIt) {
7328 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
7329 if (ARI->CalleeRepairCB)
7330 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
7331 NewFnArgIt += ARI->ReplacementTypes.size();
7332 } else {
7333 NewFnArgIt->takeName(&*OldFnArgIt);
7334 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
7335 ++NewFnArgIt;
7336 }
7337 }
7338
7339 // Eliminate the instructions *after* we visited all of them.
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007340 for (auto &CallSitePair : CallSitePairs) {
7341 CallBase &OldCB = *CallSitePair.first;
7342 CallBase &NewCB = *CallSitePair.second;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007343 // We do not modify the call graph here but simply reanalyze the old
7344 // function. This should be revisited once the old PM is gone.
7345 ModifiedFns.insert(OldCB.getFunction());
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007346 OldCB.replaceAllUsesWith(&NewCB);
7347 OldCB.eraseFromParent();
7348 }
Johannes Doerfert75133632019-10-10 01:39:16 -05007349
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007350 // Replace the function in the call graph (if any).
7351 CGUpdater.replaceFunctionWith(*OldFn, *NewFn);
7352
7353 // If the old function was modified and needed to be reanalyzed, the new one
7354 // does now.
7355 if (ModifiedFns.erase(OldFn))
7356 ModifiedFns.insert(NewFn);
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007357
Johannes Doerfert75133632019-10-10 01:39:16 -05007358 Changed = ChangeStatus::CHANGED;
7359 }
7360
7361 return Changed;
7362}
7363
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007364void Attributor::initializeInformationCache(Function &F) {
7365
7366 // Walk all instructions to find interesting instructions that might be
7367 // queried by abstract attributes during their initialization or update.
7368 // This has to happen before we create attributes.
7369 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
7370 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
7371
7372 for (Instruction &I : instructions(&F)) {
7373 bool IsInterestingOpcode = false;
7374
7375 // To allow easy access to all instructions in a function with a given
7376 // opcode we store them in the InfoCache. As not all opcodes are interesting
7377 // to concrete attributes we only cache the ones that are as identified in
7378 // the following switch.
7379 // Note: There are no concrete attributes now so this is initially empty.
7380 switch (I.getOpcode()) {
7381 default:
7382 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
7383 "New call site/base instruction type needs to be known int the "
7384 "Attributor.");
7385 break;
7386 case Instruction::Load:
7387 // The alignment of a pointer is interesting for loads.
7388 case Instruction::Store:
7389 // The alignment of a pointer is interesting for stores.
7390 case Instruction::Call:
7391 case Instruction::CallBr:
7392 case Instruction::Invoke:
7393 case Instruction::CleanupRet:
7394 case Instruction::CatchSwitch:
Johannes Doerfert5732f562019-12-24 19:25:08 -06007395 case Instruction::AtomicRMW:
7396 case Instruction::AtomicCmpXchg:
Hideto Uenoef4febd2019-12-29 17:34:08 +09007397 case Instruction::Br:
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007398 case Instruction::Resume:
7399 case Instruction::Ret:
7400 IsInterestingOpcode = true;
7401 }
7402 if (IsInterestingOpcode)
7403 InstOpcodeMap[I.getOpcode()].push_back(&I);
7404 if (I.mayReadOrWriteMemory())
7405 ReadOrWriteInsts.push_back(&I);
7406 }
7407}
7408
Johannes Doerfert12173e62019-10-13 20:25:25 -05007409void Attributor::recordDependence(const AbstractAttribute &FromAA,
Johannes Doerfert680f6382019-11-02 02:48:05 -05007410 const AbstractAttribute &ToAA,
7411 DepClassTy DepClass) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05007412 if (FromAA.getState().isAtFixpoint())
7413 return;
7414
Johannes Doerfert680f6382019-11-02 02:48:05 -05007415 if (DepClass == DepClassTy::REQUIRED)
7416 QueryMap[&FromAA].RequiredAAs.insert(
7417 const_cast<AbstractAttribute *>(&ToAA));
7418 else
7419 QueryMap[&FromAA].OptionalAAs.insert(
7420 const_cast<AbstractAttribute *>(&ToAA));
Johannes Doerfert2dad7292019-10-13 21:10:31 -05007421 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05007422}
7423
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00007424void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00007425 if (!VisitedFunctions.insert(&F).second)
7426 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05007427 if (F.isDeclaration())
7428 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007429
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007430 IRPosition FPos = IRPosition::function(F);
7431
Johannes Doerfert305b9612019-08-04 18:40:01 +00007432 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00007433 // We need dead instruction detection because we do not want to deal with
7434 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007435 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00007436
7437 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007438 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00007439
Johannes Doerfert58f324a2019-12-24 18:48:50 -06007440 // Every function might contain instructions that cause "undefined behavior".
7441 getOrCreateAAFor<AAUndefinedBehavior>(FPos);
7442
Stefan Stipanovic53605892019-06-27 11:27:54 +00007443 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007444 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00007445
Stefan Stipanovic06263672019-07-11 21:37:40 +00007446 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007447 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00007448
Hideto Ueno65bbaf92019-07-12 17:38:51 +00007449 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007450 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00007451
Johannes Doerferte83f3032019-08-05 23:22:05 +00007452 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007453 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00007454
Hideto Ueno63f60662019-09-21 15:13:19 +00007455 // Every function might be "no-recurse".
7456 getOrCreateAAFor<AANoRecurse>(FPos);
7457
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007458 // Every function might be "readnone/readonly/writeonly/...".
7459 getOrCreateAAFor<AAMemoryBehavior>(FPos);
7460
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007461 // Every function might be applicable for Heap-To-Stack conversion.
7462 if (EnableHeapToStack)
7463 getOrCreateAAFor<AAHeapToStack>(FPos);
7464
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00007465 // Return attributes are only appropriate if the return type is non void.
7466 Type *ReturnType = F.getReturnType();
7467 if (!ReturnType->isVoidTy()) {
7468 // Argument attribute "returned" --- Create only one per function even
7469 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007470 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00007471
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007472 IRPosition RetPos = IRPosition::returned(F);
7473
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007474 // Every returned value might be dead.
7475 getOrCreateAAFor<AAIsDead>(RetPos);
7476
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007477 // Every function might be simplified.
7478 getOrCreateAAFor<AAValueSimplify>(RetPos);
7479
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00007480 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007481
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00007482 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007483 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00007484
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00007485 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007486 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00007487
7488 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007489 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00007490
7491 // Every function with pointer return type might be marked
7492 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007493 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00007494 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00007495 }
7496
Hideto Ueno54869ec2019-07-15 06:49:04 +00007497 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007498 IRPosition ArgPos = IRPosition::argument(Arg);
7499
7500 // Every argument might be simplified.
7501 getOrCreateAAFor<AAValueSimplify>(ArgPos);
7502
Hideto Ueno19c07af2019-07-23 08:16:17 +00007503 if (Arg.getType()->isPointerTy()) {
7504 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007505 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00007506
Hideto Uenocbab3342019-08-29 05:52:00 +00007507 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007508 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00007509
Hideto Ueno19c07af2019-07-23 08:16:17 +00007510 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007511 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00007512
7513 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007514 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00007515
7516 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007517 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007518
7519 // Every argument with pointer type might be marked
7520 // "readnone/readonly/writeonly/..."
7521 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007522
7523 // Every argument with pointer type might be marked nofree.
7524 getOrCreateAAFor<AANoFree>(ArgPos);
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007525
7526 // Every argument with pointer type might be privatizable (or promotable)
7527 getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00007528 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00007529 }
7530
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007531 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00007532 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007533 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05007534 // Skip declerations except if annotations on their call sites were
7535 // explicitly requested.
Johannes Doerfert139c9ef2019-12-13 23:41:02 -06007536 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
7537 !Callee->hasMetadata(LLVMContext::MD_callback))
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05007538 return true;
7539
7540 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09007541
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007542 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
7543
7544 // Call site return values might be dead.
7545 getOrCreateAAFor<AAIsDead>(CSRetPos);
Hideto Ueno188f9a32020-01-15 15:25:52 +09007546
7547 // Call site return integer values might be limited by a constant range.
7548 if (Callee->getReturnType()->isIntegerTy()) {
7549 getOrCreateAAFor<AAValueConstantRange>(CSRetPos);
7550 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007551 }
7552
Johannes Doerfert28880192019-12-31 00:57:00 -06007553 for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007554
7555 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
7556
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007557 // Every call site argument might be dead.
7558 getOrCreateAAFor<AAIsDead>(CSArgPos);
7559
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007560 // Call site argument might be simplified.
7561 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
7562
Hideto Ueno54869ec2019-07-15 06:49:04 +00007563 if (!CS.getArgument(i)->getType()->isPointerTy())
7564 continue;
7565
7566 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007567 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00007568
Hideto Uenocbab3342019-08-29 05:52:00 +00007569 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007570 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00007571
Hideto Ueno19c07af2019-07-23 08:16:17 +00007572 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007573 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00007574
7575 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007576 getOrCreateAAFor<AAAlign>(CSArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007577
Johannes Doerfert28880192019-12-31 00:57:00 -06007578 // Call site argument attribute
7579 // "readnone/readonly/writeonly/..."
7580 getOrCreateAAFor<AAMemoryBehavior>(CSArgPos);
7581
Hideto Ueno4ecf2552019-12-12 13:42:40 +00007582 // Call site argument attribute "nofree".
7583 getOrCreateAAFor<AANoFree>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00007584 }
7585 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007586 return true;
7587 };
7588
7589 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
7590 bool Success, AnyDead = false;
7591 Success = checkForAllInstructionsImpl(
7592 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
7593 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
7594 (unsigned)Instruction::Call});
7595 (void)Success;
7596 assert(Success && !AnyDead && "Expected the check call to be successful!");
7597
7598 auto LoadStorePred = [&](Instruction &I) -> bool {
7599 if (isa<LoadInst>(I))
7600 getOrCreateAAFor<AAAlign>(
7601 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
7602 else
7603 getOrCreateAAFor<AAAlign>(
7604 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
7605 return true;
7606 };
7607 Success = checkForAllInstructionsImpl(
7608 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
7609 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
7610 (void)Success;
7611 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00007612}
7613
7614/// Helpers to ease debugging through output streams and print calls.
7615///
7616///{
7617raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
7618 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
7619}
7620
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007621raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00007622 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007623 case IRPosition::IRP_INVALID:
7624 return OS << "inv";
7625 case IRPosition::IRP_FLOAT:
7626 return OS << "flt";
7627 case IRPosition::IRP_RETURNED:
7628 return OS << "fn_ret";
7629 case IRPosition::IRP_CALL_SITE_RETURNED:
7630 return OS << "cs_ret";
7631 case IRPosition::IRP_FUNCTION:
7632 return OS << "fn";
7633 case IRPosition::IRP_CALL_SITE:
7634 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007635 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00007636 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007637 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00007638 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00007639 }
7640 llvm_unreachable("Unknown attribute position!");
7641}
7642
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007643raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007644 const Value &AV = Pos.getAssociatedValue();
7645 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007646 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
7647}
7648
Johannes Doerfert1a746452019-10-20 22:28:49 -05007649template <typename base_ty, base_ty BestState, base_ty WorstState>
Hideto Ueno188f9a32020-01-15 15:25:52 +09007650raw_ostream &
7651llvm::operator<<(raw_ostream &OS,
7652 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00007653 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
7654 << static_cast<const AbstractState &>(S);
7655}
7656
Hideto Ueno188f9a32020-01-15 15:25:52 +09007657raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {
7658 OS << "range-state(" << S.getBitWidth() << ")<";
7659 S.getKnown().print(OS);
7660 OS << " / ";
7661 S.getAssumed().print(OS);
7662 OS << ">";
7663
7664 return OS << static_cast<const AbstractState &>(S);
7665}
7666
Johannes Doerfertaade7822019-06-05 03:02:24 +00007667raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
7668 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
7669}
7670
7671raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
7672 AA.print(OS);
7673 return OS;
7674}
7675
7676void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007677 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
7678 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00007679}
7680///}
7681
7682/// ----------------------------------------------------------------------------
7683/// Pass (Manager) Boilerplate
7684/// ----------------------------------------------------------------------------
7685
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007686static bool runAttributorOnFunctions(InformationCache &InfoCache,
7687 SetVector<Function *> &Functions,
7688 AnalysisGetter &AG,
7689 CallGraphUpdater &CGUpdater) {
7690 if (DisableAttributor || Functions.empty())
Johannes Doerfertaade7822019-06-05 03:02:24 +00007691 return false;
7692
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007693 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << Functions.size()
Johannes Doerfertaade7822019-06-05 03:02:24 +00007694 << " functions.\n");
7695
7696 // Create an Attributor and initially empty information cache that is filled
7697 // while we identify default attribute opportunities.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007698 Attributor A(Functions, InfoCache, CGUpdater, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00007699
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007700 for (Function *F : Functions)
7701 A.initializeInformationCache(*F);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007702
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007703 for (Function *F : Functions) {
7704 if (F->hasExactDefinition())
Johannes Doerfertb0412e42019-09-04 16:16:13 +00007705 NumFnWithExactDefinition++;
7706 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00007707 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007708
Johannes Doerfert2f622062019-09-04 16:35:20 +00007709 // We look at internal functions only on-demand but if any use is not a
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007710 // direct call or outside the current set of analyzed functions, we have to
7711 // do it eagerly.
7712 if (F->hasLocalLinkage()) {
7713 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
7714 ImmutableCallSite ICS(U.getUser());
7715 return ICS && ICS.isCallee(&U) &&
7716 Functions.count(const_cast<Function *>(ICS.getCaller()));
Johannes Doerfert2f622062019-09-04 16:35:20 +00007717 }))
7718 continue;
7719 }
7720
Johannes Doerfertaade7822019-06-05 03:02:24 +00007721 // Populate the Attributor with abstract attribute opportunities in the
7722 // function and the information cache with IR information.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007723 A.identifyDefaultAbstractAttributes(*F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00007724 }
7725
Johannes Doerfert77a9e612020-01-11 23:36:17 -06007726 ChangeStatus Changed = A.run();
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007727 assert(!verifyModule(*Functions.front()->getParent(), &errs()) &&
7728 "Module verification failed!");
Johannes Doerfert77a9e612020-01-11 23:36:17 -06007729 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
7730 << " functions, result: " << Changed << ".\n");
7731 return Changed == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007732}
7733
7734PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007735 FunctionAnalysisManager &FAM =
7736 AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
7737 AnalysisGetter AG(FAM);
7738
7739 SetVector<Function *> Functions;
7740 for (Function &F : M)
7741 Functions.insert(&F);
7742
7743 CallGraphUpdater CGUpdater;
7744 InformationCache InfoCache(M, AG, /* CGSCC */ nullptr);
7745 if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
7746 // FIXME: Think about passes we will preserve and add them here.
7747 return PreservedAnalyses::none();
7748 }
7749 return PreservedAnalyses::all();
7750}
7751
7752PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C,
7753 CGSCCAnalysisManager &AM,
7754 LazyCallGraph &CG,
7755 CGSCCUpdateResult &UR) {
7756 FunctionAnalysisManager &FAM =
7757 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
7758 AnalysisGetter AG(FAM);
7759
7760 SetVector<Function *> Functions;
7761 for (LazyCallGraph::Node &N : C)
7762 Functions.insert(&N.getFunction());
7763
7764 if (Functions.empty())
7765 return PreservedAnalyses::all();
7766
7767 Module &M = *Functions.back()->getParent();
7768 CallGraphUpdater CGUpdater;
7769 CGUpdater.initialize(CG, C, AM, UR);
7770 InformationCache InfoCache(M, AG, /* CGSCC */ &Functions);
7771 if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00007772 // FIXME: Think about passes we will preserve and add them here.
7773 return PreservedAnalyses::none();
7774 }
7775 return PreservedAnalyses::all();
7776}
7777
7778namespace {
7779
7780struct AttributorLegacyPass : public ModulePass {
7781 static char ID;
7782
7783 AttributorLegacyPass() : ModulePass(ID) {
7784 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
7785 }
7786
7787 bool runOnModule(Module &M) override {
7788 if (skipModule(M))
7789 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007790
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00007791 AnalysisGetter AG;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007792 SetVector<Function *> Functions;
7793 for (Function &F : M)
7794 Functions.insert(&F);
7795
7796 CallGraphUpdater CGUpdater;
7797 InformationCache InfoCache(M, AG, /* CGSCC */ nullptr);
7798 return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater);
Johannes Doerfertaade7822019-06-05 03:02:24 +00007799 }
7800
7801 void getAnalysisUsage(AnalysisUsage &AU) const override {
7802 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007803 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00007804 }
7805};
7806
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007807struct AttributorCGSCCLegacyPass : public CallGraphSCCPass {
7808 CallGraphUpdater CGUpdater;
7809 static char ID;
7810
7811 AttributorCGSCCLegacyPass() : CallGraphSCCPass(ID) {
7812 initializeAttributorCGSCCLegacyPassPass(*PassRegistry::getPassRegistry());
7813 }
7814
7815 bool runOnSCC(CallGraphSCC &SCC) override {
7816 if (skipSCC(SCC))
7817 return false;
7818
7819 SetVector<Function *> Functions;
7820 for (CallGraphNode *CGN : SCC)
7821 if (Function *Fn = CGN->getFunction())
7822 if (!Fn->isDeclaration())
7823 Functions.insert(Fn);
7824
7825 if (Functions.empty())
7826 return false;
7827
7828 AnalysisGetter AG;
7829 CallGraph &CG = const_cast<CallGraph &>(SCC.getCallGraph());
7830 CGUpdater.initialize(CG, SCC);
7831 Module &M = *Functions.back()->getParent();
7832 InformationCache InfoCache(M, AG, /* CGSCC */ &Functions);
7833 return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater);
7834 }
7835
7836 bool doFinalization(CallGraph &CG) override { return CGUpdater.finalize(); }
7837
7838 void getAnalysisUsage(AnalysisUsage &AU) const override {
7839 // FIXME: Think about passes we will preserve and add them here.
7840 AU.addRequired<TargetLibraryInfoWrapperPass>();
7841 CallGraphSCCPass::getAnalysisUsage(AU);
7842 }
7843};
7844
Johannes Doerfertaade7822019-06-05 03:02:24 +00007845} // end anonymous namespace
7846
7847Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007848Pass *llvm::createAttributorCGSCCLegacyPass() {
7849 return new AttributorCGSCCLegacyPass();
7850}
Johannes Doerfertaade7822019-06-05 03:02:24 +00007851
7852char AttributorLegacyPass::ID = 0;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007853char AttributorCGSCCLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007854
7855const char AAReturnedValues::ID = 0;
7856const char AANoUnwind::ID = 0;
7857const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00007858const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007859const char AANonNull::ID = 0;
7860const char AANoRecurse::ID = 0;
7861const char AAWillReturn::ID = 0;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06007862const char AAUndefinedBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007863const char AANoAlias::ID = 0;
Pankaj Gode04945c92019-11-22 18:40:47 +05307864const char AAReachability::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007865const char AANoReturn::ID = 0;
7866const char AAIsDead::ID = 0;
7867const char AADereferenceable::ID = 0;
7868const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00007869const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007870const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007871const char AAHeapToStack::ID = 0;
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007872const char AAPrivatizablePtr::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007873const char AAMemoryBehavior::ID = 0;
Hideto Ueno188f9a32020-01-15 15:25:52 +09007874const char AAValueConstantRange::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007875
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007876// Macro magic to create the static generator function for attributes that
7877// follow the naming scheme.
7878
7879#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
7880 case IRPosition::PK: \
7881 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
7882
7883#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
7884 case IRPosition::PK: \
7885 AA = new CLASS##SUFFIX(IRP); \
7886 break;
7887
7888#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7889 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7890 CLASS *AA = nullptr; \
7891 switch (IRP.getPositionKind()) { \
7892 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7893 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
7894 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
7895 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
7896 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
7897 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
7898 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
7899 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
7900 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007901 return *AA; \
7902 }
7903
7904#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7905 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7906 CLASS *AA = nullptr; \
7907 switch (IRP.getPositionKind()) { \
7908 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7909 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
7910 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
7911 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
7912 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
7913 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
7914 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
7915 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
7916 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007917 return *AA; \
7918 }
7919
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007920#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7921 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7922 CLASS *AA = nullptr; \
7923 switch (IRP.getPositionKind()) { \
7924 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7925 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
7926 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
7927 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
7928 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
7929 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
7930 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
7931 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
7932 } \
7933 return *AA; \
7934 }
7935
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007936#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7937 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7938 CLASS *AA = nullptr; \
7939 switch (IRP.getPositionKind()) { \
7940 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7941 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
7942 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
7943 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
7944 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
7945 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
7946 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
7947 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
7948 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007949 return *AA; \
7950 }
7951
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007952#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7953 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7954 CLASS *AA = nullptr; \
7955 switch (IRP.getPositionKind()) { \
7956 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7957 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
7958 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
7959 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
7960 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
7961 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
7962 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
7963 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
7964 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007965 return *AA; \
7966 }
7967
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007968CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
7969CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007970CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
7971CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
7972CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007973CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
7974
7975CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
7976CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007977CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007978CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
7979CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00007980CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Hideto Ueno188f9a32020-01-15 15:25:52 +09007981CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007982
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007983CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007984CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007985CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007986
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007987CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
Pankaj Gode04945c92019-11-22 18:40:47 +05307988CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06007989CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007990
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007991CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
7992
Johannes Doerfertd4bea882019-10-07 23:28:54 +00007993#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007994#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00007995#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007996#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007997#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007998#undef SWITCH_PK_CREATE
7999#undef SWITCH_PK_INV
8000
Johannes Doerfertaade7822019-06-05 03:02:24 +00008001INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
8002 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008003INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00008004INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
8005 "Deduce and propagate attributes", false, false)
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008006INITIALIZE_PASS_BEGIN(AttributorCGSCCLegacyPass, "attributor-cgscc",
8007 "Deduce and propagate attributes (CGSCC pass)", false,
8008 false)
8009INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
8010INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
8011INITIALIZE_PASS_END(AttributorCGSCCLegacyPass, "attributor-cgscc",
8012 "Deduce and propagate attributes (CGSCC pass)", false,
8013 false)