blob: 877557a92fb5e970739e15b87b95dd8597f28f7e [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 Doerfert185e9b02020-02-11 11:19:34 -0600377/// value, the \p State, and a flag to indicate if we stripped anything (=the
378/// value used for the callback is not the value associated with \p IRP). To
Johannes Doerfertdef99282019-08-14 21:29:37 +0000379/// limit how much effort is invested, we will never visit more values than
380/// specified by \p MaxValues.
381template <typename AAType, typename StateTy>
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000382static bool genericValueTraversal(
Johannes Doerfertdef99282019-08-14 21:29:37 +0000383 Attributor &A, IRPosition IRP, const AAType &QueryingAA, StateTy &State,
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000384 const function_ref<bool(Value &, StateTy &, bool)> &VisitValueCB,
Johannes Doerfertdef99282019-08-14 21:29:37 +0000385 int MaxValues = 8) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000386
Johannes Doerfertdef99282019-08-14 21:29:37 +0000387 const AAIsDead *LivenessAA = nullptr;
388 if (IRP.getAnchorScope())
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000389 LivenessAA = &A.getAAFor<AAIsDead>(
Johannes Doerfert19b00432019-08-26 17:48:05 +0000390 QueryingAA, IRPosition::function(*IRP.getAnchorScope()),
391 /* TrackDependence */ false);
392 bool AnyDead = false;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000393
394 // TODO: Use Positions here to allow context sensitivity in VisitValueCB
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000395 SmallPtrSet<Value *, 16> Visited;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000396 SmallVector<Value *, 16> Worklist;
Johannes Doerfertdef99282019-08-14 21:29:37 +0000397 Worklist.push_back(&IRP.getAssociatedValue());
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000398
399 int Iteration = 0;
400 do {
401 Value *V = Worklist.pop_back_val();
402
403 // Check if we should process the current value. To prevent endless
404 // recursion keep a record of the values we followed!
Johannes Doerfertdef99282019-08-14 21:29:37 +0000405 if (!Visited.insert(V).second)
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000406 continue;
407
408 // Make sure we limit the compile time for complex expressions.
409 if (Iteration++ >= MaxValues)
410 return false;
411
412 // Explicitly look through calls with a "returned" attribute if we do
413 // not have a pointer as stripPointerCasts only works on them.
Johannes Doerfertdef99282019-08-14 21:29:37 +0000414 Value *NewV = nullptr;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000415 if (V->getType()->isPointerTy()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +0000416 NewV = V->stripPointerCasts();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000417 } else {
418 CallSite CS(V);
419 if (CS && CS.getCalledFunction()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000420 for (Argument &Arg : CS.getCalledFunction()->args())
421 if (Arg.hasReturnedAttr()) {
422 NewV = CS.getArgOperand(Arg.getArgNo());
423 break;
424 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000425 }
426 }
Johannes Doerfertdef99282019-08-14 21:29:37 +0000427 if (NewV && NewV != V) {
428 Worklist.push_back(NewV);
429 continue;
430 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000431
432 // Look through select instructions, visit both potential values.
433 if (auto *SI = dyn_cast<SelectInst>(V)) {
434 Worklist.push_back(SI->getTrueValue());
435 Worklist.push_back(SI->getFalseValue());
436 continue;
437 }
438
Johannes Doerfertdef99282019-08-14 21:29:37 +0000439 // Look through phi nodes, visit all live operands.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000440 if (auto *PHI = dyn_cast<PHINode>(V)) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000441 assert(LivenessAA &&
442 "Expected liveness in the presence of instructions!");
Johannes Doerfertdef99282019-08-14 21:29:37 +0000443 for (unsigned u = 0, e = PHI->getNumIncomingValues(); u < e; u++) {
444 const BasicBlock *IncomingBB = PHI->getIncomingBlock(u);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000445 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +0000446 AnyDead = true;
Johannes Doerfert19b00432019-08-26 17:48:05 +0000447 continue;
448 }
449 Worklist.push_back(PHI->getIncomingValue(u));
Johannes Doerfertdef99282019-08-14 21:29:37 +0000450 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000451 continue;
452 }
453
454 // Once a leaf is reached we inform the user through the callback.
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000455 if (!VisitValueCB(*V, State, Iteration > 1))
456 return false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000457 } while (!Worklist.empty());
458
Johannes Doerfert19b00432019-08-26 17:48:05 +0000459 // If we actually used liveness information so we have to record a dependence.
460 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -0500461 A.recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +0000462
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000463 // All values have been visited.
464 return true;
465}
466
Johannes Doerfertaade7822019-06-05 03:02:24 +0000467/// Return true if \p New is equal or worse than \p Old.
468static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
469 if (!Old.isIntAttribute())
470 return true;
471
472 return Old.getValueAsInt() >= New.getValueAsInt();
473}
474
475/// Return true if the information provided by \p Attr was added to the
476/// attribute list \p Attrs. This is only the case if it was not already present
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000477/// in \p Attrs at the position describe by \p PK and \p AttrIdx.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000478static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000479 AttributeList &Attrs, int AttrIdx) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000480
481 if (Attr.isEnumAttribute()) {
482 Attribute::AttrKind Kind = Attr.getKindAsEnum();
483 if (Attrs.hasAttribute(AttrIdx, Kind))
484 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
485 return false;
486 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
487 return true;
488 }
489 if (Attr.isStringAttribute()) {
490 StringRef Kind = Attr.getKindAsString();
491 if (Attrs.hasAttribute(AttrIdx, Kind))
492 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
493 return false;
494 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
495 return true;
496 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000497 if (Attr.isIntAttribute()) {
498 Attribute::AttrKind Kind = Attr.getKindAsEnum();
499 if (Attrs.hasAttribute(AttrIdx, Kind))
500 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
501 return false;
502 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
503 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
504 return true;
505 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000506
507 llvm_unreachable("Expected enum or string attribute!");
508}
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000509
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000510static const Value *
511getBasePointerOfAccessPointerOperand(const Instruction *I, int64_t &BytesOffset,
512 const DataLayout &DL,
513 bool AllowNonInbounds = false) {
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -0600514 const Value *Ptr = getPointerOperand(I, /* AllowVolatile */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000515 if (!Ptr)
516 return nullptr;
517
518 return GetPointerBaseWithConstantOffset(Ptr, BytesOffset, DL,
Hideto Ueno0f4383f2019-11-27 14:41:12 +0000519 AllowNonInbounds);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000520}
Johannes Doerfertaade7822019-06-05 03:02:24 +0000521
Johannes Doerfertece81902019-08-12 22:05:53 +0000522ChangeStatus AbstractAttribute::update(Attributor &A) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000523 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
524 if (getState().isAtFixpoint())
525 return HasChanged;
526
527 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
528
Johannes Doerfertece81902019-08-12 22:05:53 +0000529 HasChanged = updateImpl(A);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000530
531 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
532 << "\n");
533
534 return HasChanged;
535}
536
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000537ChangeStatus
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500538IRAttributeManifest::manifestAttrs(Attributor &A, const IRPosition &IRP,
Johannes Doerfertd1b79e02019-08-07 22:46:11 +0000539 const ArrayRef<Attribute> &DeducedAttrs) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000540 Function *ScopeFn = IRP.getAssociatedFunction();
Kristina Brooks26e60f02019-08-06 19:53:19 +0000541 IRPosition::Kind PK = IRP.getPositionKind();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000542
Johannes Doerfertaade7822019-06-05 03:02:24 +0000543 // In the following some generic code that will manifest attributes in
544 // DeducedAttrs if they improve the current IR. Due to the different
545 // annotation positions we use the underlying AttributeList interface.
Johannes Doerfertaade7822019-06-05 03:02:24 +0000546
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000547 AttributeList Attrs;
548 switch (PK) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000549 case IRPosition::IRP_INVALID:
550 case IRPosition::IRP_FLOAT:
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000551 return ChangeStatus::UNCHANGED;
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000552 case IRPosition::IRP_ARGUMENT:
553 case IRPosition::IRP_FUNCTION:
554 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000555 Attrs = ScopeFn->getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000556 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000557 case IRPosition::IRP_CALL_SITE:
558 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000559 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000560 Attrs = ImmutableCallSite(&IRP.getAnchorValue()).getAttributes();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000561 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000562 }
563
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000564 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000565 LLVMContext &Ctx = IRP.getAnchorValue().getContext();
Johannes Doerfertaade7822019-06-05 03:02:24 +0000566 for (const Attribute &Attr : DeducedAttrs) {
Kristina Brooks26e60f02019-08-06 19:53:19 +0000567 if (!addIfNotExistent(Ctx, Attr, Attrs, IRP.getAttrIdx()))
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000568 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000569
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000570 HasChanged = ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000571 }
572
573 if (HasChanged == ChangeStatus::UNCHANGED)
574 return HasChanged;
575
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000576 switch (PK) {
577 case IRPosition::IRP_ARGUMENT:
578 case IRPosition::IRP_FUNCTION:
579 case IRPosition::IRP_RETURNED:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000580 ScopeFn->setAttributes(Attrs);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000581 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000582 case IRPosition::IRP_CALL_SITE:
583 case IRPosition::IRP_CALL_SITE_RETURNED:
Johannes Doerfertfb69f762019-08-05 23:32:31 +0000584 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Kristina Brooks26e60f02019-08-06 19:53:19 +0000585 CallSite(&IRP.getAnchorValue()).setAttributes(Attrs);
Johannes Doerfert4395b312019-08-14 21:46:28 +0000586 break;
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000587 case IRPosition::IRP_INVALID:
Johannes Doerfert4395b312019-08-14 21:46:28 +0000588 case IRPosition::IRP_FLOAT:
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000589 break;
Johannes Doerfertaade7822019-06-05 03:02:24 +0000590 }
591
592 return HasChanged;
593}
594
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000595const IRPosition IRPosition::EmptyKey(255);
596const IRPosition IRPosition::TombstoneKey(256);
597
598SubsumingPositionIterator::SubsumingPositionIterator(const IRPosition &IRP) {
599 IRPositions.emplace_back(IRP);
600
601 ImmutableCallSite ICS(&IRP.getAnchorValue());
602 switch (IRP.getPositionKind()) {
603 case IRPosition::IRP_INVALID:
604 case IRPosition::IRP_FLOAT:
605 case IRPosition::IRP_FUNCTION:
606 return;
607 case IRPosition::IRP_ARGUMENT:
608 case IRPosition::IRP_RETURNED:
609 IRPositions.emplace_back(
610 IRPosition::function(*IRP.getAssociatedFunction()));
611 return;
612 case IRPosition::IRP_CALL_SITE:
613 assert(ICS && "Expected call site!");
614 // TODO: We need to look at the operand bundles similar to the redirection
615 // in CallBase.
616 if (!ICS.hasOperandBundles())
617 if (const Function *Callee = ICS.getCalledFunction())
618 IRPositions.emplace_back(IRPosition::function(*Callee));
619 return;
620 case IRPosition::IRP_CALL_SITE_RETURNED:
621 assert(ICS && "Expected call site!");
622 // TODO: We need to look at the operand bundles similar to the redirection
623 // in CallBase.
624 if (!ICS.hasOperandBundles()) {
625 if (const Function *Callee = ICS.getCalledFunction()) {
626 IRPositions.emplace_back(IRPosition::returned(*Callee));
627 IRPositions.emplace_back(IRPosition::function(*Callee));
628 }
629 }
630 IRPositions.emplace_back(
631 IRPosition::callsite_function(cast<CallBase>(*ICS.getInstruction())));
632 return;
633 case IRPosition::IRP_CALL_SITE_ARGUMENT: {
634 int ArgNo = IRP.getArgNo();
635 assert(ICS && ArgNo >= 0 && "Expected call site!");
636 // TODO: We need to look at the operand bundles similar to the redirection
637 // in CallBase.
638 if (!ICS.hasOperandBundles()) {
639 const Function *Callee = ICS.getCalledFunction();
640 if (Callee && Callee->arg_size() > unsigned(ArgNo))
641 IRPositions.emplace_back(IRPosition::argument(*Callee->getArg(ArgNo)));
642 if (Callee)
643 IRPositions.emplace_back(IRPosition::function(*Callee));
644 }
645 IRPositions.emplace_back(IRPosition::value(IRP.getAssociatedValue()));
646 return;
647 }
648 }
649}
650
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000651bool IRPosition::hasAttr(ArrayRef<Attribute::AttrKind> AKs,
652 bool IgnoreSubsumingPositions) const {
653 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000654 for (Attribute::AttrKind AK : AKs)
655 if (EquivIRP.getAttr(AK).getKindAsEnum() == AK)
656 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +0000657 // The first position returned by the SubsumingPositionIterator is
658 // always the position itself. If we ignore subsuming positions we
659 // are done after the first iteration.
660 if (IgnoreSubsumingPositions)
661 break;
662 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000663 return false;
664}
665
666void IRPosition::getAttrs(ArrayRef<Attribute::AttrKind> AKs,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600667 SmallVectorImpl<Attribute> &Attrs,
668 bool IgnoreSubsumingPositions) const {
669 for (const IRPosition &EquivIRP : SubsumingPositionIterator(*this)) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000670 for (Attribute::AttrKind AK : AKs) {
671 const Attribute &Attr = EquivIRP.getAttr(AK);
672 if (Attr.getKindAsEnum() == AK)
673 Attrs.push_back(Attr);
674 }
Johannes Doerfert6abd01e2019-12-12 15:02:36 -0600675 // The first position returned by the SubsumingPositionIterator is
676 // always the position itself. If we ignore subsuming positions we
677 // are done after the first iteration.
678 if (IgnoreSubsumingPositions)
679 break;
680 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000681}
682
683void IRPosition::verify() {
684 switch (KindOrArgNo) {
685 default:
686 assert(KindOrArgNo >= 0 && "Expected argument or call site argument!");
687 assert((isa<CallBase>(AnchorVal) || isa<Argument>(AnchorVal)) &&
688 "Expected call base or argument for positive attribute index!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000689 if (isa<Argument>(AnchorVal)) {
690 assert(cast<Argument>(AnchorVal)->getArgNo() == unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000691 "Argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000692 assert(cast<Argument>(AnchorVal) == &getAssociatedValue() &&
693 "Associated value mismatch!");
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000694 } else {
Simon Pilgrim920b0402019-08-29 10:08:45 +0000695 assert(cast<CallBase>(*AnchorVal).arg_size() > unsigned(getArgNo()) &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000696 "Call site argument number mismatch!");
Simon Pilgrim920b0402019-08-29 10:08:45 +0000697 assert(cast<CallBase>(*AnchorVal).getArgOperand(getArgNo()) ==
698 &getAssociatedValue() &&
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000699 "Associated value mismatch!");
700 }
701 break;
702 case IRP_INVALID:
703 assert(!AnchorVal && "Expected no value for an invalid position!");
704 break;
705 case IRP_FLOAT:
706 assert((!isa<CallBase>(&getAssociatedValue()) &&
707 !isa<Argument>(&getAssociatedValue())) &&
708 "Expected specialized kind for call base and argument values!");
709 break;
710 case IRP_RETURNED:
711 assert(isa<Function>(AnchorVal) &&
712 "Expected function for a 'returned' position!");
713 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
714 break;
715 case IRP_CALL_SITE_RETURNED:
716 assert((isa<CallBase>(AnchorVal)) &&
717 "Expected call base for 'call site returned' position!");
718 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
719 break;
720 case IRP_CALL_SITE:
721 assert((isa<CallBase>(AnchorVal)) &&
722 "Expected call base for 'call site function' position!");
723 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
724 break;
725 case IRP_FUNCTION:
726 assert(isa<Function>(AnchorVal) &&
727 "Expected function for a 'function' position!");
728 assert(AnchorVal == &getAssociatedValue() && "Associated value mismatch!");
729 break;
730 }
731}
732
Benjamin Kramerdf4b9a32019-09-17 12:56:29 +0000733namespace {
Johannes Doerfert1a746452019-10-20 22:28:49 -0500734/// Helper function to clamp a state \p S of type \p StateType with the
Johannes Doerfert234eda52019-08-16 19:51:23 +0000735/// information in \p R and indicate/return if \p S did change (as-in update is
736/// required to be run again).
Johannes Doerfert234eda52019-08-16 19:51:23 +0000737template <typename StateType>
Johannes Doerfert1a746452019-10-20 22:28:49 -0500738ChangeStatus clampStateAndIndicateChange(StateType &S, const StateType &R) {
Johannes Doerfert234eda52019-08-16 19:51:23 +0000739 auto Assumed = S.getAssumed();
740 S ^= R;
741 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
742 : ChangeStatus::CHANGED;
743}
Johannes Doerfertb9b87912019-08-20 06:02:39 +0000744
Johannes Doerfert234eda52019-08-16 19:51:23 +0000745/// Clamp the information known for all returned values of a function
746/// (identified by \p QueryingAA) into \p S.
747template <typename AAType, typename StateType = typename AAType::StateType>
748static void clampReturnedValueStates(Attributor &A, const AAType &QueryingAA,
749 StateType &S) {
750 LLVM_DEBUG(dbgs() << "[Attributor] Clamp return value states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600751 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000752
753 assert((QueryingAA.getIRPosition().getPositionKind() ==
754 IRPosition::IRP_RETURNED ||
755 QueryingAA.getIRPosition().getPositionKind() ==
756 IRPosition::IRP_CALL_SITE_RETURNED) &&
757 "Can only clamp returned value states for a function returned or call "
758 "site returned position!");
759
760 // Use an optional state as there might not be any return values and we want
761 // to join (IntegerState::operator&) the state of all there are.
762 Optional<StateType> T;
763
764 // Callback for each possibly returned value.
765 auto CheckReturnValue = [&](Value &RV) -> bool {
766 const IRPosition &RVPos = IRPosition::value(RV);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000767 const AAType &AA = A.getAAFor<AAType>(QueryingAA, RVPos);
768 LLVM_DEBUG(dbgs() << "[Attributor] RV: " << RV << " AA: " << AA.getAsStr()
769 << " @ " << RVPos << "\n");
770 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000771 if (T.hasValue())
772 *T &= AAS;
773 else
774 T = AAS;
775 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " RV State: " << T
776 << "\n");
777 return T->isValidState();
778 };
779
780 if (!A.checkForAllReturnedValues(CheckReturnValue, QueryingAA))
781 S.indicatePessimisticFixpoint();
782 else if (T.hasValue())
783 S ^= *T;
784}
785
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000786/// Helper class to compose two generic deduction
787template <typename AAType, typename Base, typename StateType,
788 template <typename...> class F, template <typename...> class G>
789struct AAComposeTwoGenericDeduction
790 : public F<AAType, G<AAType, Base, StateType>, StateType> {
791 AAComposeTwoGenericDeduction(const IRPosition &IRP)
792 : F<AAType, G<AAType, Base, StateType>, StateType>(IRP) {}
793
794 /// See AbstractAttribute::updateImpl(...).
795 ChangeStatus updateImpl(Attributor &A) override {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100796 ChangeStatus ChangedF =
797 F<AAType, G<AAType, Base, StateType>, StateType>::updateImpl(A);
Johannes Doerfertdb6efb02019-10-13 20:40:10 +0000798 ChangeStatus ChangedG = G<AAType, Base, StateType>::updateImpl(A);
799 return ChangedF | ChangedG;
Hideto Ueno08daf8c2019-10-08 15:20:19 +0000800 }
801};
802
Johannes Doerfert234eda52019-08-16 19:51:23 +0000803/// Helper class for generic deduction: return value -> returned position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000804template <typename AAType, typename Base,
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600805 typename StateType = typename Base::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000806struct AAReturnedFromReturnedValues : public Base {
807 AAReturnedFromReturnedValues(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000808
809 /// See AbstractAttribute::updateImpl(...).
810 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600811 StateType S(StateType::getBestState(this->getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000812 clampReturnedValueStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000813 // TODO: If we know we visited all returned values, thus no are assumed
814 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000815 return clampStateAndIndicateChange<StateType>(this->getState(), S);
816 }
817};
818
819/// Clamp the information known at all call sites for a given argument
820/// (identified by \p QueryingAA) into \p S.
821template <typename AAType, typename StateType = typename AAType::StateType>
822static void clampCallSiteArgumentStates(Attributor &A, const AAType &QueryingAA,
823 StateType &S) {
824 LLVM_DEBUG(dbgs() << "[Attributor] Clamp call site argument states for "
Johannes Doerfert3d347e22019-12-13 23:35:45 -0600825 << QueryingAA << " into " << S << "\n");
Johannes Doerfert234eda52019-08-16 19:51:23 +0000826
827 assert(QueryingAA.getIRPosition().getPositionKind() ==
828 IRPosition::IRP_ARGUMENT &&
829 "Can only clamp call site argument states for an argument position!");
830
831 // Use an optional state as there might not be any return values and we want
832 // to join (IntegerState::operator&) the state of all there are.
833 Optional<StateType> T;
834
835 // The argument number which is also the call site argument number.
836 unsigned ArgNo = QueryingAA.getIRPosition().getArgNo();
837
Johannes Doerfert661db042019-10-07 23:14:58 +0000838 auto CallSiteCheck = [&](AbstractCallSite ACS) {
839 const IRPosition &ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
840 // Check if a coresponding argument was found or if it is on not associated
841 // (which can happen for callback calls).
842 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
843 return false;
844
845 const AAType &AA = A.getAAFor<AAType>(QueryingAA, ACSArgPos);
846 LLVM_DEBUG(dbgs() << "[Attributor] ACS: " << *ACS.getInstruction()
847 << " AA: " << AA.getAsStr() << " @" << ACSArgPos << "\n");
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000848 const StateType &AAS = static_cast<const StateType &>(AA.getState());
Johannes Doerfert234eda52019-08-16 19:51:23 +0000849 if (T.hasValue())
850 *T &= AAS;
851 else
852 T = AAS;
853 LLVM_DEBUG(dbgs() << "[Attributor] AA State: " << AAS << " CSA State: " << T
854 << "\n");
855 return T->isValidState();
856 };
857
Johannes Doerfert368f7ee2019-12-30 16:12:36 -0600858 bool AllCallSitesKnown;
859 if (!A.checkForAllCallSites(CallSiteCheck, QueryingAA, true,
860 AllCallSitesKnown))
Johannes Doerfert234eda52019-08-16 19:51:23 +0000861 S.indicatePessimisticFixpoint();
862 else if (T.hasValue())
863 S ^= *T;
864}
865
866/// Helper class for generic deduction: call site argument -> argument position.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000867template <typename AAType, typename Base,
868 typename StateType = typename AAType::StateType>
869struct AAArgumentFromCallSiteArguments : public Base {
870 AAArgumentFromCallSiteArguments(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000871
872 /// See AbstractAttribute::updateImpl(...).
873 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertea5fabe2020-01-28 09:46:15 -0600874 StateType S(StateType::getBestState(this->getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000875 clampCallSiteArgumentStates<AAType, StateType>(A, *this, S);
Johannes Doerfert028b2aa2019-08-20 05:57:01 +0000876 // TODO: If we know we visited all incoming values, thus no are assumed
877 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +0000878 return clampStateAndIndicateChange<StateType>(this->getState(), S);
879 }
880};
881
882/// Helper class for generic replication: function returned -> cs returned.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000883template <typename AAType, typename Base,
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600884 typename StateType = typename Base::StateType>
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000885struct AACallSiteReturnedFromReturned : public Base {
886 AACallSiteReturnedFromReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert234eda52019-08-16 19:51:23 +0000887
888 /// See AbstractAttribute::updateImpl(...).
889 ChangeStatus updateImpl(Attributor &A) override {
890 assert(this->getIRPosition().getPositionKind() ==
891 IRPosition::IRP_CALL_SITE_RETURNED &&
892 "Can only wrap function returned positions for call site returned "
893 "positions!");
894 auto &S = this->getState();
895
896 const Function *AssociatedFunction =
897 this->getIRPosition().getAssociatedFunction();
898 if (!AssociatedFunction)
899 return S.indicatePessimisticFixpoint();
900
901 IRPosition FnPos = IRPosition::returned(*AssociatedFunction);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000902 const AAType &AA = A.getAAFor<AAType>(*this, FnPos);
Johannes Doerfert234eda52019-08-16 19:51:23 +0000903 return clampStateAndIndicateChange(
Johannes Doerfert791c9f12020-01-29 18:02:42 -0600904 S, static_cast<const StateType &>(AA.getState()));
Johannes Doerfert234eda52019-08-16 19:51:23 +0000905 }
906};
907
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000908/// Helper class for generic deduction using must-be-executed-context
909/// Base class is required to have `followUse` method.
910
911/// bool followUse(Attributor &A, const Use *U, const Instruction *I)
Simon Pilgrimf7aee612019-10-10 15:25:16 +0000912/// U - Underlying use.
913/// I - The user of the \p U.
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000914/// `followUse` returns true if the value should be tracked transitively.
915
916template <typename AAType, typename Base,
917 typename StateType = typename AAType::StateType>
918struct AAFromMustBeExecutedContext : public Base {
919 AAFromMustBeExecutedContext(const IRPosition &IRP) : Base(IRP) {}
920
921 void initialize(Attributor &A) override {
922 Base::initialize(A);
Johannes Doerfertb2083c52019-10-20 22:46:48 -0500923 const IRPosition &IRP = this->getIRPosition();
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000924 Instruction *CtxI = IRP.getCtxI();
925
926 if (!CtxI)
927 return;
928
929 for (const Use &U : IRP.getAssociatedValue().uses())
930 Uses.insert(&U);
931 }
932
933 /// See AbstractAttribute::updateImpl(...).
934 ChangeStatus updateImpl(Attributor &A) override {
935 auto BeforeState = this->getState();
936 auto &S = this->getState();
937 Instruction *CtxI = this->getIRPosition().getCtxI();
938 if (!CtxI)
939 return ChangeStatus::UNCHANGED;
940
941 MustBeExecutedContextExplorer &Explorer =
942 A.getInfoCache().getMustBeExecutedContextExplorer();
943
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500944 auto EIt = Explorer.begin(CtxI), EEnd = Explorer.end(CtxI);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +0100945 for (unsigned u = 0; u < Uses.size(); ++u) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500946 const Use *U = Uses[u];
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000947 if (const Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -0500948 bool Found = Explorer.findInContextOf(UserI, EIt, EEnd);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000949 if (Found && Base::followUse(A, U, UserI))
950 for (const Use &Us : UserI->uses())
Johannes Doerferteb4f41d2019-10-30 17:21:53 -0500951 Uses.insert(&Us);
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000952 }
953 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +0000954
955 return BeforeState == S ? ChangeStatus::UNCHANGED : ChangeStatus::CHANGED;
956 }
957
958private:
959 /// Container for (transitive) uses of the associated value.
960 SetVector<const Use *> Uses;
961};
962
963template <typename AAType, typename Base,
964 typename StateType = typename AAType::StateType>
965using AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext =
966 AAComposeTwoGenericDeduction<AAType, Base, StateType,
967 AAFromMustBeExecutedContext,
968 AAArgumentFromCallSiteArguments>;
969
970template <typename AAType, typename Base,
971 typename StateType = typename AAType::StateType>
972using AACallSiteReturnedFromReturnedAndMustBeExecutedContext =
973 AAComposeTwoGenericDeduction<AAType, Base, StateType,
974 AAFromMustBeExecutedContext,
975 AACallSiteReturnedFromReturned>;
976
Stefan Stipanovic53605892019-06-27 11:27:54 +0000977/// -----------------------NoUnwind Function Attribute--------------------------
978
Johannes Doerfert344d0382019-08-07 22:34:26 +0000979struct AANoUnwindImpl : AANoUnwind {
Johannes Doerfert710ebb02019-08-14 21:18:01 +0000980 AANoUnwindImpl(const IRPosition &IRP) : AANoUnwind(IRP) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000981
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000982 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000983 return getAssumed() ? "nounwind" : "may-unwind";
984 }
985
986 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +0000987 ChangeStatus updateImpl(Attributor &A) override {
988 auto Opcodes = {
989 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
990 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
991 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
992
993 auto CheckForNoUnwind = [&](Instruction &I) {
994 if (!I.mayThrow())
995 return true;
996
Johannes Doerfert12cbbab2019-08-20 06:15:50 +0000997 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
998 const auto &NoUnwindAA =
999 A.getAAFor<AANoUnwind>(*this, IRPosition::callsite_function(ICS));
1000 return NoUnwindAA.isAssumedNoUnwind();
1001 }
1002 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001003 };
1004
1005 if (!A.checkForAllInstructions(CheckForNoUnwind, *this, Opcodes))
1006 return indicatePessimisticFixpoint();
1007
1008 return ChangeStatus::UNCHANGED;
1009 }
Stefan Stipanovic53605892019-06-27 11:27:54 +00001010};
1011
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001012struct AANoUnwindFunction final : public AANoUnwindImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001013 AANoUnwindFunction(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001014
1015 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001016 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nounwind) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001017};
1018
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001019/// NoUnwind attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001020struct AANoUnwindCallSite final : AANoUnwindImpl {
1021 AANoUnwindCallSite(const IRPosition &IRP) : AANoUnwindImpl(IRP) {}
1022
1023 /// See AbstractAttribute::initialize(...).
1024 void initialize(Attributor &A) override {
1025 AANoUnwindImpl::initialize(A);
1026 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001027 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001028 indicatePessimisticFixpoint();
1029 }
1030
1031 /// See AbstractAttribute::updateImpl(...).
1032 ChangeStatus updateImpl(Attributor &A) override {
1033 // TODO: Once we have call site specific value information we can provide
1034 // call site specific liveness information and then it makes
1035 // sense to specialize attributes for call sites arguments instead of
1036 // redirecting requests to the callee argument.
1037 Function *F = getAssociatedFunction();
1038 const IRPosition &FnPos = IRPosition::function(*F);
1039 auto &FnAA = A.getAAFor<AANoUnwind>(*this, FnPos);
1040 return clampStateAndIndicateChange(
1041 getState(),
1042 static_cast<const AANoUnwind::StateType &>(FnAA.getState()));
1043 }
1044
1045 /// See AbstractAttribute::trackStatistics()
1046 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nounwind); }
1047};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001048
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001049/// --------------------- Function Return Values -------------------------------
1050
1051/// "Attribute" that collects all potential returned values and the return
1052/// instructions that they arise from.
1053///
1054/// If there is a unique returned value R, the manifest method will:
1055/// - mark R with the "returned" attribute, if R is an argument.
Johannes Doerferteccdf082019-08-05 23:35:12 +00001056class AAReturnedValuesImpl : public AAReturnedValues, public AbstractState {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001057
1058 /// Mapping of values potentially returned by the associated function to the
1059 /// return instructions that might return them.
Johannes Doerferta4a308c2019-08-26 17:51:23 +00001060 MapVector<Value *, SmallSetVector<ReturnInst *, 4>> ReturnedValues;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001061
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001062 /// Mapping to remember the number of returned values for a call site such
1063 /// that we can avoid updates if nothing changed.
1064 DenseMap<const CallBase *, unsigned> NumReturnedValuesPerKnownAA;
1065
1066 /// Set of unresolved calls returned by the associated function.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001067 SmallSetVector<CallBase *, 4> UnresolvedCalls;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001068
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001069 /// State flags
1070 ///
1071 ///{
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001072 bool IsFixed = false;
1073 bool IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001074 ///}
1075
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001076public:
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001077 AAReturnedValuesImpl(const IRPosition &IRP) : AAReturnedValues(IRP) {}
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001078
1079 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001080 void initialize(Attributor &A) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001081 // Reset the state.
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001082 IsFixed = false;
1083 IsValidState = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001084 ReturnedValues.clear();
1085
Johannes Doerfertdef99282019-08-14 21:29:37 +00001086 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001087 if (!F) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001088 indicatePessimisticFixpoint();
1089 return;
1090 }
Johannes Doerferte273ac42020-01-12 00:13:03 -06001091 assert(!F->getReturnType()->isVoidTy() &&
1092 "Did not expect a void return type!");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001093
1094 // The map from instruction opcodes to those instructions in the function.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001095 auto &OpcodeInstMap = A.getInfoCache().getOpcodeInstMapForFunction(*F);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001096
1097 // Look through all arguments, if one is marked as returned we are done.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001098 for (Argument &Arg : F->args()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001099 if (Arg.hasReturnedAttr()) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001100 auto &ReturnInstSet = ReturnedValues[&Arg];
1101 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
1102 ReturnInstSet.insert(cast<ReturnInst>(RI));
1103
1104 indicateOptimisticFixpoint();
1105 return;
1106 }
1107 }
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001108
1109 if (!F->hasExactDefinition())
1110 indicatePessimisticFixpoint();
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001111 }
1112
1113 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001114 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001115
1116 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001117 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001118
1119 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001120 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001121
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001122 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00001123 ChangeStatus updateImpl(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001124
Johannes Doerfertdef99282019-08-14 21:29:37 +00001125 llvm::iterator_range<iterator> returned_values() override {
1126 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1127 }
1128
1129 llvm::iterator_range<const_iterator> returned_values() const override {
1130 return llvm::make_range(ReturnedValues.begin(), ReturnedValues.end());
1131 }
1132
Johannes Doerfert695089e2019-08-23 15:23:49 +00001133 const SmallSetVector<CallBase *, 4> &getUnresolvedCalls() const override {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001134 return UnresolvedCalls;
1135 }
1136
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001137 /// Return the number of potential return values, -1 if unknown.
Johannes Doerfertdef99282019-08-14 21:29:37 +00001138 size_t getNumReturnValues() const override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001139 return isValidState() ? ReturnedValues.size() : -1;
1140 }
1141
1142 /// Return an assumed unique return value if a single candidate is found. If
1143 /// there cannot be one, return a nullptr. If it is not clear yet, return the
1144 /// Optional::NoneType.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001145 Optional<Value *> getAssumedUniqueReturnValue(Attributor &A) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001146
Johannes Doerfert14a04932019-08-07 22:27:24 +00001147 /// See AbstractState::checkForAllReturnedValues(...).
1148 bool checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001149 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001150 &Pred) const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001151
1152 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +00001153 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001154
1155 /// See AbstractState::isAtFixpoint().
1156 bool isAtFixpoint() const override { return IsFixed; }
1157
1158 /// See AbstractState::isValidState().
1159 bool isValidState() const override { return IsValidState; }
1160
1161 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001162 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001163 IsFixed = true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001164 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001165 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001166
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001167 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001168 IsFixed = true;
1169 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001170 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001171 }
1172};
1173
1174ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
1175 ChangeStatus Changed = ChangeStatus::UNCHANGED;
1176
1177 // Bookkeeping.
1178 assert(isValidState());
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001179 STATS_DECLTRACK(KnownReturnValues, FunctionReturn,
1180 "Number of function with known return values");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001181
1182 // Check if we have an assumed unique return value that we could manifest.
Johannes Doerfert14a04932019-08-07 22:27:24 +00001183 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(A);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001184
1185 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
1186 return Changed;
1187
1188 // Bookkeeping.
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001189 STATS_DECLTRACK(UniqueReturnValue, FunctionReturn,
1190 "Number of function with unique return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001191
Johannes Doerfert23400e612019-08-23 17:41:37 +00001192 // Callback to replace the uses of CB with the constant C.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06001193 auto ReplaceCallSiteUsersWith = [&A](CallBase &CB, Constant &C) {
Johannes Doerfert8fa56c42019-10-11 01:45:32 +00001194 if (CB.getNumUses() == 0 || CB.isMustTailCall())
Johannes Doerfert23400e612019-08-23 17:41:37 +00001195 return ChangeStatus::UNCHANGED;
Johannes Doerfert4c62a352020-01-12 00:17:08 -06001196 if (A.changeValueAfterManifest(CB, C))
1197 return ChangeStatus::CHANGED;
1198 return ChangeStatus::UNCHANGED;
Johannes Doerfert23400e612019-08-23 17:41:37 +00001199 };
1200
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001201 // If the assumed unique return value is an argument, annotate it.
1202 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05001203 // TODO: This should be handled differently!
1204 this->AnchorVal = UniqueRVArg;
1205 this->KindOrArgNo = UniqueRVArg->getArgNo();
Johannes Doerfert23400e612019-08-23 17:41:37 +00001206 Changed = IRAttribute::manifest(A);
1207 } else if (auto *RVC = dyn_cast<Constant>(UniqueRV.getValue())) {
1208 // We can replace the returned value with the unique returned constant.
1209 Value &AnchorValue = getAnchorValue();
1210 if (Function *F = dyn_cast<Function>(&AnchorValue)) {
1211 for (const Use &U : F->uses())
1212 if (CallBase *CB = dyn_cast<CallBase>(U.getUser()))
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001213 if (CB->isCallee(&U)) {
1214 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001215 CB->getType() == RVC->getType()
1216 ? RVC
1217 : ConstantExpr::getTruncOrBitCast(RVC, CB->getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001218 Changed = ReplaceCallSiteUsersWith(*CB, *RVCCast) | Changed;
1219 }
Johannes Doerfert23400e612019-08-23 17:41:37 +00001220 } else {
1221 assert(isa<CallBase>(AnchorValue) &&
1222 "Expcected a function or call base anchor!");
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001223 Constant *RVCCast =
Johannes Doerfert07d16422019-11-01 23:03:35 -05001224 AnchorValue.getType() == RVC->getType()
1225 ? RVC
1226 : ConstantExpr::getTruncOrBitCast(RVC, AnchorValue.getType());
Johannes Doerferte7c6f972019-09-14 02:57:50 +00001227 Changed = ReplaceCallSiteUsersWith(cast<CallBase>(AnchorValue), *RVCCast);
Johannes Doerfert23400e612019-08-23 17:41:37 +00001228 }
1229 if (Changed == ChangeStatus::CHANGED)
1230 STATS_DECLTRACK(UniqueConstantReturnValue, FunctionReturn,
1231 "Number of function returns replaced by constant return");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001232 }
1233
1234 return Changed;
1235}
1236
1237const std::string AAReturnedValuesImpl::getAsStr() const {
1238 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +00001239 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
Johannes Doerfertdef99282019-08-14 21:29:37 +00001240 ")[#UC: " + std::to_string(UnresolvedCalls.size()) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001241}
1242
Johannes Doerfert14a04932019-08-07 22:27:24 +00001243Optional<Value *>
1244AAReturnedValuesImpl::getAssumedUniqueReturnValue(Attributor &A) const {
1245 // If checkForAllReturnedValues provides a unique value, ignoring potential
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001246 // undef values that can also be present, it is assumed to be the actual
1247 // return value and forwarded to the caller of this method. If there are
1248 // multiple, a nullptr is returned indicating there cannot be a unique
1249 // returned value.
1250 Optional<Value *> UniqueRV;
1251
Johannes Doerfert14a04932019-08-07 22:27:24 +00001252 auto Pred = [&](Value &RV) -> bool {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001253 // If we found a second returned value and neither the current nor the saved
1254 // one is an undef, there is no unique returned value. Undefs are special
1255 // since we can pretend they have any value.
1256 if (UniqueRV.hasValue() && UniqueRV != &RV &&
1257 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
1258 UniqueRV = nullptr;
1259 return false;
1260 }
1261
1262 // Do not overwrite a value with an undef.
1263 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
1264 UniqueRV = &RV;
1265
1266 return true;
1267 };
1268
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001269 if (!A.checkForAllReturnedValues(Pred, *this))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001270 UniqueRV = nullptr;
1271
1272 return UniqueRV;
1273}
1274
Johannes Doerfert14a04932019-08-07 22:27:24 +00001275bool AAReturnedValuesImpl::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00001276 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00001277 &Pred) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001278 if (!isValidState())
1279 return false;
1280
1281 // Check all returned values but ignore call sites as long as we have not
1282 // encountered an overdefined one during an update.
1283 for (auto &It : ReturnedValues) {
1284 Value *RV = It.first;
1285
Johannes Doerfertdef99282019-08-14 21:29:37 +00001286 CallBase *CB = dyn_cast<CallBase>(RV);
1287 if (CB && !UnresolvedCalls.count(CB))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001288 continue;
1289
Johannes Doerfert695089e2019-08-23 15:23:49 +00001290 if (!Pred(*RV, It.second))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001291 return false;
1292 }
1293
1294 return true;
1295}
1296
Johannes Doerfertece81902019-08-12 22:05:53 +00001297ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001298 size_t NumUnresolvedCalls = UnresolvedCalls.size();
1299 bool Changed = false;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001300
Johannes Doerfertdef99282019-08-14 21:29:37 +00001301 // State used in the value traversals starting in returned values.
1302 struct RVState {
1303 // The map in which we collect return values -> return instrs.
1304 decltype(ReturnedValues) &RetValsMap;
1305 // The flag to indicate a change.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001306 bool &Changed;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001307 // The return instrs we come from.
Johannes Doerfert695089e2019-08-23 15:23:49 +00001308 SmallSetVector<ReturnInst *, 4> RetInsts;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001309 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001310
Johannes Doerfertdef99282019-08-14 21:29:37 +00001311 // Callback for a leaf value returned by the associated function.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001312 auto VisitValueCB = [](Value &Val, RVState &RVS, bool) -> bool {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001313 auto Size = RVS.RetValsMap[&Val].size();
1314 RVS.RetValsMap[&Val].insert(RVS.RetInsts.begin(), RVS.RetInsts.end());
1315 bool Inserted = RVS.RetValsMap[&Val].size() != Size;
1316 RVS.Changed |= Inserted;
1317 LLVM_DEBUG({
1318 if (Inserted)
1319 dbgs() << "[AAReturnedValues] 1 Add new returned value " << Val
1320 << " => " << RVS.RetInsts.size() << "\n";
1321 });
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001322 return true;
Johannes Doerfertdef99282019-08-14 21:29:37 +00001323 };
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001324
Johannes Doerfertdef99282019-08-14 21:29:37 +00001325 // Helper method to invoke the generic value traversal.
1326 auto VisitReturnedValue = [&](Value &RV, RVState &RVS) {
1327 IRPosition RetValPos = IRPosition::value(RV);
1328 return genericValueTraversal<AAReturnedValues, RVState>(A, RetValPos, *this,
1329 RVS, VisitValueCB);
1330 };
Johannes Doerfertda4d8112019-08-01 16:21:54 +00001331
Johannes Doerfertdef99282019-08-14 21:29:37 +00001332 // Callback for all "return intructions" live in the associated function.
1333 auto CheckReturnInst = [this, &VisitReturnedValue, &Changed](Instruction &I) {
1334 ReturnInst &Ret = cast<ReturnInst>(I);
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001335 RVState RVS({ReturnedValues, Changed, {}});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001336 RVS.RetInsts.insert(&Ret);
Johannes Doerfertdef99282019-08-14 21:29:37 +00001337 return VisitReturnedValue(*Ret.getReturnValue(), RVS);
1338 };
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001339
Johannes Doerfertdef99282019-08-14 21:29:37 +00001340 // Start by discovering returned values from all live returned instructions in
1341 // the associated function.
1342 if (!A.checkForAllInstructions(CheckReturnInst, *this, {Instruction::Ret}))
1343 return indicatePessimisticFixpoint();
1344
1345 // Once returned values "directly" present in the code are handled we try to
1346 // resolve returned calls.
1347 decltype(ReturnedValues) NewRVsMap;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001348 for (auto &It : ReturnedValues) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001349 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned value: " << *It.first
1350 << " by #" << It.second.size() << " RIs\n");
1351 CallBase *CB = dyn_cast<CallBase>(It.first);
1352 if (!CB || UnresolvedCalls.count(CB))
1353 continue;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001354
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001355 if (!CB->getCalledFunction()) {
1356 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1357 << "\n");
1358 UnresolvedCalls.insert(CB);
1359 continue;
1360 }
1361
1362 // TODO: use the function scope once we have call site AAReturnedValues.
1363 const auto &RetValAA = A.getAAFor<AAReturnedValues>(
1364 *this, IRPosition::function(*CB->getCalledFunction()));
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001365 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Found another AAReturnedValues: "
Johannes Doerfert3d347e22019-12-13 23:35:45 -06001366 << RetValAA << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001367
1368 // Skip dead ends, thus if we do not know anything about the returned
1369 // call we mark it as unresolved and it will stay that way.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001370 if (!RetValAA.getState().isValidState()) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00001371 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Unresolved call: " << *CB
1372 << "\n");
1373 UnresolvedCalls.insert(CB);
1374 continue;
1375 }
1376
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001377 // Do not try to learn partial information. If the callee has unresolved
1378 // return values we will treat the call as unresolved/opaque.
1379 auto &RetValAAUnresolvedCalls = RetValAA.getUnresolvedCalls();
1380 if (!RetValAAUnresolvedCalls.empty()) {
1381 UnresolvedCalls.insert(CB);
1382 continue;
1383 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001384
Johannes Doerfertde7674c2019-08-19 21:35:31 +00001385 // Now check if we can track transitively returned values. If possible, thus
1386 // if all return value can be represented in the current scope, do so.
1387 bool Unresolved = false;
1388 for (auto &RetValAAIt : RetValAA.returned_values()) {
1389 Value *RetVal = RetValAAIt.first;
1390 if (isa<Argument>(RetVal) || isa<CallBase>(RetVal) ||
1391 isa<Constant>(RetVal))
1392 continue;
1393 // Anything that did not fit in the above categories cannot be resolved,
1394 // mark the call as unresolved.
1395 LLVM_DEBUG(dbgs() << "[AAReturnedValues] transitively returned value "
1396 "cannot be translated: "
1397 << *RetVal << "\n");
1398 UnresolvedCalls.insert(CB);
1399 Unresolved = true;
1400 break;
1401 }
1402
1403 if (Unresolved)
1404 continue;
1405
Johannes Doerfertdeb9ea32019-08-23 15:42:19 +00001406 // Now track transitively returned values.
1407 unsigned &NumRetAA = NumReturnedValuesPerKnownAA[CB];
1408 if (NumRetAA == RetValAA.getNumReturnValues()) {
1409 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Skip call as it has not "
1410 "changed since it was seen last\n");
1411 continue;
1412 }
1413 NumRetAA = RetValAA.getNumReturnValues();
1414
Johannes Doerfertdef99282019-08-14 21:29:37 +00001415 for (auto &RetValAAIt : RetValAA.returned_values()) {
1416 Value *RetVal = RetValAAIt.first;
1417 if (Argument *Arg = dyn_cast<Argument>(RetVal)) {
1418 // Arguments are mapped to call site operands and we begin the traversal
1419 // again.
Johannes Doerfert056f1b52019-08-19 19:14:10 +00001420 bool Unused = false;
1421 RVState RVS({NewRVsMap, Unused, RetValAAIt.second});
Johannes Doerfertdef99282019-08-14 21:29:37 +00001422 VisitReturnedValue(*CB->getArgOperand(Arg->getArgNo()), RVS);
1423 continue;
1424 } else if (isa<CallBase>(RetVal)) {
1425 // Call sites are resolved by the callee attribute over time, no need to
1426 // do anything for us.
1427 continue;
1428 } else if (isa<Constant>(RetVal)) {
1429 // Constants are valid everywhere, we can simply take them.
1430 NewRVsMap[RetVal].insert(It.second.begin(), It.second.end());
1431 continue;
1432 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001433 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001434 }
1435
Johannes Doerfertdef99282019-08-14 21:29:37 +00001436 // To avoid modifications to the ReturnedValues map while we iterate over it
1437 // we kept record of potential new entries in a copy map, NewRVsMap.
1438 for (auto &It : NewRVsMap) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001439 assert(!It.second.empty() && "Entry does not add anything.");
1440 auto &ReturnInsts = ReturnedValues[It.first];
1441 for (ReturnInst *RI : It.second)
Johannes Doerfert695089e2019-08-23 15:23:49 +00001442 if (ReturnInsts.insert(RI)) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001443 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
1444 << *It.first << " => " << *RI << "\n");
Johannes Doerfertdef99282019-08-14 21:29:37 +00001445 Changed = true;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001446 }
1447 }
1448
Johannes Doerfertdef99282019-08-14 21:29:37 +00001449 Changed |= (NumUnresolvedCalls != UnresolvedCalls.size());
1450 return Changed ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00001451}
1452
Johannes Doerfertdef99282019-08-14 21:29:37 +00001453struct AAReturnedValuesFunction final : public AAReturnedValuesImpl {
1454 AAReturnedValuesFunction(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1455
1456 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001457 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(returned) }
Johannes Doerfertdef99282019-08-14 21:29:37 +00001458};
1459
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001460/// Returned values information for a call sites.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001461struct AAReturnedValuesCallSite final : AAReturnedValuesImpl {
1462 AAReturnedValuesCallSite(const IRPosition &IRP) : AAReturnedValuesImpl(IRP) {}
1463
1464 /// See AbstractAttribute::initialize(...).
1465 void initialize(Attributor &A) override {
1466 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001467 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00001468 // sense to specialize attributes for call sites instead of
1469 // redirecting requests to the callee.
1470 llvm_unreachable("Abstract attributes for returned values are not "
1471 "supported for call sites yet!");
1472 }
1473
1474 /// See AbstractAttribute::updateImpl(...).
1475 ChangeStatus updateImpl(Attributor &A) override {
1476 return indicatePessimisticFixpoint();
1477 }
1478
1479 /// See AbstractAttribute::trackStatistics()
1480 void trackStatistics() const override {}
1481};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001482
Stefan Stipanovic06263672019-07-11 21:37:40 +00001483/// ------------------------ NoSync Function Attribute -------------------------
1484
Johannes Doerfert344d0382019-08-07 22:34:26 +00001485struct AANoSyncImpl : AANoSync {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001486 AANoSyncImpl(const IRPosition &IRP) : AANoSync(IRP) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +00001487
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +00001488 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001489 return getAssumed() ? "nosync" : "may-sync";
1490 }
1491
1492 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00001493 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001494
Stefan Stipanovic06263672019-07-11 21:37:40 +00001495 /// Helper function used to determine whether an instruction is non-relaxed
1496 /// atomic. In other words, if an atomic instruction does not have unordered
1497 /// or monotonic ordering
1498 static bool isNonRelaxedAtomic(Instruction *I);
1499
1500 /// Helper function used to determine whether an instruction is volatile.
1501 static bool isVolatile(Instruction *I);
1502
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001503 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
1504 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +00001505 static bool isNoSyncIntrinsic(Instruction *I);
1506};
1507
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001508bool AANoSyncImpl::isNonRelaxedAtomic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001509 if (!I->isAtomic())
1510 return false;
1511
1512 AtomicOrdering Ordering;
1513 switch (I->getOpcode()) {
1514 case Instruction::AtomicRMW:
1515 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
1516 break;
1517 case Instruction::Store:
1518 Ordering = cast<StoreInst>(I)->getOrdering();
1519 break;
1520 case Instruction::Load:
1521 Ordering = cast<LoadInst>(I)->getOrdering();
1522 break;
1523 case Instruction::Fence: {
1524 auto *FI = cast<FenceInst>(I);
1525 if (FI->getSyncScopeID() == SyncScope::SingleThread)
1526 return false;
1527 Ordering = FI->getOrdering();
1528 break;
1529 }
1530 case Instruction::AtomicCmpXchg: {
1531 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
1532 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
1533 // Only if both are relaxed, than it can be treated as relaxed.
1534 // Otherwise it is non-relaxed.
1535 if (Success != AtomicOrdering::Unordered &&
1536 Success != AtomicOrdering::Monotonic)
1537 return true;
1538 if (Failure != AtomicOrdering::Unordered &&
1539 Failure != AtomicOrdering::Monotonic)
1540 return true;
1541 return false;
1542 }
1543 default:
1544 llvm_unreachable(
1545 "New atomic operations need to be known in the attributor.");
1546 }
1547
1548 // Relaxed.
1549 if (Ordering == AtomicOrdering::Unordered ||
1550 Ordering == AtomicOrdering::Monotonic)
1551 return false;
1552 return true;
1553}
1554
1555/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
1556/// FIXME: We should ipmrove the handling of intrinsics.
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001557bool AANoSyncImpl::isNoSyncIntrinsic(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001558 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
1559 switch (II->getIntrinsicID()) {
1560 /// Element wise atomic memory intrinsics are can only be unordered,
1561 /// therefore nosync.
1562 case Intrinsic::memset_element_unordered_atomic:
1563 case Intrinsic::memmove_element_unordered_atomic:
1564 case Intrinsic::memcpy_element_unordered_atomic:
1565 return true;
1566 case Intrinsic::memset:
1567 case Intrinsic::memmove:
1568 case Intrinsic::memcpy:
1569 if (!cast<MemIntrinsic>(II)->isVolatile())
1570 return true;
1571 return false;
1572 default:
1573 return false;
1574 }
1575 }
1576 return false;
1577}
1578
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001579bool AANoSyncImpl::isVolatile(Instruction *I) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001580 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
1581 "Calls should not be checked here");
1582
1583 switch (I->getOpcode()) {
1584 case Instruction::AtomicRMW:
1585 return cast<AtomicRMWInst>(I)->isVolatile();
1586 case Instruction::Store:
1587 return cast<StoreInst>(I)->isVolatile();
1588 case Instruction::Load:
1589 return cast<LoadInst>(I)->isVolatile();
1590 case Instruction::AtomicCmpXchg:
1591 return cast<AtomicCmpXchgInst>(I)->isVolatile();
1592 default:
1593 return false;
1594 }
1595}
1596
Johannes Doerfertece81902019-08-12 22:05:53 +00001597ChangeStatus AANoSyncImpl::updateImpl(Attributor &A) {
Stefan Stipanovic06263672019-07-11 21:37:40 +00001598
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001599 auto CheckRWInstForNoSync = [&](Instruction &I) {
1600 /// We are looking for volatile instructions or Non-Relaxed atomics.
Pankaj Godeb9a26a82019-11-22 14:46:43 +05301601 /// FIXME: We should improve the handling of intrinsics.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001602
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001603 if (isa<IntrinsicInst>(&I) && isNoSyncIntrinsic(&I))
1604 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001605
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001606 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
1607 if (ICS.hasFnAttr(Attribute::NoSync))
1608 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001609
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001610 const auto &NoSyncAA =
1611 A.getAAFor<AANoSync>(*this, IRPosition::callsite_function(ICS));
1612 if (NoSyncAA.isAssumedNoSync())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001613 return true;
1614 return false;
1615 }
Stefan Stipanovic06263672019-07-11 21:37:40 +00001616
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001617 if (!isVolatile(&I) && !isNonRelaxedAtomic(&I))
1618 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001619
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001620 return false;
1621 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001622
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001623 auto CheckForNoSync = [&](Instruction &I) {
1624 // At this point we handled all read/write effects and they are all
1625 // nosync, so they can be skipped.
1626 if (I.mayReadOrWriteMemory())
1627 return true;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001628
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001629 // non-convergent and readnone imply nosync.
1630 return !ImmutableCallSite(&I).isConvergent();
1631 };
Stefan Stipanovic06263672019-07-11 21:37:40 +00001632
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001633 if (!A.checkForAllReadWriteInstructions(CheckRWInstForNoSync, *this) ||
1634 !A.checkForAllCallLikeInstructions(CheckForNoSync, *this))
Johannes Doerfertd0f64002019-08-06 00:32:43 +00001635 return indicatePessimisticFixpoint();
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00001636
Stefan Stipanovic06263672019-07-11 21:37:40 +00001637 return ChangeStatus::UNCHANGED;
1638}
1639
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001640struct AANoSyncFunction final : public AANoSyncImpl {
1641 AANoSyncFunction(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1642
1643 /// See AbstractAttribute::trackStatistics()
1644 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nosync) }
1645};
1646
1647/// NoSync attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001648struct AANoSyncCallSite final : AANoSyncImpl {
1649 AANoSyncCallSite(const IRPosition &IRP) : AANoSyncImpl(IRP) {}
1650
1651 /// See AbstractAttribute::initialize(...).
1652 void initialize(Attributor &A) override {
1653 AANoSyncImpl::initialize(A);
1654 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001655 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001656 indicatePessimisticFixpoint();
1657 }
1658
1659 /// See AbstractAttribute::updateImpl(...).
1660 ChangeStatus updateImpl(Attributor &A) override {
1661 // TODO: Once we have call site specific value information we can provide
1662 // call site specific liveness information and then it makes
1663 // sense to specialize attributes for call sites arguments instead of
1664 // redirecting requests to the callee argument.
1665 Function *F = getAssociatedFunction();
1666 const IRPosition &FnPos = IRPosition::function(*F);
1667 auto &FnAA = A.getAAFor<AANoSync>(*this, FnPos);
1668 return clampStateAndIndicateChange(
1669 getState(), static_cast<const AANoSync::StateType &>(FnAA.getState()));
1670 }
1671
1672 /// See AbstractAttribute::trackStatistics()
1673 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nosync); }
1674};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001675
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001676/// ------------------------ No-Free Attributes ----------------------------
1677
Johannes Doerfert344d0382019-08-07 22:34:26 +00001678struct AANoFreeImpl : public AANoFree {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001679 AANoFreeImpl(const IRPosition &IRP) : AANoFree(IRP) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001680
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001681 /// See AbstractAttribute::updateImpl(...).
1682 ChangeStatus updateImpl(Attributor &A) override {
1683 auto CheckForNoFree = [&](Instruction &I) {
1684 ImmutableCallSite ICS(&I);
1685 if (ICS.hasFnAttr(Attribute::NoFree))
1686 return true;
1687
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001688 const auto &NoFreeAA =
1689 A.getAAFor<AANoFree>(*this, IRPosition::callsite_function(ICS));
1690 return NoFreeAA.isAssumedNoFree();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001691 };
1692
1693 if (!A.checkForAllCallLikeInstructions(CheckForNoFree, *this))
1694 return indicatePessimisticFixpoint();
1695 return ChangeStatus::UNCHANGED;
1696 }
1697
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001698 /// See AbstractAttribute::getAsStr().
1699 const std::string getAsStr() const override {
1700 return getAssumed() ? "nofree" : "may-free";
1701 }
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001702};
1703
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001704struct AANoFreeFunction final : public AANoFreeImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001705 AANoFreeFunction(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00001706
1707 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00001708 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(nofree) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00001709};
1710
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001711/// NoFree attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001712struct AANoFreeCallSite final : AANoFreeImpl {
1713 AANoFreeCallSite(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1714
1715 /// See AbstractAttribute::initialize(...).
1716 void initialize(Attributor &A) override {
1717 AANoFreeImpl::initialize(A);
1718 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001719 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00001720 indicatePessimisticFixpoint();
1721 }
1722
1723 /// See AbstractAttribute::updateImpl(...).
1724 ChangeStatus updateImpl(Attributor &A) override {
1725 // TODO: Once we have call site specific value information we can provide
1726 // call site specific liveness information and then it makes
1727 // sense to specialize attributes for call sites arguments instead of
1728 // redirecting requests to the callee argument.
1729 Function *F = getAssociatedFunction();
1730 const IRPosition &FnPos = IRPosition::function(*F);
1731 auto &FnAA = A.getAAFor<AANoFree>(*this, FnPos);
1732 return clampStateAndIndicateChange(
1733 getState(), static_cast<const AANoFree::StateType &>(FnAA.getState()));
1734 }
1735
1736 /// See AbstractAttribute::trackStatistics()
1737 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(nofree); }
1738};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00001739
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001740/// NoFree attribute for floating values.
1741struct AANoFreeFloating : AANoFreeImpl {
1742 AANoFreeFloating(const IRPosition &IRP) : AANoFreeImpl(IRP) {}
1743
1744 /// See AbstractAttribute::trackStatistics()
1745 void trackStatistics() const override{STATS_DECLTRACK_FLOATING_ATTR(nofree)}
1746
1747 /// See Abstract Attribute::updateImpl(...).
1748 ChangeStatus updateImpl(Attributor &A) override {
1749 const IRPosition &IRP = getIRPosition();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001750
1751 const auto &NoFreeAA =
1752 A.getAAFor<AANoFree>(*this, IRPosition::function_scope(IRP));
1753 if (NoFreeAA.isAssumedNoFree())
1754 return ChangeStatus::UNCHANGED;
1755
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001756 Value &AssociatedValue = getIRPosition().getAssociatedValue();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001757 auto Pred = [&](const Use &U, bool &Follow) -> bool {
1758 Instruction *UserI = cast<Instruction>(U.getUser());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001759 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001760 if (CB->isBundleOperand(&U))
1761 return false;
1762 if (!CB->isArgOperand(&U))
1763 return true;
1764 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001765
1766 const auto &NoFreeArg = A.getAAFor<AANoFree>(
1767 *this, IRPosition::callsite_argument(*CB, ArgNo));
Hideto Ueno63599bd2019-12-12 12:26:09 +00001768 return NoFreeArg.isAssumedNoFree();
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001769 }
1770
1771 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
1772 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
Hideto Ueno63599bd2019-12-12 12:26:09 +00001773 Follow = true;
1774 return true;
Hideto Ueno4ecf2552019-12-12 13:42:40 +00001775 }
Johannes Doerfertf9555392020-01-10 14:49:45 -06001776 if (isa<ReturnInst>(UserI))
1777 return true;
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001778
1779 // Unknown user.
Hideto Ueno63599bd2019-12-12 12:26:09 +00001780 return false;
1781 };
1782 if (!A.checkForAllUses(Pred, *this, AssociatedValue))
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001783 return indicatePessimisticFixpoint();
Hideto Ueno63599bd2019-12-12 12:26:09 +00001784
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001785 return ChangeStatus::UNCHANGED;
1786 }
1787};
1788
1789/// NoFree attribute for a call site argument.
1790struct AANoFreeArgument final : AANoFreeFloating {
1791 AANoFreeArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1792
1793 /// See AbstractAttribute::trackStatistics()
1794 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nofree) }
1795};
1796
1797/// NoFree attribute for call site arguments.
1798struct AANoFreeCallSiteArgument final : AANoFreeFloating {
1799 AANoFreeCallSiteArgument(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1800
1801 /// See AbstractAttribute::updateImpl(...).
1802 ChangeStatus updateImpl(Attributor &A) override {
1803 // TODO: Once we have call site specific value information we can provide
1804 // call site specific liveness information and then it makes
1805 // sense to specialize attributes for call sites arguments instead of
1806 // redirecting requests to the callee argument.
1807 Argument *Arg = getAssociatedArgument();
1808 if (!Arg)
1809 return indicatePessimisticFixpoint();
1810 const IRPosition &ArgPos = IRPosition::argument(*Arg);
1811 auto &ArgAA = A.getAAFor<AANoFree>(*this, ArgPos);
1812 return clampStateAndIndicateChange(
1813 getState(), static_cast<const AANoFree::StateType &>(ArgAA.getState()));
1814 }
1815
1816 /// See AbstractAttribute::trackStatistics()
1817 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nofree)};
1818};
1819
1820/// NoFree attribute for function return value.
1821struct AANoFreeReturned final : AANoFreeFloating {
1822 AANoFreeReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {
1823 llvm_unreachable("NoFree is not applicable to function returns!");
1824 }
1825
1826 /// See AbstractAttribute::initialize(...).
1827 void initialize(Attributor &A) override {
1828 llvm_unreachable("NoFree is not applicable to function returns!");
1829 }
1830
1831 /// See AbstractAttribute::updateImpl(...).
1832 ChangeStatus updateImpl(Attributor &A) override {
1833 llvm_unreachable("NoFree is not applicable to function returns!");
1834 }
1835
1836 /// See AbstractAttribute::trackStatistics()
1837 void trackStatistics() const override {}
1838};
1839
1840/// NoFree attribute deduction for a call site return value.
1841struct AANoFreeCallSiteReturned final : AANoFreeFloating {
1842 AANoFreeCallSiteReturned(const IRPosition &IRP) : AANoFreeFloating(IRP) {}
1843
1844 ChangeStatus manifest(Attributor &A) override {
1845 return ChangeStatus::UNCHANGED;
1846 }
1847 /// See AbstractAttribute::trackStatistics()
1848 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nofree) }
1849};
1850
Hideto Ueno54869ec2019-07-15 06:49:04 +00001851/// ------------------------ NonNull Argument Attribute ------------------------
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001852static int64_t getKnownNonNullAndDerefBytesForUse(
1853 Attributor &A, AbstractAttribute &QueryingAA, Value &AssociatedValue,
1854 const Use *U, const Instruction *I, bool &IsNonNull, bool &TrackUse) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001855 TrackUse = false;
1856
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001857 const Value *UseV = U->get();
1858 if (!UseV->getType()->isPointerTy())
1859 return 0;
1860
1861 Type *PtrTy = UseV->getType();
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001862 const Function *F = I->getFunction();
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001863 bool NullPointerIsDefined =
1864 F ? llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()) : true;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001865 const DataLayout &DL = A.getInfoCache().getDL();
1866 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
1867 if (ICS.isBundleOperand(U))
1868 return 0;
1869
1870 if (ICS.isCallee(U)) {
1871 IsNonNull |= !NullPointerIsDefined;
1872 return 0;
1873 }
1874
1875 unsigned ArgNo = ICS.getArgumentNo(U);
1876 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
Johannes Doerfert77a6b352019-11-02 14:47:45 -05001877 // As long as we only use known information there is no need to track
1878 // dependences here.
1879 auto &DerefAA = A.getAAFor<AADereferenceable>(QueryingAA, IRP,
1880 /* TrackDependence */ false);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001881 IsNonNull |= DerefAA.isKnownNonNull();
1882 return DerefAA.getKnownDereferenceableBytes();
1883 }
1884
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001885 // We need to follow common pointer manipulation uses to the accesses they
1886 // feed into. We can try to be smart to avoid looking through things we do not
1887 // like for now, e.g., non-inbounds GEPs.
1888 if (isa<CastInst>(I)) {
1889 TrackUse = true;
1890 return 0;
1891 }
1892 if (auto *GEP = dyn_cast<GetElementPtrInst>(I))
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001893 if (GEP->hasAllConstantIndices()) {
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001894 TrackUse = true;
1895 return 0;
1896 }
1897
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001898 int64_t Offset;
1899 if (const Value *Base = getBasePointerOfAccessPointerOperand(I, Offset, DL)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09001900 if (Base == &AssociatedValue &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06001901 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001902 int64_t DerefBytes =
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001903 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType()) + Offset;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001904
1905 IsNonNull |= !NullPointerIsDefined;
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001906 return std::max(int64_t(0), DerefBytes);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001907 }
1908 }
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001909
1910 /// Corner case when an offset is 0.
1911 if (const Value *Base = getBasePointerOfAccessPointerOperand(
1912 I, Offset, DL, /*AllowNonInbounds*/ true)) {
1913 if (Offset == 0 && Base == &AssociatedValue &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06001914 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno0f4383f2019-11-27 14:41:12 +00001915 int64_t DerefBytes =
1916 (int64_t)DL.getTypeStoreSize(PtrTy->getPointerElementType());
1917 IsNonNull |= !NullPointerIsDefined;
1918 return std::max(int64_t(0), DerefBytes);
1919 }
1920 }
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001921
1922 return 0;
1923}
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00001924
Johannes Doerfert344d0382019-08-07 22:34:26 +00001925struct AANonNullImpl : AANonNull {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001926 AANonNullImpl(const IRPosition &IRP)
1927 : AANonNull(IRP),
1928 NullIsDefined(NullPointerIsDefined(
1929 getAnchorScope(),
1930 getAssociatedValue().getType()->getPointerAddressSpace())) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001931
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001932 /// See AbstractAttribute::initialize(...).
1933 void initialize(Attributor &A) override {
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001934 if (!NullIsDefined &&
1935 hasAttr({Attribute::NonNull, Attribute::Dereferenceable}))
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001936 indicateOptimisticFixpoint();
Johannes Doerferteb4f41d2019-10-30 17:21:53 -05001937 else if (isa<ConstantPointerNull>(getAssociatedValue()))
1938 indicatePessimisticFixpoint();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00001939 else
1940 AANonNull::initialize(A);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00001941 }
1942
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001943 /// See AAFromMustBeExecutedContext
1944 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
1945 bool IsNonNull = false;
1946 bool TrackUse = false;
1947 getKnownNonNullAndDerefBytesForUse(A, *this, getAssociatedValue(), U, I,
1948 IsNonNull, TrackUse);
Johannes Doerfert1a746452019-10-20 22:28:49 -05001949 setKnown(IsNonNull);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001950 return TrackUse;
1951 }
1952
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001953 /// See AbstractAttribute::getAsStr().
1954 const std::string getAsStr() const override {
1955 return getAssumed() ? "nonnull" : "may-null";
1956 }
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001957
1958 /// Flag to determine if the underlying value can be null and still allow
1959 /// valid accesses.
1960 const bool NullIsDefined;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001961};
1962
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001963/// NonNull attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001964struct AANonNullFloating
1965 : AAFromMustBeExecutedContext<AANonNull, AANonNullImpl> {
1966 using Base = AAFromMustBeExecutedContext<AANonNull, AANonNullImpl>;
1967 AANonNullFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001968
Hideto Ueno54869ec2019-07-15 06:49:04 +00001969 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001970 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00001971 ChangeStatus Change = Base::updateImpl(A);
1972 if (isKnownNonNull())
1973 return Change;
1974
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001975 if (!NullIsDefined) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01001976 const auto &DerefAA =
1977 A.getAAFor<AADereferenceable>(*this, getIRPosition());
Johannes Doerfertd82385b2019-10-13 20:48:26 +00001978 if (DerefAA.getAssumedDereferenceableBytes())
1979 return Change;
1980 }
1981
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001982 const DataLayout &DL = A.getDataLayout();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00001983
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001984 DominatorTree *DT = nullptr;
1985 InformationCache &InfoCache = A.getInfoCache();
1986 if (const Function *Fn = getAnchorScope())
1987 DT = InfoCache.getAnalysisResultForFunction<DominatorTreeAnalysis>(*Fn);
1988
Johannes Doerfert1a746452019-10-20 22:28:49 -05001989 auto VisitValueCB = [&](Value &V, AANonNull::StateType &T,
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001990 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001991 const auto &AA = A.getAAFor<AANonNull>(*this, IRPosition::value(V));
1992 if (!Stripped && this == &AA) {
Johannes Doerfert2d6d6512019-10-29 11:46:00 -05001993 if (!isKnownNonZero(&V, DL, 0, /* TODO: AC */ nullptr, getCtxI(), DT))
Johannes Doerfertb9b87912019-08-20 06:02:39 +00001994 T.indicatePessimisticFixpoint();
1995 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00001996 // Use abstract attribute information.
1997 const AANonNull::StateType &NS =
1998 static_cast<const AANonNull::StateType &>(AA.getState());
1999 T ^= NS;
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002000 }
2001 return T.isValidState();
2002 };
2003
2004 StateType T;
2005 if (!genericValueTraversal<AANonNull, StateType>(A, getIRPosition(), *this,
2006 T, VisitValueCB))
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002007 return indicatePessimisticFixpoint();
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002008
2009 return clampStateAndIndicateChange(getState(), T);
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002010 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002011
2012 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002013 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002014};
2015
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002016/// NonNull attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002017struct AANonNullReturned final
2018 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002019 AANonNullReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002020 : AAReturnedFromReturnedValues<AANonNull, AANonNullImpl>(IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002021
2022 /// See AbstractAttribute::trackStatistics()
2023 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(nonnull) }
2024};
2025
Hideto Ueno54869ec2019-07-15 06:49:04 +00002026/// NonNull attribute for function argument.
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002027struct AANonNullArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002028 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
2029 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002030 AANonNullArgument(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002031 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AANonNull,
2032 AANonNullImpl>(
2033 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002034
2035 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002036 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002037};
2038
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002039struct AANonNullCallSiteArgument final : AANonNullFloating {
2040 AANonNullCallSiteArgument(const IRPosition &IRP) : AANonNullFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002041
2042 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert1aac1822019-08-29 01:26:09 +00002043 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(nonnull) }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002044};
Johannes Doerfert007153e2019-08-05 23:26:06 +00002045
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002046/// NonNull attribute for a call site return position.
2047struct AANonNullCallSiteReturned final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002048 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
2049 AANonNullImpl> {
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002050 AANonNullCallSiteReturned(const IRPosition &IRP)
Hideto Ueno96e6ce42019-10-08 15:25:56 +00002051 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AANonNull,
2052 AANonNullImpl>(
2053 IRP) {}
Johannes Doerfertb9b87912019-08-20 06:02:39 +00002054
2055 /// See AbstractAttribute::trackStatistics()
2056 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(nonnull) }
2057};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002058
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002059/// ------------------------ No-Recurse Attributes ----------------------------
2060
2061struct AANoRecurseImpl : public AANoRecurse {
2062 AANoRecurseImpl(const IRPosition &IRP) : AANoRecurse(IRP) {}
2063
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002064 /// See AbstractAttribute::getAsStr()
2065 const std::string getAsStr() const override {
2066 return getAssumed() ? "norecurse" : "may-recurse";
2067 }
2068};
2069
2070struct AANoRecurseFunction final : AANoRecurseImpl {
2071 AANoRecurseFunction(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2072
Hideto Ueno63f60662019-09-21 15:13:19 +00002073 /// See AbstractAttribute::initialize(...).
2074 void initialize(Attributor &A) override {
2075 AANoRecurseImpl::initialize(A);
2076 if (const Function *F = getAnchorScope())
Johannes Doerfert26d02b02019-12-30 16:15:38 -06002077 if (A.getInfoCache().getSccSize(*F) != 1)
2078 indicatePessimisticFixpoint();
Hideto Ueno63f60662019-09-21 15:13:19 +00002079 }
2080
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002081 /// See AbstractAttribute::updateImpl(...).
2082 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno63f60662019-09-21 15:13:19 +00002083
Johannes Doerfert26d02b02019-12-30 16:15:38 -06002084 // If all live call sites are known to be no-recurse, we are as well.
2085 auto CallSitePred = [&](AbstractCallSite ACS) {
2086 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(
2087 *this, IRPosition::function(*ACS.getInstruction()->getFunction()),
2088 /* TrackDependence */ false, DepClassTy::OPTIONAL);
2089 return NoRecurseAA.isKnownNoRecurse();
2090 };
2091 bool AllCallSitesKnown;
2092 if (A.checkForAllCallSites(CallSitePred, *this, true, AllCallSitesKnown)) {
2093 // If we know all call sites and all are known no-recurse, we are done.
2094 // If all known call sites, which might not be all that exist, are known
2095 // to be no-recurse, we are not done but we can continue to assume
2096 // no-recurse. If one of the call sites we have not visited will become
2097 // live, another update is triggered.
2098 if (AllCallSitesKnown)
2099 indicateOptimisticFixpoint();
2100 return ChangeStatus::UNCHANGED;
2101 }
2102
2103 // If the above check does not hold anymore we look at the calls.
Hideto Ueno63f60662019-09-21 15:13:19 +00002104 auto CheckForNoRecurse = [&](Instruction &I) {
2105 ImmutableCallSite ICS(&I);
2106 if (ICS.hasFnAttr(Attribute::NoRecurse))
2107 return true;
2108
2109 const auto &NoRecurseAA =
2110 A.getAAFor<AANoRecurse>(*this, IRPosition::callsite_function(ICS));
2111 if (!NoRecurseAA.isAssumedNoRecurse())
2112 return false;
2113
2114 // Recursion to the same function
2115 if (ICS.getCalledFunction() == getAnchorScope())
2116 return false;
2117
2118 return true;
2119 };
2120
2121 if (!A.checkForAllCallLikeInstructions(CheckForNoRecurse, *this))
2122 return indicatePessimisticFixpoint();
2123 return ChangeStatus::UNCHANGED;
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002124 }
2125
2126 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(norecurse) }
2127};
2128
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002129/// NoRecurse attribute deduction for a call sites.
2130struct AANoRecurseCallSite final : AANoRecurseImpl {
2131 AANoRecurseCallSite(const IRPosition &IRP) : AANoRecurseImpl(IRP) {}
2132
2133 /// See AbstractAttribute::initialize(...).
2134 void initialize(Attributor &A) override {
2135 AANoRecurseImpl::initialize(A);
2136 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002137 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002138 indicatePessimisticFixpoint();
2139 }
2140
2141 /// See AbstractAttribute::updateImpl(...).
2142 ChangeStatus updateImpl(Attributor &A) override {
2143 // TODO: Once we have call site specific value information we can provide
2144 // call site specific liveness information and then it makes
2145 // sense to specialize attributes for call sites arguments instead of
2146 // redirecting requests to the callee argument.
2147 Function *F = getAssociatedFunction();
2148 const IRPosition &FnPos = IRPosition::function(*F);
2149 auto &FnAA = A.getAAFor<AANoRecurse>(*this, FnPos);
2150 return clampStateAndIndicateChange(
2151 getState(),
2152 static_cast<const AANoRecurse::StateType &>(FnAA.getState()));
2153 }
2154
2155 /// See AbstractAttribute::trackStatistics()
2156 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(norecurse); }
2157};
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002158
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002159/// -------------------- Undefined-Behavior Attributes ------------------------
2160
2161struct AAUndefinedBehaviorImpl : public AAUndefinedBehavior {
2162 AAUndefinedBehaviorImpl(const IRPosition &IRP) : AAUndefinedBehavior(IRP) {}
2163
2164 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert5732f562019-12-24 19:25:08 -06002165 // through a pointer (i.e. also branches etc.)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002166 ChangeStatus updateImpl(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002167 const size_t UBPrevSize = KnownUBInsts.size();
2168 const size_t NoUBPrevSize = AssumedNoUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002169
Johannes Doerfert5732f562019-12-24 19:25:08 -06002170 auto InspectMemAccessInstForUB = [&](Instruction &I) {
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002171 // Skip instructions that are already saved.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002172 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002173 return true;
2174
Hideto Uenoef4febd2019-12-29 17:34:08 +09002175 // If we reach here, we know we have an instruction
2176 // that accesses memory through a pointer operand,
2177 // for which getPointerOperand() should give it to us.
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06002178 const Value *PtrOp = getPointerOperand(&I, /* AllowVolatile */ true);
Hideto Uenoef4febd2019-12-29 17:34:08 +09002179 assert(PtrOp &&
2180 "Expected pointer operand of memory accessing instruction");
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002181
Johannes Doerfert5732f562019-12-24 19:25:08 -06002182 // A memory access through a pointer is considered UB
2183 // only if the pointer has constant null value.
2184 // TODO: Expand it to not only check constant values.
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002185 if (!isa<ConstantPointerNull>(PtrOp)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002186 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002187 return true;
2188 }
Johannes Doerfert5732f562019-12-24 19:25:08 -06002189 const Type *PtrTy = PtrOp->getType();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002190
Johannes Doerfert5732f562019-12-24 19:25:08 -06002191 // Because we only consider instructions inside functions,
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002192 // assume that a parent function exists.
2193 const Function *F = I.getFunction();
2194
Johannes Doerfert5732f562019-12-24 19:25:08 -06002195 // A memory access using constant null pointer is only considered UB
2196 // if null pointer is _not_ defined for the target platform.
Hideto Uenoef4febd2019-12-29 17:34:08 +09002197 if (llvm::NullPointerIsDefined(F, PtrTy->getPointerAddressSpace()))
2198 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002199 else
Hideto Uenoef4febd2019-12-29 17:34:08 +09002200 KnownUBInsts.insert(&I);
2201 return true;
2202 };
2203
2204 auto InspectBrInstForUB = [&](Instruction &I) {
2205 // A conditional branch instruction is considered UB if it has `undef`
2206 // condition.
2207
2208 // Skip instructions that are already saved.
2209 if (AssumedNoUBInsts.count(&I) || KnownUBInsts.count(&I))
2210 return true;
2211
2212 // We know we have a branch instruction.
2213 auto BrInst = cast<BranchInst>(&I);
2214
2215 // Unconditional branches are never considered UB.
2216 if (BrInst->isUnconditional())
2217 return true;
2218
2219 // Either we stopped and the appropriate action was taken,
2220 // or we got back a simplified value to continue.
2221 Optional<Value *> SimplifiedCond =
2222 stopOnUndefOrAssumed(A, BrInst->getCondition(), BrInst);
2223 if (!SimplifiedCond.hasValue())
2224 return true;
2225 AssumedNoUBInsts.insert(&I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002226 return true;
2227 };
2228
Johannes Doerfert5732f562019-12-24 19:25:08 -06002229 A.checkForAllInstructions(InspectMemAccessInstForUB, *this,
2230 {Instruction::Load, Instruction::Store,
2231 Instruction::AtomicCmpXchg,
2232 Instruction::AtomicRMW});
Hideto Uenoef4febd2019-12-29 17:34:08 +09002233 A.checkForAllInstructions(InspectBrInstForUB, *this, {Instruction::Br});
2234 if (NoUBPrevSize != AssumedNoUBInsts.size() ||
2235 UBPrevSize != KnownUBInsts.size())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002236 return ChangeStatus::CHANGED;
2237 return ChangeStatus::UNCHANGED;
2238 }
2239
Hideto Uenoef4febd2019-12-29 17:34:08 +09002240 bool isKnownToCauseUB(Instruction *I) const override {
2241 return KnownUBInsts.count(I);
2242 }
2243
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002244 bool isAssumedToCauseUB(Instruction *I) const override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002245 // In simple words, if an instruction is not in the assumed to _not_
2246 // cause UB, then it is assumed UB (that includes those
2247 // in the KnownUBInsts set). The rest is boilerplate
2248 // is to ensure that it is one of the instructions we test
2249 // for UB.
2250
2251 switch (I->getOpcode()) {
2252 case Instruction::Load:
2253 case Instruction::Store:
2254 case Instruction::AtomicCmpXchg:
2255 case Instruction::AtomicRMW:
2256 return !AssumedNoUBInsts.count(I);
2257 case Instruction::Br: {
2258 auto BrInst = cast<BranchInst>(I);
2259 if (BrInst->isUnconditional())
2260 return false;
2261 return !AssumedNoUBInsts.count(I);
2262 } break;
2263 default:
2264 return false;
2265 }
2266 return false;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002267 }
2268
2269 ChangeStatus manifest(Attributor &A) override {
Hideto Uenoef4febd2019-12-29 17:34:08 +09002270 if (KnownUBInsts.empty())
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002271 return ChangeStatus::UNCHANGED;
Hideto Uenoef4febd2019-12-29 17:34:08 +09002272 for (Instruction *I : KnownUBInsts)
Hideto Uenocb5eb132019-12-27 02:39:37 +09002273 A.changeToUnreachableAfterManifest(I);
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002274 return ChangeStatus::CHANGED;
2275 }
2276
2277 /// See AbstractAttribute::getAsStr()
2278 const std::string getAsStr() const override {
2279 return getAssumed() ? "undefined-behavior" : "no-ub";
2280 }
2281
Hideto Uenoef4febd2019-12-29 17:34:08 +09002282 /// Note: The correctness of this analysis depends on the fact that the
2283 /// following 2 sets will stop changing after some point.
2284 /// "Change" here means that their size changes.
2285 /// The size of each set is monotonically increasing
2286 /// (we only add items to them) and it is upper bounded by the number of
2287 /// instructions in the processed function (we can never save more
2288 /// elements in either set than this number). Hence, at some point,
2289 /// they will stop increasing.
2290 /// Consequently, at some point, both sets will have stopped
2291 /// changing, effectively making the analysis reach a fixpoint.
2292
2293 /// Note: These 2 sets are disjoint and an instruction can be considered
2294 /// one of 3 things:
2295 /// 1) Known to cause UB (AAUndefinedBehavior could prove it) and put it in
2296 /// the KnownUBInsts set.
2297 /// 2) Assumed to cause UB (in every updateImpl, AAUndefinedBehavior
2298 /// has a reason to assume it).
2299 /// 3) Assumed to not cause UB. very other instruction - AAUndefinedBehavior
2300 /// could not find a reason to assume or prove that it can cause UB,
2301 /// hence it assumes it doesn't. We have a set for these instructions
2302 /// so that we don't reprocess them in every update.
2303 /// Note however that instructions in this set may cause UB.
2304
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002305protected:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002306 /// A set of all live instructions _known_ to cause UB.
2307 SmallPtrSet<Instruction *, 8> KnownUBInsts;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002308
2309private:
Hideto Uenoef4febd2019-12-29 17:34:08 +09002310 /// A set of all the (live) instructions that are assumed to _not_ cause UB.
2311 SmallPtrSet<Instruction *, 8> AssumedNoUBInsts;
2312
2313 // Should be called on updates in which if we're processing an instruction
2314 // \p I that depends on a value \p V, one of the following has to happen:
2315 // - If the value is assumed, then stop.
2316 // - If the value is known but undef, then consider it UB.
2317 // - Otherwise, do specific processing with the simplified value.
2318 // We return None in the first 2 cases to signify that an appropriate
2319 // action was taken and the caller should stop.
2320 // Otherwise, we return the simplified value that the caller should
2321 // use for specific processing.
2322 Optional<Value *> stopOnUndefOrAssumed(Attributor &A, const Value *V,
2323 Instruction *I) {
2324 const auto &ValueSimplifyAA =
2325 A.getAAFor<AAValueSimplify>(*this, IRPosition::value(*V));
2326 Optional<Value *> SimplifiedV =
2327 ValueSimplifyAA.getAssumedSimplifiedValue(A);
2328 if (!ValueSimplifyAA.isKnown()) {
2329 // Don't depend on assumed values.
2330 return llvm::None;
2331 }
2332 if (!SimplifiedV.hasValue()) {
2333 // If it is known (which we tested above) but it doesn't have a value,
2334 // then we can assume `undef` and hence the instruction is UB.
2335 KnownUBInsts.insert(I);
2336 return llvm::None;
2337 }
2338 Value *Val = SimplifiedV.getValue();
2339 if (isa<UndefValue>(Val)) {
2340 KnownUBInsts.insert(I);
2341 return llvm::None;
2342 }
2343 return Val;
2344 }
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002345};
2346
2347struct AAUndefinedBehaviorFunction final : AAUndefinedBehaviorImpl {
2348 AAUndefinedBehaviorFunction(const IRPosition &IRP)
2349 : AAUndefinedBehaviorImpl(IRP) {}
2350
2351 /// See AbstractAttribute::trackStatistics()
2352 void trackStatistics() const override {
2353 STATS_DECL(UndefinedBehaviorInstruction, Instruction,
2354 "Number of instructions known to have UB");
2355 BUILD_STAT_NAME(UndefinedBehaviorInstruction, Instruction) +=
Hideto Uenoef4febd2019-12-29 17:34:08 +09002356 KnownUBInsts.size();
Johannes Doerfert58f324a2019-12-24 18:48:50 -06002357 }
2358};
2359
Hideto Ueno11d37102019-07-17 15:15:43 +00002360/// ------------------------ Will-Return Attributes ----------------------------
2361
Hideto Ueno11d37102019-07-17 15:15:43 +00002362// Helper function that checks whether a function has any cycle.
2363// TODO: Replace with more efficent code
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002364static bool containsCycle(Function &F) {
Hideto Ueno11d37102019-07-17 15:15:43 +00002365 SmallPtrSet<BasicBlock *, 32> Visited;
2366
2367 // Traverse BB by dfs and check whether successor is already visited.
2368 for (BasicBlock *BB : depth_first(&F)) {
2369 Visited.insert(BB);
2370 for (auto *SuccBB : successors(BB)) {
2371 if (Visited.count(SuccBB))
2372 return true;
2373 }
2374 }
2375 return false;
2376}
2377
2378// Helper function that checks the function have a loop which might become an
2379// endless loop
2380// FIXME: Any cycle is regarded as endless loop for now.
2381// We have to allow some patterns.
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002382static bool containsPossiblyEndlessLoop(Function *F) {
2383 return !F || !F->hasExactDefinition() || containsCycle(*F);
Hideto Ueno11d37102019-07-17 15:15:43 +00002384}
2385
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002386struct AAWillReturnImpl : public AAWillReturn {
2387 AAWillReturnImpl(const IRPosition &IRP) : AAWillReturn(IRP) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00002388
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002389 /// See AbstractAttribute::initialize(...).
2390 void initialize(Attributor &A) override {
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002391 AAWillReturn::initialize(A);
Hideto Ueno11d37102019-07-17 15:15:43 +00002392
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002393 Function *F = getAssociatedFunction();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002394 if (containsPossiblyEndlessLoop(F))
2395 indicatePessimisticFixpoint();
2396 }
Hideto Ueno11d37102019-07-17 15:15:43 +00002397
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002398 /// See AbstractAttribute::updateImpl(...).
2399 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002400 auto CheckForWillReturn = [&](Instruction &I) {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002401 IRPosition IPos = IRPosition::callsite_function(ImmutableCallSite(&I));
2402 const auto &WillReturnAA = A.getAAFor<AAWillReturn>(*this, IPos);
2403 if (WillReturnAA.isKnownWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002404 return true;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002405 if (!WillReturnAA.isAssumedWillReturn())
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002406 return false;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002407 const auto &NoRecurseAA = A.getAAFor<AANoRecurse>(*this, IPos);
2408 return NoRecurseAA.isAssumedNoRecurse();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002409 };
2410
2411 if (!A.checkForAllCallLikeInstructions(CheckForWillReturn, *this))
2412 return indicatePessimisticFixpoint();
2413
2414 return ChangeStatus::UNCHANGED;
2415 }
2416
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002417 /// See AbstractAttribute::getAsStr()
2418 const std::string getAsStr() const override {
2419 return getAssumed() ? "willreturn" : "may-noreturn";
2420 }
2421};
2422
2423struct AAWillReturnFunction final : AAWillReturnImpl {
2424 AAWillReturnFunction(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2425
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002426 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002427 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(willreturn) }
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002428};
Hideto Ueno11d37102019-07-17 15:15:43 +00002429
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002430/// WillReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002431struct AAWillReturnCallSite final : AAWillReturnImpl {
2432 AAWillReturnCallSite(const IRPosition &IRP) : AAWillReturnImpl(IRP) {}
2433
2434 /// See AbstractAttribute::initialize(...).
2435 void initialize(Attributor &A) override {
2436 AAWillReturnImpl::initialize(A);
2437 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002438 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002439 indicatePessimisticFixpoint();
2440 }
2441
2442 /// See AbstractAttribute::updateImpl(...).
2443 ChangeStatus updateImpl(Attributor &A) override {
2444 // TODO: Once we have call site specific value information we can provide
2445 // call site specific liveness information and then it makes
2446 // sense to specialize attributes for call sites arguments instead of
2447 // redirecting requests to the callee argument.
2448 Function *F = getAssociatedFunction();
2449 const IRPosition &FnPos = IRPosition::function(*F);
2450 auto &FnAA = A.getAAFor<AAWillReturn>(*this, FnPos);
2451 return clampStateAndIndicateChange(
2452 getState(),
2453 static_cast<const AAWillReturn::StateType &>(FnAA.getState()));
2454 }
2455
2456 /// See AbstractAttribute::trackStatistics()
2457 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(willreturn); }
2458};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002459
Pankaj Gode04945c92019-11-22 18:40:47 +05302460/// -------------------AAReachability Attribute--------------------------
2461
2462struct AAReachabilityImpl : AAReachability {
2463 AAReachabilityImpl(const IRPosition &IRP) : AAReachability(IRP) {}
2464
2465 const std::string getAsStr() const override {
2466 // TODO: Return the number of reachable queries.
2467 return "reachable";
2468 }
2469
2470 /// See AbstractAttribute::initialize(...).
Johannes Doerfert0bc33362019-12-16 21:03:18 -06002471 void initialize(Attributor &A) override { indicatePessimisticFixpoint(); }
Pankaj Gode04945c92019-11-22 18:40:47 +05302472
2473 /// See AbstractAttribute::updateImpl(...).
2474 ChangeStatus updateImpl(Attributor &A) override {
2475 return indicatePessimisticFixpoint();
2476 }
2477};
2478
2479struct AAReachabilityFunction final : public AAReachabilityImpl {
2480 AAReachabilityFunction(const IRPosition &IRP) : AAReachabilityImpl(IRP) {}
2481
2482 /// See AbstractAttribute::trackStatistics()
2483 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(reachable); }
2484};
2485
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002486/// ------------------------ NoAlias Argument Attribute ------------------------
2487
Johannes Doerfert344d0382019-08-07 22:34:26 +00002488struct AANoAliasImpl : AANoAlias {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002489 AANoAliasImpl(const IRPosition &IRP) : AANoAlias(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002490
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002491 const std::string getAsStr() const override {
2492 return getAssumed() ? "noalias" : "may-alias";
2493 }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002494};
2495
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002496/// NoAlias attribute for a floating value.
2497struct AANoAliasFloating final : AANoAliasImpl {
2498 AANoAliasFloating(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2499
Hideto Uenocbab3342019-08-29 05:52:00 +00002500 /// See AbstractAttribute::initialize(...).
2501 void initialize(Attributor &A) override {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002502 AANoAliasImpl::initialize(A);
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002503 Value *Val = &getAssociatedValue();
2504 do {
2505 CastInst *CI = dyn_cast<CastInst>(Val);
2506 if (!CI)
2507 break;
2508 Value *Base = CI->getOperand(0);
2509 if (Base->getNumUses() != 1)
2510 break;
2511 Val = Base;
2512 } while (true);
2513
Johannes Doerfert72adda12019-10-10 05:33:21 +00002514 if (isa<AllocaInst>(Val))
2515 indicateOptimisticFixpoint();
Johannes Doerfert24ae77e2020-01-27 22:19:11 -06002516 else if (isa<ConstantPointerNull>(Val) &&
2517 !NullPointerIsDefined(getAnchorScope(),
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002518 Val->getType()->getPointerAddressSpace()))
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002519 indicateOptimisticFixpoint();
Johannes Doerfert87ddf1f2020-01-25 20:21:41 -06002520 else if (Val != &getAssociatedValue()) {
2521 const auto &ValNoAliasAA =
2522 A.getAAFor<AANoAlias>(*this, IRPosition::value(*Val));
2523 if (ValNoAliasAA.isKnownNoAlias())
2524 indicateOptimisticFixpoint();
2525 }
Hideto Uenocbab3342019-08-29 05:52:00 +00002526 }
2527
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002528 /// See AbstractAttribute::updateImpl(...).
2529 ChangeStatus updateImpl(Attributor &A) override {
2530 // TODO: Implement this.
2531 return indicatePessimisticFixpoint();
2532 }
2533
2534 /// See AbstractAttribute::trackStatistics()
2535 void trackStatistics() const override {
2536 STATS_DECLTRACK_FLOATING_ATTR(noalias)
2537 }
2538};
2539
2540/// NoAlias attribute for an argument.
Hideto Uenocbab3342019-08-29 05:52:00 +00002541struct AANoAliasArgument final
2542 : AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl> {
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002543 using Base = AAArgumentFromCallSiteArguments<AANoAlias, AANoAliasImpl>;
2544 AANoAliasArgument(const IRPosition &IRP) : Base(IRP) {}
2545
Johannes Doerfert2baf0002020-01-12 00:18:07 -06002546 /// See AbstractAttribute::initialize(...).
2547 void initialize(Attributor &A) override {
2548 Base::initialize(A);
2549 // See callsite argument attribute and callee argument attribute.
2550 if (hasAttr({Attribute::ByVal}))
2551 indicateOptimisticFixpoint();
2552 }
2553
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002554 /// See AbstractAttribute::update(...).
2555 ChangeStatus updateImpl(Attributor &A) override {
2556 // We have to make sure no-alias on the argument does not break
2557 // synchronization when this is a callback argument, see also [1] below.
2558 // If synchronization cannot be affected, we delegate to the base updateImpl
2559 // function, otherwise we give up for now.
2560
2561 // If the function is no-sync, no-alias cannot break synchronization.
2562 const auto &NoSyncAA = A.getAAFor<AANoSync>(
2563 *this, IRPosition::function_scope(getIRPosition()));
2564 if (NoSyncAA.isAssumedNoSync())
2565 return Base::updateImpl(A);
2566
2567 // If the argument is read-only, no-alias cannot break synchronization.
2568 const auto &MemBehaviorAA =
2569 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
2570 if (MemBehaviorAA.isAssumedReadOnly())
2571 return Base::updateImpl(A);
2572
2573 // If the argument is never passed through callbacks, no-alias cannot break
2574 // synchronization.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002575 bool AllCallSitesKnown;
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002576 if (A.checkForAllCallSites(
2577 [](AbstractCallSite ACS) { return !ACS.isCallbackCall(); }, *this,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002578 true, AllCallSitesKnown))
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002579 return Base::updateImpl(A);
2580
2581 // TODO: add no-alias but make sure it doesn't break synchronization by
2582 // introducing fake uses. See:
2583 // [1] Compiler Optimizations for OpenMP, J. Doerfert and H. Finkel,
2584 // International Workshop on OpenMP 2018,
2585 // http://compilers.cs.uni-saarland.de/people/doerfert/par_opt18.pdf
2586
2587 return indicatePessimisticFixpoint();
2588 }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002589
2590 /// See AbstractAttribute::trackStatistics()
2591 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(noalias) }
2592};
2593
2594struct AANoAliasCallSiteArgument final : AANoAliasImpl {
2595 AANoAliasCallSiteArgument(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2596
Hideto Uenocbab3342019-08-29 05:52:00 +00002597 /// See AbstractAttribute::initialize(...).
2598 void initialize(Attributor &A) override {
Hideto Ueno6381b142019-08-30 10:00:32 +00002599 // See callsite argument attribute and callee argument attribute.
2600 ImmutableCallSite ICS(&getAnchorValue());
2601 if (ICS.paramHasAttr(getArgNo(), Attribute::NoAlias))
2602 indicateOptimisticFixpoint();
Johannes Doerfert24ae77e2020-01-27 22:19:11 -06002603 Value &Val = getAssociatedValue();
2604 if (isa<ConstantPointerNull>(Val) &&
2605 !NullPointerIsDefined(getAnchorScope(),
2606 Val.getType()->getPointerAddressSpace()))
2607 indicateOptimisticFixpoint();
Hideto Uenocbab3342019-08-29 05:52:00 +00002608 }
2609
Johannes Doerfert53992c72020-01-27 22:24:32 -06002610 /// Determine if the underlying value may alias with the call site argument
2611 /// \p OtherArgNo of \p ICS (= the underlying call site).
2612 bool mayAliasWithArgument(Attributor &A, AAResults *&AAR,
2613 const AAMemoryBehavior &MemBehaviorAA,
2614 ImmutableCallSite ICS, unsigned OtherArgNo) {
2615 // We do not need to worry about aliasing with the underlying IRP.
2616 if (this->getArgNo() == (int)OtherArgNo)
2617 return false;
2618
2619 // If it is not a pointer or pointer vector we do not alias.
2620 const Value *ArgOp = ICS.getArgOperand(OtherArgNo);
2621 if (!ArgOp->getType()->isPtrOrPtrVectorTy())
2622 return false;
2623
2624 auto &ICSArgMemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
2625 *this, IRPosition::callsite_argument(ICS, OtherArgNo),
2626 /* TrackDependence */ false);
2627
2628 // If the argument is readnone, there is no read-write aliasing.
2629 if (ICSArgMemBehaviorAA.isAssumedReadNone()) {
2630 A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
2631 return false;
2632 }
2633
2634 // If the argument is readonly and the underlying value is readonly, there
2635 // is no read-write aliasing.
2636 bool IsReadOnly = MemBehaviorAA.isAssumedReadOnly();
2637 if (ICSArgMemBehaviorAA.isAssumedReadOnly() && IsReadOnly) {
2638 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
2639 A.recordDependence(ICSArgMemBehaviorAA, *this, DepClassTy::OPTIONAL);
2640 return false;
2641 }
2642
2643 // We have to utilize actual alias analysis queries so we need the object.
2644 if (!AAR)
2645 AAR = A.getInfoCache().getAAResultsForFunction(*getAnchorScope());
2646
2647 // Try to rule it out at the call site.
2648 bool IsAliasing = !AAR || !AAR->isNoAlias(&getAssociatedValue(), ArgOp);
2649 LLVM_DEBUG(dbgs() << "[NoAliasCSArg] Check alias between "
2650 "callsite arguments: "
2651 << getAssociatedValue() << " " << *ArgOp << " => "
2652 << (IsAliasing ? "" : "no-") << "alias \n");
2653
2654 return IsAliasing;
2655 }
2656
2657 bool
2658 isKnownNoAliasDueToNoAliasPreservation(Attributor &A, AAResults *&AAR,
2659 const AAMemoryBehavior &MemBehaviorAA,
2660 const AANoAlias &NoAliasAA) {
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002661 // We can deduce "noalias" if the following conditions hold.
2662 // (i) Associated value is assumed to be noalias in the definition.
2663 // (ii) Associated value is assumed to be no-capture in all the uses
2664 // possibly executed before this callsite.
2665 // (iii) There is no other pointer argument which could alias with the
2666 // value.
2667
Johannes Doerfert53992c72020-01-27 22:24:32 -06002668 bool AssociatedValueIsNoAliasAtDef = NoAliasAA.isAssumedNoAlias();
2669 if (!AssociatedValueIsNoAliasAtDef) {
2670 LLVM_DEBUG(dbgs() << "[AANoAlias] " << getAssociatedValue()
2671 << " is not no-alias at the definition\n");
2672 return false;
2673 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002674
Johannes Doerfert53992c72020-01-27 22:24:32 -06002675 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
2676 auto &NoCaptureAA =
2677 A.getAAFor<AANoCapture>(*this, VIRP, /* TrackDependence */ false);
2678 // Check whether the value is captured in the scope using AANoCapture.
2679 // FIXME: This is conservative though, it is better to look at CFG and
2680 // check only uses possibly executed before this callsite.
Johannes Doerfert72adda12019-10-10 05:33:21 +00002681 if (!NoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
2682 LLVM_DEBUG(
Johannes Doerfert53992c72020-01-27 22:24:32 -06002683 dbgs() << "[AANoAliasCSArg] " << getAssociatedValue()
Johannes Doerfert72adda12019-10-10 05:33:21 +00002684 << " cannot be noalias as it is potentially captured\n");
Johannes Doerfert53992c72020-01-27 22:24:32 -06002685 return false;
Johannes Doerfert72adda12019-10-10 05:33:21 +00002686 }
Johannes Doerfert53992c72020-01-27 22:24:32 -06002687 A.recordDependence(NoCaptureAA, *this, DepClassTy::OPTIONAL);
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002688
Johannes Doerfert53992c72020-01-27 22:24:32 -06002689 // Check there is no other pointer argument which could alias with the
2690 // value passed at this call site.
Johannes Doerfertb1b441d2019-10-10 01:19:57 -05002691 // TODO: AbstractCallSite
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002692 ImmutableCallSite ICS(&getAnchorValue());
Johannes Doerfert53992c72020-01-27 22:24:32 -06002693 for (unsigned OtherArgNo = 0; OtherArgNo < ICS.getNumArgOperands();
2694 OtherArgNo++)
2695 if (mayAliasWithArgument(A, AAR, MemBehaviorAA, ICS, OtherArgNo))
2696 return false;
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002697
Johannes Doerfert53992c72020-01-27 22:24:32 -06002698 return true;
2699 }
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002700
Johannes Doerfert53992c72020-01-27 22:24:32 -06002701 /// See AbstractAttribute::updateImpl(...).
2702 ChangeStatus updateImpl(Attributor &A) override {
2703 // If the argument is readnone we are done as there are no accesses via the
2704 // argument.
2705 auto &MemBehaviorAA =
2706 A.getAAFor<AAMemoryBehavior>(*this, getIRPosition(),
2707 /* TrackDependence */ false);
2708 if (MemBehaviorAA.isAssumedReadNone()) {
2709 A.recordDependence(MemBehaviorAA, *this, DepClassTy::OPTIONAL);
2710 return ChangeStatus::UNCHANGED;
Hideto Ueno1d68ed82019-09-11 07:00:33 +00002711 }
2712
Johannes Doerfert53992c72020-01-27 22:24:32 -06002713 const IRPosition &VIRP = IRPosition::value(getAssociatedValue());
2714 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, VIRP,
2715 /* TrackDependence */ false);
2716
2717 AAResults *AAR = nullptr;
2718 if (isKnownNoAliasDueToNoAliasPreservation(A, AAR, MemBehaviorAA,
2719 NoAliasAA)) {
2720 LLVM_DEBUG(
2721 dbgs() << "[AANoAlias] No-Alias deduced via no-alias preservation\n");
2722 return ChangeStatus::UNCHANGED;
2723 }
2724
2725 return indicatePessimisticFixpoint();
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002726 }
2727
2728 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002729 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(noalias) }
Johannes Doerfert6dedc782019-08-16 21:31:11 +00002730};
2731
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002732/// NoAlias attribute for function return value.
Johannes Doerfertbeb51502019-08-07 22:36:15 +00002733struct AANoAliasReturned final : AANoAliasImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00002734 AANoAliasReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002735
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002736 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002737 virtual ChangeStatus updateImpl(Attributor &A) override {
2738
2739 auto CheckReturnValue = [&](Value &RV) -> bool {
2740 if (Constant *C = dyn_cast<Constant>(&RV))
2741 if (C->isNullValue() || isa<UndefValue>(C))
2742 return true;
2743
2744 /// For now, we can only deduce noalias if we have call sites.
2745 /// FIXME: add more support.
2746 ImmutableCallSite ICS(&RV);
2747 if (!ICS)
2748 return false;
2749
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002750 const IRPosition &RVPos = IRPosition::value(RV);
2751 const auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, RVPos);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00002752 if (!NoAliasAA.isAssumedNoAlias())
2753 return false;
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002754
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00002755 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, RVPos);
2756 return NoCaptureAA.isAssumedNoCaptureMaybeReturned();
Johannes Doerfertfe6dbad2019-08-16 19:36:17 +00002757 };
2758
2759 if (!A.checkForAllReturnedValues(CheckReturnValue, *this))
2760 return indicatePessimisticFixpoint();
2761
2762 return ChangeStatus::UNCHANGED;
2763 }
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00002764
2765 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00002766 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(noalias) }
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002767};
2768
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002769/// NoAlias attribute deduction for a call site return value.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002770struct AANoAliasCallSiteReturned final : AANoAliasImpl {
2771 AANoAliasCallSiteReturned(const IRPosition &IRP) : AANoAliasImpl(IRP) {}
2772
2773 /// See AbstractAttribute::initialize(...).
2774 void initialize(Attributor &A) override {
2775 AANoAliasImpl::initialize(A);
2776 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00002777 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002778 indicatePessimisticFixpoint();
2779 }
2780
2781 /// See AbstractAttribute::updateImpl(...).
2782 ChangeStatus updateImpl(Attributor &A) override {
2783 // TODO: Once we have call site specific value information we can provide
2784 // call site specific liveness information and then it makes
2785 // sense to specialize attributes for call sites arguments instead of
2786 // redirecting requests to the callee argument.
2787 Function *F = getAssociatedFunction();
2788 const IRPosition &FnPos = IRPosition::returned(*F);
2789 auto &FnAA = A.getAAFor<AANoAlias>(*this, FnPos);
2790 return clampStateAndIndicateChange(
2791 getState(), static_cast<const AANoAlias::StateType &>(FnAA.getState()));
2792 }
2793
2794 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert56e9b602019-09-04 20:34:57 +00002795 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(noalias); }
Johannes Doerfert3fac6682019-08-30 15:24:52 +00002796};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00002797
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002798/// -------------------AAIsDead Function Attribute-----------------------
2799
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002800struct AAIsDeadValueImpl : public AAIsDead {
2801 AAIsDeadValueImpl(const IRPosition &IRP) : AAIsDead(IRP) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00002802
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002803 /// See AAIsDead::isAssumedDead().
2804 bool isAssumedDead() const override { return getAssumed(); }
2805
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002806 /// See AAIsDead::isKnownDead().
2807 bool isKnownDead() const override { return getKnown(); }
2808
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002809 /// See AAIsDead::isAssumedDead(BasicBlock *).
2810 bool isAssumedDead(const BasicBlock *BB) const override { return false; }
2811
2812 /// See AAIsDead::isKnownDead(BasicBlock *).
2813 bool isKnownDead(const BasicBlock *BB) const override { return false; }
2814
2815 /// See AAIsDead::isAssumedDead(Instruction *I).
2816 bool isAssumedDead(const Instruction *I) const override {
2817 return I == getCtxI() && isAssumedDead();
2818 }
2819
2820 /// See AAIsDead::isKnownDead(Instruction *I).
2821 bool isKnownDead(const Instruction *I) const override {
2822 return I == getCtxI() && getKnown();
2823 }
2824
2825 /// See AbstractAttribute::getAsStr().
2826 const std::string getAsStr() const override {
2827 return isAssumedDead() ? "assumed-dead" : "assumed-live";
2828 }
2829};
2830
2831struct AAIsDeadFloating : public AAIsDeadValueImpl {
2832 AAIsDeadFloating(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2833
2834 /// See AbstractAttribute::initialize(...).
2835 void initialize(Attributor &A) override {
2836 if (Instruction *I = dyn_cast<Instruction>(&getAssociatedValue()))
2837 if (!wouldInstructionBeTriviallyDead(I))
2838 indicatePessimisticFixpoint();
2839 if (isa<UndefValue>(getAssociatedValue()))
2840 indicatePessimisticFixpoint();
2841 }
2842
2843 /// See AbstractAttribute::updateImpl(...).
2844 ChangeStatus updateImpl(Attributor &A) override {
2845 auto UsePred = [&](const Use &U, bool &Follow) {
2846 Instruction *UserI = cast<Instruction>(U.getUser());
2847 if (CallSite CS = CallSite(UserI)) {
2848 if (!CS.isArgOperand(&U))
2849 return false;
2850 const IRPosition &CSArgPos =
2851 IRPosition::callsite_argument(CS, CS.getArgumentNo(&U));
2852 const auto &CSArgIsDead = A.getAAFor<AAIsDead>(*this, CSArgPos);
2853 return CSArgIsDead.isAssumedDead();
2854 }
2855 if (ReturnInst *RI = dyn_cast<ReturnInst>(UserI)) {
2856 const IRPosition &RetPos = IRPosition::returned(*RI->getFunction());
2857 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, RetPos);
2858 return RetIsDeadAA.isAssumedDead();
2859 }
2860 Follow = true;
2861 return wouldInstructionBeTriviallyDead(UserI);
2862 };
2863
2864 if (!A.checkForAllUses(UsePred, *this, getAssociatedValue()))
2865 return indicatePessimisticFixpoint();
2866 return ChangeStatus::UNCHANGED;
2867 }
2868
2869 /// See AbstractAttribute::manifest(...).
2870 ChangeStatus manifest(Attributor &A) override {
2871 Value &V = getAssociatedValue();
2872 if (auto *I = dyn_cast<Instruction>(&V))
2873 if (wouldInstructionBeTriviallyDead(I)) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05002874 A.deleteAfterManifest(*I);
2875 return ChangeStatus::CHANGED;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002876 }
2877
2878 if (V.use_empty())
2879 return ChangeStatus::UNCHANGED;
2880
2881 UndefValue &UV = *UndefValue::get(V.getType());
Hideto Ueno34fe8d02019-12-30 17:08:48 +09002882 bool AnyChange = A.changeValueAfterManifest(V, UV);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002883 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2884 }
2885
2886 /// See AbstractAttribute::trackStatistics()
2887 void trackStatistics() const override {
2888 STATS_DECLTRACK_FLOATING_ATTR(IsDead)
2889 }
2890};
2891
2892struct AAIsDeadArgument : public AAIsDeadFloating {
2893 AAIsDeadArgument(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
2894
2895 /// See AbstractAttribute::initialize(...).
2896 void initialize(Attributor &A) override {
2897 if (!getAssociatedFunction()->hasExactDefinition())
2898 indicatePessimisticFixpoint();
2899 }
2900
Johannes Doerfert75133632019-10-10 01:39:16 -05002901 /// See AbstractAttribute::manifest(...).
2902 ChangeStatus manifest(Attributor &A) override {
2903 ChangeStatus Changed = AAIsDeadFloating::manifest(A);
2904 Argument &Arg = *getAssociatedArgument();
Johannes Doerfert89c2e732019-10-30 17:20:20 -05002905 if (A.isValidFunctionSignatureRewrite(Arg, /* ReplacementTypes */ {}))
Johannes Doerfert75133632019-10-10 01:39:16 -05002906 if (A.registerFunctionSignatureRewrite(
2907 Arg, /* ReplacementTypes */ {},
2908 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy{},
2909 Attributor::ArgumentReplacementInfo::ACSRepairCBTy{}))
2910 return ChangeStatus::CHANGED;
2911 return Changed;
2912 }
2913
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002914 /// See AbstractAttribute::trackStatistics()
2915 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(IsDead) }
2916};
2917
2918struct AAIsDeadCallSiteArgument : public AAIsDeadValueImpl {
2919 AAIsDeadCallSiteArgument(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2920
2921 /// See AbstractAttribute::initialize(...).
2922 void initialize(Attributor &A) override {
2923 if (isa<UndefValue>(getAssociatedValue()))
2924 indicatePessimisticFixpoint();
2925 }
2926
2927 /// See AbstractAttribute::updateImpl(...).
2928 ChangeStatus updateImpl(Attributor &A) override {
2929 // TODO: Once we have call site specific value information we can provide
2930 // call site specific liveness information and then it makes
2931 // sense to specialize attributes for call sites arguments instead of
2932 // redirecting requests to the callee argument.
2933 Argument *Arg = getAssociatedArgument();
2934 if (!Arg)
2935 return indicatePessimisticFixpoint();
2936 const IRPosition &ArgPos = IRPosition::argument(*Arg);
2937 auto &ArgAA = A.getAAFor<AAIsDead>(*this, ArgPos);
2938 return clampStateAndIndicateChange(
2939 getState(), static_cast<const AAIsDead::StateType &>(ArgAA.getState()));
2940 }
2941
2942 /// See AbstractAttribute::manifest(...).
2943 ChangeStatus manifest(Attributor &A) override {
2944 CallBase &CB = cast<CallBase>(getAnchorValue());
2945 Use &U = CB.getArgOperandUse(getArgNo());
2946 assert(!isa<UndefValue>(U.get()) &&
2947 "Expected undef values to be filtered out!");
2948 UndefValue &UV = *UndefValue::get(U->getType());
2949 if (A.changeUseAfterManifest(U, UV))
2950 return ChangeStatus::CHANGED;
2951 return ChangeStatus::UNCHANGED;
2952 }
2953
2954 /// See AbstractAttribute::trackStatistics()
2955 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(IsDead) }
2956};
2957
2958struct AAIsDeadReturned : public AAIsDeadValueImpl {
2959 AAIsDeadReturned(const IRPosition &IRP) : AAIsDeadValueImpl(IRP) {}
2960
2961 /// See AbstractAttribute::updateImpl(...).
2962 ChangeStatus updateImpl(Attributor &A) override {
2963
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002964 bool AllKnownDead = true;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002965 auto PredForCallSite = [&](AbstractCallSite ACS) {
2966 if (ACS.isCallbackCall())
2967 return false;
2968 const IRPosition &CSRetPos =
2969 IRPosition::callsite_returned(ACS.getCallSite());
2970 const auto &RetIsDeadAA = A.getAAFor<AAIsDead>(*this, CSRetPos);
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002971 AllKnownDead &= RetIsDeadAA.isKnownDead();
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002972 return RetIsDeadAA.isAssumedDead();
2973 };
2974
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002975 bool AllCallSitesKnown;
2976 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
2977 AllCallSitesKnown))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002978 return indicatePessimisticFixpoint();
2979
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06002980 if (AllCallSitesKnown && AllKnownDead)
2981 indicateOptimisticFixpoint();
2982
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05002983 return ChangeStatus::UNCHANGED;
2984 }
2985
2986 /// See AbstractAttribute::manifest(...).
2987 ChangeStatus manifest(Attributor &A) override {
2988 // TODO: Rewrite the signature to return void?
2989 bool AnyChange = false;
2990 UndefValue &UV = *UndefValue::get(getAssociatedFunction()->getReturnType());
2991 auto RetInstPred = [&](Instruction &I) {
2992 ReturnInst &RI = cast<ReturnInst>(I);
2993 if (!isa<UndefValue>(RI.getReturnValue()))
2994 AnyChange |= A.changeUseAfterManifest(RI.getOperandUse(0), UV);
2995 return true;
2996 };
2997 A.checkForAllInstructions(RetInstPred, *this, {Instruction::Ret});
2998 return AnyChange ? ChangeStatus::CHANGED : ChangeStatus::UNCHANGED;
2999 }
3000
3001 /// See AbstractAttribute::trackStatistics()
3002 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(IsDead) }
3003};
3004
3005struct AAIsDeadCallSiteReturned : public AAIsDeadFloating {
3006 AAIsDeadCallSiteReturned(const IRPosition &IRP) : AAIsDeadFloating(IRP) {}
3007
3008 /// See AbstractAttribute::initialize(...).
3009 void initialize(Attributor &A) override {}
3010
3011 /// See AbstractAttribute::trackStatistics()
3012 void trackStatistics() const override { STATS_DECLTRACK_CSRET_ATTR(IsDead) }
3013};
3014
3015struct AAIsDeadFunction : public AAIsDead {
3016 AAIsDeadFunction(const IRPosition &IRP) : AAIsDead(IRP) {}
3017
3018 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003019 void initialize(Attributor &A) override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003020 const Function *F = getAssociatedFunction();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003021 if (F && !F->isDeclaration()) {
3022 ToBeExploredFrom.insert(&F->getEntryBlock().front());
3023 assumeLive(A, F->getEntryBlock());
3024 }
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003025 }
3026
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003027 /// See AbstractAttribute::getAsStr().
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003028 const std::string getAsStr() const override {
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003029 return "Live[#BB " + std::to_string(AssumedLiveBlocks.size()) + "/" +
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003030 std::to_string(getAssociatedFunction()->size()) + "][#TBEP " +
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003031 std::to_string(ToBeExploredFrom.size()) + "][#KDE " +
3032 std::to_string(KnownDeadEnds.size()) + "]";
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003033 }
3034
3035 /// See AbstractAttribute::manifest(...).
3036 ChangeStatus manifest(Attributor &A) override {
3037 assert(getState().isValidState() &&
3038 "Attempted to manifest an invalid state!");
3039
3040 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003041 Function &F = *getAssociatedFunction();
3042
3043 if (AssumedLiveBlocks.empty()) {
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003044 A.deleteAfterManifest(F);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003045 return ChangeStatus::CHANGED;
3046 }
Johannes Doerfert924d2132019-08-05 21:34:45 +00003047
Johannes Doerfertbeb51502019-08-07 22:36:15 +00003048 // Flag to determine if we can change an invoke to a call assuming the
3049 // callee is nounwind. This is not possible if the personality of the
3050 // function allows to catch asynchronous exceptions.
Johannes Doerfert924d2132019-08-05 21:34:45 +00003051 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003052
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003053 KnownDeadEnds.set_union(ToBeExploredFrom);
3054 for (const Instruction *DeadEndI : KnownDeadEnds) {
3055 auto *CB = dyn_cast<CallBase>(DeadEndI);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003056 if (!CB)
3057 continue;
3058 const auto &NoReturnAA =
3059 A.getAAFor<AANoReturn>(*this, IRPosition::callsite_function(*CB));
Johannes Doerfertc7ab19d2019-11-01 21:59:32 -05003060 bool MayReturn = !NoReturnAA.isAssumedNoReturn();
3061 if (MayReturn && (!Invoke2CallAllowed || !isa<InvokeInst>(CB)))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003062 continue;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003063
Johannes Doerferta4088c72020-01-07 16:01:57 -06003064 if (auto *II = dyn_cast<InvokeInst>(DeadEndI))
3065 A.registerInvokeWithDeadSuccessor(const_cast<InvokeInst &>(*II));
3066 else
3067 A.changeToUnreachableAfterManifest(
3068 const_cast<Instruction *>(DeadEndI->getNextNode()));
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003069 HasChanged = ChangeStatus::CHANGED;
3070 }
3071
Johannes Doerfertb19cd272019-09-03 20:42:16 +00003072 for (BasicBlock &BB : F)
3073 if (!AssumedLiveBlocks.count(&BB))
3074 A.deleteAfterManifest(BB);
3075
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003076 return HasChanged;
3077 }
3078
3079 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003080 ChangeStatus updateImpl(Attributor &A) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003081
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003082 /// See AbstractAttribute::trackStatistics()
3083 void trackStatistics() const override {}
3084
3085 /// Returns true if the function is assumed dead.
3086 bool isAssumedDead() const override { return false; }
3087
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06003088 /// See AAIsDead::isKnownDead().
3089 bool isKnownDead() const override { return false; }
3090
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003091 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003092 bool isAssumedDead(const BasicBlock *BB) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003093 assert(BB->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003094 "BB must be in the same anchor scope function.");
3095
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003096 if (!getAssumed())
3097 return false;
3098 return !AssumedLiveBlocks.count(BB);
3099 }
3100
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003101 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003102 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003103 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003104 }
3105
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003106 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003107 bool isAssumedDead(const Instruction *I) const override {
Johannes Doerfert6dedc782019-08-16 21:31:11 +00003108 assert(I->getParent()->getParent() == getAssociatedFunction() &&
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003109 "Instruction must be in the same anchor scope function.");
3110
Stefan Stipanovic7849e412019-08-03 15:27:41 +00003111 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003112 return false;
3113
3114 // If it is not in AssumedLiveBlocks then it for sure dead.
3115 // Otherwise, it can still be after noreturn call in a live block.
3116 if (!AssumedLiveBlocks.count(I->getParent()))
3117 return true;
3118
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003119 // If it is not after a liveness barrier it is live.
3120 const Instruction *PrevI = I->getPrevNode();
3121 while (PrevI) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003122 if (KnownDeadEnds.count(PrevI) || ToBeExploredFrom.count(PrevI))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003123 return true;
3124 PrevI = PrevI->getPrevNode();
3125 }
3126 return false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003127 }
3128
3129 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00003130 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003131 return getKnown() && isAssumedDead(I);
3132 }
3133
Johannes Doerfert924d2132019-08-05 21:34:45 +00003134 /// Determine if \p F might catch asynchronous exceptions.
3135 static bool mayCatchAsynchronousExceptions(const Function &F) {
3136 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
3137 }
3138
Johannes Doerfert2f622062019-09-04 16:35:20 +00003139 /// Assume \p BB is (partially) live now and indicate to the Attributor \p A
3140 /// that internal function called from \p BB should now be looked at.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003141 bool assumeLive(Attributor &A, const BasicBlock &BB) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00003142 if (!AssumedLiveBlocks.insert(&BB).second)
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003143 return false;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003144
3145 // We assume that all of BB is (probably) live now and if there are calls to
3146 // internal functions we will assume that those are now live as well. This
3147 // is a performance optimization for blocks with calls to a lot of internal
3148 // functions. It can however cause dead functions to be treated as live.
3149 for (const Instruction &I : BB)
3150 if (ImmutableCallSite ICS = ImmutableCallSite(&I))
3151 if (const Function *F = ICS.getCalledFunction())
Johannes Doerfert766f2cc2019-10-07 23:21:52 +00003152 if (F->hasLocalLinkage())
Johannes Doerfert2f622062019-09-04 16:35:20 +00003153 A.markLiveInternalFunction(*F);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003154 return true;
Johannes Doerfert2f622062019-09-04 16:35:20 +00003155 }
3156
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003157 /// Collection of instructions that need to be explored again, e.g., we
3158 /// did assume they do not transfer control to (one of their) successors.
3159 SmallSetVector<const Instruction *, 8> ToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003160
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003161 /// Collection of instructions that are known to not transfer control.
3162 SmallSetVector<const Instruction *, 8> KnownDeadEnds;
3163
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003164 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00003165 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003166};
3167
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003168static bool
3169identifyAliveSuccessors(Attributor &A, const CallBase &CB,
3170 AbstractAttribute &AA,
3171 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3172 const IRPosition &IPos = IRPosition::callsite_function(CB);
3173
3174 const auto &NoReturnAA = A.getAAFor<AANoReturn>(AA, IPos);
3175 if (NoReturnAA.isAssumedNoReturn())
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003176 return !NoReturnAA.isKnownNoReturn();
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003177 if (CB.isTerminator())
3178 AliveSuccessors.push_back(&CB.getSuccessor(0)->front());
3179 else
3180 AliveSuccessors.push_back(CB.getNextNode());
Stefan Stipanovicd0216172019-08-02 21:31:22 +00003181 return false;
3182}
3183
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003184static bool
3185identifyAliveSuccessors(Attributor &A, const InvokeInst &II,
3186 AbstractAttribute &AA,
3187 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3188 bool UsedAssumedInformation =
3189 identifyAliveSuccessors(A, cast<CallBase>(II), AA, AliveSuccessors);
Johannes Doerfert924d2132019-08-05 21:34:45 +00003190
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003191 // First, determine if we can change an invoke to a call assuming the
3192 // callee is nounwind. This is not possible if the personality of the
3193 // function allows to catch asynchronous exceptions.
3194 if (AAIsDeadFunction::mayCatchAsynchronousExceptions(*II.getFunction())) {
3195 AliveSuccessors.push_back(&II.getUnwindDest()->front());
3196 } else {
3197 const IRPosition &IPos = IRPosition::callsite_function(II);
3198 const auto &AANoUnw = A.getAAFor<AANoUnwind>(AA, IPos);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003199 if (AANoUnw.isAssumedNoUnwind()) {
3200 UsedAssumedInformation |= !AANoUnw.isKnownNoUnwind();
3201 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003202 AliveSuccessors.push_back(&II.getUnwindDest()->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003203 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003204 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003205 return UsedAssumedInformation;
3206}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003207
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003208static bool
3209identifyAliveSuccessors(Attributor &A, const BranchInst &BI,
3210 AbstractAttribute &AA,
3211 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
3212 bool UsedAssumedInformation = false;
3213 if (BI.getNumSuccessors() == 1) {
3214 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3215 } else {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003216 Optional<ConstantInt *> CI =
3217 getAssumedConstant(A, *BI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003218 if (!CI.hasValue()) {
3219 // No value yet, assume both edges are dead.
3220 } else if (CI.getValue()) {
3221 const BasicBlock *SuccBB =
3222 BI.getSuccessor(1 - CI.getValue()->getZExtValue());
3223 AliveSuccessors.push_back(&SuccBB->front());
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003224 } else {
3225 AliveSuccessors.push_back(&BI.getSuccessor(0)->front());
3226 AliveSuccessors.push_back(&BI.getSuccessor(1)->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003227 UsedAssumedInformation = false;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003228 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003229 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003230 return UsedAssumedInformation;
3231}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003232
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003233static bool
3234identifyAliveSuccessors(Attributor &A, const SwitchInst &SI,
3235 AbstractAttribute &AA,
3236 SmallVectorImpl<const Instruction *> &AliveSuccessors) {
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003237 bool UsedAssumedInformation = false;
3238 Optional<ConstantInt *> CI =
3239 getAssumedConstant(A, *SI.getCondition(), AA, UsedAssumedInformation);
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003240 if (!CI.hasValue()) {
3241 // No value yet, assume all edges are dead.
3242 } else if (CI.getValue()) {
3243 for (auto &CaseIt : SI.cases()) {
3244 if (CaseIt.getCaseValue() == CI.getValue()) {
3245 AliveSuccessors.push_back(&CaseIt.getCaseSuccessor()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003246 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003247 }
3248 }
Johannes Doerferted47a9c2019-11-01 13:57:49 -05003249 AliveSuccessors.push_back(&SI.getDefaultDest()->front());
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003250 return UsedAssumedInformation;
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003251 } else {
3252 for (const BasicBlock *SuccBB : successors(SI.getParent()))
3253 AliveSuccessors.push_back(&SuccBB->front());
3254 }
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003255 return UsedAssumedInformation;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003256}
3257
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003258ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003259 ChangeStatus Change = ChangeStatus::UNCHANGED;
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00003260
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003261 LLVM_DEBUG(dbgs() << "[AAIsDead] Live [" << AssumedLiveBlocks.size() << "/"
3262 << getAssociatedFunction()->size() << "] BBs and "
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003263 << ToBeExploredFrom.size() << " exploration points and "
3264 << KnownDeadEnds.size() << " known dead ends\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003265
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003266 // Copy and clear the list of instructions we need to explore from. It is
3267 // refilled with instructions the next update has to look at.
3268 SmallVector<const Instruction *, 8> Worklist(ToBeExploredFrom.begin(),
3269 ToBeExploredFrom.end());
3270 decltype(ToBeExploredFrom) NewToBeExploredFrom;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003271
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003272 SmallVector<const Instruction *, 8> AliveSuccessors;
3273 while (!Worklist.empty()) {
3274 const Instruction *I = Worklist.pop_back_val();
3275 LLVM_DEBUG(dbgs() << "[AAIsDead] Exploration inst: " << *I << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003276
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003277 AliveSuccessors.clear();
3278
3279 bool UsedAssumedInformation = false;
3280 switch (I->getOpcode()) {
3281 // TODO: look for (assumed) UB to backwards propagate "deadness".
3282 default:
3283 if (I->isTerminator()) {
3284 for (const BasicBlock *SuccBB : successors(I->getParent()))
3285 AliveSuccessors.push_back(&SuccBB->front());
3286 } else {
3287 AliveSuccessors.push_back(I->getNextNode());
3288 }
3289 break;
3290 case Instruction::Call:
3291 UsedAssumedInformation = identifyAliveSuccessors(A, cast<CallInst>(*I),
3292 *this, AliveSuccessors);
3293 break;
3294 case Instruction::Invoke:
3295 UsedAssumedInformation = identifyAliveSuccessors(A, cast<InvokeInst>(*I),
3296 *this, AliveSuccessors);
3297 break;
3298 case Instruction::Br:
3299 UsedAssumedInformation = identifyAliveSuccessors(A, cast<BranchInst>(*I),
3300 *this, AliveSuccessors);
3301 break;
3302 case Instruction::Switch:
3303 UsedAssumedInformation = identifyAliveSuccessors(A, cast<SwitchInst>(*I),
3304 *this, AliveSuccessors);
3305 break;
Johannes Doerfert4361da22019-08-04 18:38:53 +00003306 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003307
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003308 if (UsedAssumedInformation) {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003309 NewToBeExploredFrom.insert(I);
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003310 } else {
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003311 Change = ChangeStatus::CHANGED;
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003312 if (AliveSuccessors.empty() ||
3313 (I->isTerminator() && AliveSuccessors.size() < I->getNumSuccessors()))
3314 KnownDeadEnds.insert(I);
3315 }
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003316
3317 LLVM_DEBUG(dbgs() << "[AAIsDead] #AliveSuccessors: "
3318 << AliveSuccessors.size() << " UsedAssumedInformation: "
3319 << UsedAssumedInformation << "\n");
3320
3321 for (const Instruction *AliveSuccessor : AliveSuccessors) {
3322 if (!I->isTerminator()) {
3323 assert(AliveSuccessors.size() == 1 &&
3324 "Non-terminator expected to have a single successor!");
3325 Worklist.push_back(AliveSuccessor);
3326 } else {
3327 if (assumeLive(A, *AliveSuccessor->getParent()))
3328 Worklist.push_back(AliveSuccessor);
3329 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00003330 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003331 }
3332
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003333 ToBeExploredFrom = std::move(NewToBeExploredFrom);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003334
Johannes Doerfertd6207812019-08-07 22:32:38 +00003335 // If we know everything is live there is no need to query for liveness.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003336 // Instead, indicating a pessimistic fixpoint will cause the state to be
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003337 // "invalid" and all queries to be answered conservatively without lookups.
3338 // To be in this state we have to (1) finished the exploration and (3) not
3339 // discovered any non-trivial dead end and (2) not ruled unreachable code
3340 // dead.
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003341 if (ToBeExploredFrom.empty() &&
Johannes Doerfert3cbe3312019-11-01 21:04:54 -05003342 getAssociatedFunction()->size() == AssumedLiveBlocks.size() &&
3343 llvm::all_of(KnownDeadEnds, [](const Instruction *DeadEndI) {
3344 return DeadEndI->isTerminator() && DeadEndI->getNumSuccessors() == 0;
3345 }))
Johannes Doerfertdac2d402019-10-29 11:47:47 -05003346 return indicatePessimisticFixpoint();
3347 return Change;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00003348}
3349
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003350/// Liveness information for a call sites.
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05003351struct AAIsDeadCallSite final : AAIsDeadFunction {
3352 AAIsDeadCallSite(const IRPosition &IRP) : AAIsDeadFunction(IRP) {}
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003353
3354 /// See AbstractAttribute::initialize(...).
3355 void initialize(Attributor &A) override {
3356 // TODO: Once we have call site specific value information we can provide
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003357 // call site specific liveness information and then it makes
Johannes Doerfert07a5c122019-08-28 14:09:14 +00003358 // sense to specialize attributes for call sites instead of
3359 // redirecting requests to the callee.
3360 llvm_unreachable("Abstract attributes for liveness are not "
3361 "supported for call sites yet!");
3362 }
3363
3364 /// See AbstractAttribute::updateImpl(...).
3365 ChangeStatus updateImpl(Attributor &A) override {
3366 return indicatePessimisticFixpoint();
3367 }
3368
3369 /// See AbstractAttribute::trackStatistics()
3370 void trackStatistics() const override {}
3371};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003372
Hideto Ueno19c07af2019-07-23 08:16:17 +00003373/// -------------------- Dereferenceable Argument Attribute --------------------
3374
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003375template <>
3376ChangeStatus clampStateAndIndicateChange<DerefState>(DerefState &S,
3377 const DerefState &R) {
Johannes Doerfert31784242019-10-29 23:18:49 -05003378 ChangeStatus CS0 =
3379 clampStateAndIndicateChange(S.DerefBytesState, R.DerefBytesState);
3380 ChangeStatus CS1 = clampStateAndIndicateChange(S.GlobalState, R.GlobalState);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003381 return CS0 | CS1;
3382}
3383
Hideto Ueno70576ca2019-08-22 14:18:29 +00003384struct AADereferenceableImpl : AADereferenceable {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003385 AADereferenceableImpl(const IRPosition &IRP) : AADereferenceable(IRP) {}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003386 using StateType = DerefState;
Hideto Ueno19c07af2019-07-23 08:16:17 +00003387
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003388 void initialize(Attributor &A) override {
3389 SmallVector<Attribute, 4> Attrs;
3390 getAttrs({Attribute::Dereferenceable, Attribute::DereferenceableOrNull},
3391 Attrs);
3392 for (const Attribute &Attr : Attrs)
3393 takeKnownDerefBytesMaximum(Attr.getValueAsInt());
3394
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003395 NonNullAA = &A.getAAFor<AANonNull>(*this, getIRPosition(),
3396 /* TrackDependence */ false);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003397
3398 const IRPosition &IRP = this->getIRPosition();
3399 bool IsFnInterface = IRP.isFnInterfaceKind();
3400 const Function *FnScope = IRP.getAnchorScope();
3401 if (IsFnInterface && (!FnScope || !FnScope->hasExactDefinition()))
3402 indicatePessimisticFixpoint();
Johannes Doerfert6a1274a2019-08-14 21:31:32 +00003403 }
3404
Hideto Ueno19c07af2019-07-23 08:16:17 +00003405 /// See AbstractAttribute::getState()
3406 /// {
Johannes Doerfert344d0382019-08-07 22:34:26 +00003407 StateType &getState() override { return *this; }
3408 const StateType &getState() const override { return *this; }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003409 /// }
3410
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003411 /// Helper function for collecting accessed bytes in must-be-executed-context
3412 void addAccessedBytesForUse(Attributor &A, const Use *U,
3413 const Instruction *I) {
3414 const Value *UseV = U->get();
3415 if (!UseV->getType()->isPointerTy())
3416 return;
3417
3418 Type *PtrTy = UseV->getType();
3419 const DataLayout &DL = A.getDataLayout();
3420 int64_t Offset;
3421 if (const Value *Base = getBasePointerOfAccessPointerOperand(
3422 I, Offset, DL, /*AllowNonInbounds*/ true)) {
Hideto Uenoef4febd2019-12-29 17:34:08 +09003423 if (Base == &getAssociatedValue() &&
Johannes Doerfertb6dbd0f2020-01-26 02:49:58 -06003424 getPointerOperand(I, /* AllowVolatile */ false) == UseV) {
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003425 uint64_t Size = DL.getTypeStoreSize(PtrTy->getPointerElementType());
3426 addAccessedBytes(Offset, Size);
3427 }
3428 }
3429 return;
3430 }
3431
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003432 /// See AAFromMustBeExecutedContext
3433 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3434 bool IsNonNull = false;
3435 bool TrackUse = false;
3436 int64_t DerefBytes = getKnownNonNullAndDerefBytesForUse(
3437 A, *this, getAssociatedValue(), U, I, IsNonNull, TrackUse);
Hideto Ueno6c742fd2019-11-29 06:55:58 +00003438
3439 addAccessedBytesForUse(A, U, I);
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003440 takeKnownDerefBytesMaximum(DerefBytes);
3441 return TrackUse;
3442 }
3443
Hideto Uenodfedae52019-11-29 06:45:07 +00003444 /// See AbstractAttribute::manifest(...).
3445 ChangeStatus manifest(Attributor &A) override {
3446 ChangeStatus Change = AADereferenceable::manifest(A);
3447 if (isAssumedNonNull() && hasAttr(Attribute::DereferenceableOrNull)) {
3448 removeAttrs({Attribute::DereferenceableOrNull});
3449 return ChangeStatus::CHANGED;
3450 }
3451 return Change;
3452 }
3453
Johannes Doerferteccdf082019-08-05 23:35:12 +00003454 void getDeducedAttributes(LLVMContext &Ctx,
3455 SmallVectorImpl<Attribute> &Attrs) const override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00003456 // TODO: Add *_globally support
3457 if (isAssumedNonNull())
3458 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
3459 Ctx, getAssumedDereferenceableBytes()));
3460 else
3461 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
3462 Ctx, getAssumedDereferenceableBytes()));
3463 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003464
3465 /// See AbstractAttribute::getAsStr().
3466 const std::string getAsStr() const override {
3467 if (!getAssumedDereferenceableBytes())
3468 return "unknown-dereferenceable";
3469 return std::string("dereferenceable") +
3470 (isAssumedNonNull() ? "" : "_or_null") +
3471 (isAssumedGlobal() ? "_globally" : "") + "<" +
3472 std::to_string(getKnownDereferenceableBytes()) + "-" +
3473 std::to_string(getAssumedDereferenceableBytes()) + ">";
3474 }
3475};
3476
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003477/// Dereferenceable attribute for a floating value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003478struct AADereferenceableFloating
3479 : AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl> {
3480 using Base =
3481 AAFromMustBeExecutedContext<AADereferenceable, AADereferenceableImpl>;
3482 AADereferenceableFloating(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00003483
3484 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003485 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003486 ChangeStatus Change = Base::updateImpl(A);
3487
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003488 const DataLayout &DL = A.getDataLayout();
3489
3490 auto VisitValueCB = [&](Value &V, DerefState &T, bool Stripped) -> bool {
3491 unsigned IdxWidth =
3492 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
3493 APInt Offset(IdxWidth, 0);
3494 const Value *Base =
3495 V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
3496
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003497 const auto &AA =
3498 A.getAAFor<AADereferenceable>(*this, IRPosition::value(*Base));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003499 int64_t DerefBytes = 0;
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003500 if (!Stripped && this == &AA) {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003501 // Use IR information if we did not strip anything.
3502 // TODO: track globally.
3503 bool CanBeNull;
3504 DerefBytes = Base->getPointerDereferenceableBytes(DL, CanBeNull);
3505 T.GlobalState.indicatePessimisticFixpoint();
3506 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003507 const DerefState &DS = static_cast<const DerefState &>(AA.getState());
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003508 DerefBytes = DS.DerefBytesState.getAssumed();
3509 T.GlobalState &= DS.GlobalState;
3510 }
3511
Hideto Ueno188f9a32020-01-15 15:25:52 +09003512 // TODO: Use `AAConstantRange` to infer dereferenceable bytes.
3513
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003514 // For now we do not try to "increase" dereferenceability due to negative
3515 // indices as we first have to come up with code to deal with loops and
3516 // for overflows of the dereferenceable bytes.
Johannes Doerfert785fad32019-08-23 17:29:23 +00003517 int64_t OffsetSExt = Offset.getSExtValue();
3518 if (OffsetSExt < 0)
Johannes Doerfertdb6efb02019-10-13 20:40:10 +00003519 OffsetSExt = 0;
Johannes Doerfert2f2d7c32019-08-23 15:45:46 +00003520
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003521 T.takeAssumedDerefBytesMinimum(
Johannes Doerfert785fad32019-08-23 17:29:23 +00003522 std::max(int64_t(0), DerefBytes - OffsetSExt));
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003523
Johannes Doerfert785fad32019-08-23 17:29:23 +00003524 if (this == &AA) {
3525 if (!Stripped) {
3526 // If nothing was stripped IR information is all we got.
3527 T.takeKnownDerefBytesMaximum(
3528 std::max(int64_t(0), DerefBytes - OffsetSExt));
3529 T.indicatePessimisticFixpoint();
3530 } else if (OffsetSExt > 0) {
3531 // If something was stripped but there is circular reasoning we look
3532 // for the offset. If it is positive we basically decrease the
3533 // dereferenceable bytes in a circluar loop now, which will simply
3534 // drive them down to the known value in a very slow way which we
3535 // can accelerate.
3536 T.indicatePessimisticFixpoint();
3537 }
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003538 }
3539
3540 return T.isValidState();
3541 };
3542
3543 DerefState T;
3544 if (!genericValueTraversal<AADereferenceable, DerefState>(
3545 A, getIRPosition(), *this, T, VisitValueCB))
3546 return indicatePessimisticFixpoint();
3547
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003548 return Change | clampStateAndIndicateChange(getState(), T);
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003549 }
3550
3551 /// See AbstractAttribute::trackStatistics()
3552 void trackStatistics() const override {
3553 STATS_DECLTRACK_FLOATING_ATTR(dereferenceable)
3554 }
3555};
3556
3557/// Dereferenceable attribute for a return value.
3558struct AADereferenceableReturned final
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003559 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl> {
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003560 AADereferenceableReturned(const IRPosition &IRP)
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003561 : AAReturnedFromReturnedValues<AADereferenceable, AADereferenceableImpl>(
3562 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003563
3564 /// See AbstractAttribute::trackStatistics()
3565 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003566 STATS_DECLTRACK_FNRET_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003567 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003568};
3569
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003570/// Dereferenceable attribute for an argument
3571struct AADereferenceableArgument final
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003572 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003573 AADereferenceable, AADereferenceableImpl> {
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003574 using Base = AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<
Johannes Doerfert791c9f12020-01-29 18:02:42 -06003575 AADereferenceable, AADereferenceableImpl>;
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003576 AADereferenceableArgument(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003577
3578 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003579 void trackStatistics() const override {
Johannes Doerfert169af992019-08-20 06:09:56 +00003580 STATS_DECLTRACK_ARG_ATTR(dereferenceable)
3581 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003582};
3583
Hideto Ueno19c07af2019-07-23 08:16:17 +00003584/// Dereferenceable attribute for a call site argument.
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003585struct AADereferenceableCallSiteArgument final : AADereferenceableFloating {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003586 AADereferenceableCallSiteArgument(const IRPosition &IRP)
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003587 : AADereferenceableFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003588
3589 /// See AbstractAttribute::trackStatistics()
3590 void trackStatistics() const override {
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003591 STATS_DECLTRACK_CSARG_ATTR(dereferenceable)
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003592 }
Hideto Ueno19c07af2019-07-23 08:16:17 +00003593};
3594
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003595/// Dereferenceable attribute deduction for a call site return value.
Hideto Ueno96e6ce42019-10-08 15:25:56 +00003596struct AADereferenceableCallSiteReturned final
3597 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3598 AADereferenceable, AADereferenceableImpl> {
3599 using Base = AACallSiteReturnedFromReturnedAndMustBeExecutedContext<
3600 AADereferenceable, AADereferenceableImpl>;
3601 AADereferenceableCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003602
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003603 /// See AbstractAttribute::trackStatistics()
3604 void trackStatistics() const override {
3605 STATS_DECLTRACK_CS_ATTR(dereferenceable);
3606 }
3607};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003608
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003609// ------------------------ Align Argument Attribute ------------------------
3610
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003611static unsigned int getKnownAlignForUse(Attributor &A,
3612 AbstractAttribute &QueryingAA,
3613 Value &AssociatedValue, const Use *U,
3614 const Instruction *I, bool &TrackUse) {
Hideto Ueno78a75022019-11-26 07:51:59 +00003615 // We need to follow common pointer manipulation uses to the accesses they
3616 // feed into.
3617 if (isa<CastInst>(I)) {
Johannes Doerfertc90681b2020-01-02 16:41:17 -06003618 // Follow all but ptr2int casts.
3619 TrackUse = !isa<PtrToIntInst>(I);
Hideto Ueno78a75022019-11-26 07:51:59 +00003620 return 0;
3621 }
3622 if (auto *GEP = dyn_cast<GetElementPtrInst>(I)) {
3623 if (GEP->hasAllConstantIndices()) {
3624 TrackUse = true;
3625 return 0;
3626 }
3627 }
3628
3629 unsigned Alignment = 0;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003630 if (ImmutableCallSite ICS = ImmutableCallSite(I)) {
3631 if (ICS.isBundleOperand(U) || ICS.isCallee(U))
3632 return 0;
3633
3634 unsigned ArgNo = ICS.getArgumentNo(U);
3635 IRPosition IRP = IRPosition::callsite_argument(ICS, ArgNo);
3636 // As long as we only use known information there is no need to track
3637 // dependences here.
3638 auto &AlignAA = A.getAAFor<AAAlign>(QueryingAA, IRP,
3639 /* TrackDependence */ false);
Hideto Ueno78a75022019-11-26 07:51:59 +00003640 Alignment = AlignAA.getKnownAlign();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003641 }
3642
Hideto Ueno78a75022019-11-26 07:51:59 +00003643 const Value *UseV = U->get();
Johannes Doerfert30ae8592020-01-10 12:13:10 -06003644 if (auto *SI = dyn_cast<StoreInst>(I)) {
3645 if (SI->getPointerOperand() == UseV)
3646 Alignment = SI->getAlignment();
3647 } else if (auto *LI = dyn_cast<LoadInst>(I))
Hideto Ueno78a75022019-11-26 07:51:59 +00003648 Alignment = LI->getAlignment();
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003649
Hideto Ueno78a75022019-11-26 07:51:59 +00003650 if (Alignment <= 1)
3651 return 0;
3652
3653 auto &DL = A.getDataLayout();
3654 int64_t Offset;
3655
3656 if (const Value *Base = GetPointerBaseWithConstantOffset(UseV, Offset, DL)) {
3657 if (Base == &AssociatedValue) {
3658 // BasePointerAddr + Offset = Alignment * Q for some integer Q.
3659 // So we can say that the maximum power of two which is a divisor of
3660 // gcd(Offset, Alignment) is an alignment.
3661
3662 uint32_t gcd =
3663 greatestCommonDivisor(uint32_t(abs((int32_t)Offset)), Alignment);
3664 Alignment = llvm::PowerOf2Floor(gcd);
3665 }
3666 }
3667
3668 return Alignment;
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003669}
Johannes Doerfert344d0382019-08-07 22:34:26 +00003670struct AAAlignImpl : AAAlign {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003671 AAAlignImpl(const IRPosition &IRP) : AAAlign(IRP) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003672
Johannes Doerfert234eda52019-08-16 19:51:23 +00003673 /// See AbstractAttribute::initialize(...).
Johannes Doerfertece81902019-08-12 22:05:53 +00003674 void initialize(Attributor &A) override {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003675 SmallVector<Attribute, 4> Attrs;
3676 getAttrs({Attribute::Alignment}, Attrs);
3677 for (const Attribute &Attr : Attrs)
3678 takeKnownMaximum(Attr.getValueAsInt());
Johannes Doerfert97fd5822019-09-04 16:26:20 +00003679
3680 if (getIRPosition().isFnInterfaceKind() &&
3681 (!getAssociatedFunction() ||
3682 !getAssociatedFunction()->hasExactDefinition()))
3683 indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003684 }
3685
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003686 /// See AbstractAttribute::manifest(...).
3687 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003688 ChangeStatus LoadStoreChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003689
3690 // Check for users that allow alignment annotations.
3691 Value &AnchorVal = getIRPosition().getAnchorValue();
3692 for (const Use &U : AnchorVal.uses()) {
3693 if (auto *SI = dyn_cast<StoreInst>(U.getUser())) {
3694 if (SI->getPointerOperand() == &AnchorVal)
3695 if (SI->getAlignment() < getAssumedAlign()) {
3696 STATS_DECLTRACK(AAAlign, Store,
James Hendersond68904f2020-01-06 10:15:44 +00003697 "Number of times alignment added to a store");
Guillaume Chateletd400d452019-10-03 13:17:21 +00003698 SI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert30179d72020-01-12 00:25:45 -06003699 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003700 }
3701 } else if (auto *LI = dyn_cast<LoadInst>(U.getUser())) {
3702 if (LI->getPointerOperand() == &AnchorVal)
3703 if (LI->getAlignment() < getAssumedAlign()) {
Guillaume Chatelet17380222019-09-30 09:37:05 +00003704 LI->setAlignment(Align(getAssumedAlign()));
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003705 STATS_DECLTRACK(AAAlign, Load,
James Hendersond68904f2020-01-06 10:15:44 +00003706 "Number of times alignment added to a load");
Johannes Doerfert30179d72020-01-12 00:25:45 -06003707 LoadStoreChanged = ChangeStatus::CHANGED;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003708 }
3709 }
3710 }
3711
Johannes Doerfert30179d72020-01-12 00:25:45 -06003712 ChangeStatus Changed = AAAlign::manifest(A);
3713
3714 MaybeAlign InheritAlign =
3715 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3716 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3717 return LoadStoreChanged;
3718 return Changed | LoadStoreChanged;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003719 }
3720
Johannes Doerfert81df4522019-08-30 15:22:28 +00003721 // TODO: Provide a helper to determine the implied ABI alignment and check in
3722 // the existing manifest method and a new one for AAAlignImpl that value
3723 // to avoid making the alignment explicit if it did not improve.
3724
3725 /// See AbstractAttribute::getDeducedAttributes
3726 virtual void
3727 getDeducedAttributes(LLVMContext &Ctx,
3728 SmallVectorImpl<Attribute> &Attrs) const override {
3729 if (getAssumedAlign() > 1)
Guillaume Chateletb65fa482019-10-15 12:56:24 +00003730 Attrs.emplace_back(
3731 Attribute::getWithAlignment(Ctx, Align(getAssumedAlign())));
Johannes Doerfert81df4522019-08-30 15:22:28 +00003732 }
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003733 /// See AAFromMustBeExecutedContext
3734 bool followUse(Attributor &A, const Use *U, const Instruction *I) {
3735 bool TrackUse = false;
3736
Hideto Ueno4ecf2552019-12-12 13:42:40 +00003737 unsigned int KnownAlign =
3738 getKnownAlignForUse(A, *this, getAssociatedValue(), U, I, TrackUse);
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003739 takeKnownMaximum(KnownAlign);
3740
3741 return TrackUse;
3742 }
Johannes Doerfert81df4522019-08-30 15:22:28 +00003743
3744 /// See AbstractAttribute::getAsStr().
3745 const std::string getAsStr() const override {
3746 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
3747 "-" + std::to_string(getAssumedAlign()) + ">")
3748 : "unknown-align";
3749 }
3750};
3751
3752/// Align attribute for a floating value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003753struct AAAlignFloating : AAFromMustBeExecutedContext<AAAlign, AAAlignImpl> {
3754 using Base = AAFromMustBeExecutedContext<AAAlign, AAAlignImpl>;
3755 AAAlignFloating(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert81df4522019-08-30 15:22:28 +00003756
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003757 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert234eda52019-08-16 19:51:23 +00003758 ChangeStatus updateImpl(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003759 Base::updateImpl(A);
3760
Johannes Doerfert234eda52019-08-16 19:51:23 +00003761 const DataLayout &DL = A.getDataLayout();
3762
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003763 auto VisitValueCB = [&](Value &V, AAAlign::StateType &T,
3764 bool Stripped) -> bool {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003765 const auto &AA = A.getAAFor<AAAlign>(*this, IRPosition::value(V));
3766 if (!Stripped && this == &AA) {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003767 // Use only IR information if we did not strip anything.
Guillaume Chateletbae629b2019-10-15 13:58:22 +00003768 const MaybeAlign PA = V.getPointerAlignment(DL);
3769 T.takeKnownMaximum(PA ? PA->value() : 0);
Johannes Doerfert234eda52019-08-16 19:51:23 +00003770 T.indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003771 } else {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003772 // Use abstract attribute information.
3773 const AAAlign::StateType &DS =
3774 static_cast<const AAAlign::StateType &>(AA.getState());
3775 T ^= DS;
Johannes Doerfert234eda52019-08-16 19:51:23 +00003776 }
Johannes Doerfertb9b87912019-08-20 06:02:39 +00003777 return T.isValidState();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003778 };
3779
3780 StateType T;
3781 if (!genericValueTraversal<AAAlign, StateType>(A, getIRPosition(), *this, T,
3782 VisitValueCB))
Johannes Doerfertcfcca1a2019-08-20 06:08:35 +00003783 return indicatePessimisticFixpoint();
Johannes Doerfert234eda52019-08-16 19:51:23 +00003784
Johannes Doerfert028b2aa2019-08-20 05:57:01 +00003785 // TODO: If we know we visited all incoming values, thus no are assumed
3786 // dead, we can take the known information from the state T.
Johannes Doerfert234eda52019-08-16 19:51:23 +00003787 return clampStateAndIndicateChange(getState(), T);
3788 }
3789
3790 /// See AbstractAttribute::trackStatistics()
3791 void trackStatistics() const override { STATS_DECLTRACK_FLOATING_ATTR(align) }
3792};
3793
3794/// Align attribute for function return value.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003795struct AAAlignReturned final
3796 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003797 AAAlignReturned(const IRPosition &IRP)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003798 : AAReturnedFromReturnedValues<AAAlign, AAAlignImpl>(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003799
3800 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003801 void trackStatistics() const override { STATS_DECLTRACK_FNRET_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003802};
3803
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003804/// Align attribute for function argument.
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00003805struct AAAlignArgument final
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003806 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3807 AAAlignImpl> {
Johannes Doerfert234eda52019-08-16 19:51:23 +00003808 AAAlignArgument(const IRPosition &IRP)
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003809 : AAArgumentFromCallSiteArgumentsAndMustBeExecutedContext<AAAlign,
3810 AAAlignImpl>(
3811 IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003812
3813 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert169af992019-08-20 06:09:56 +00003814 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003815};
3816
Johannes Doerfert234eda52019-08-16 19:51:23 +00003817struct AAAlignCallSiteArgument final : AAAlignFloating {
3818 AAAlignCallSiteArgument(const IRPosition &IRP) : AAAlignFloating(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003819
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003820 /// See AbstractAttribute::manifest(...).
3821 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfert30179d72020-01-12 00:25:45 -06003822 ChangeStatus Changed = AAAlignImpl::manifest(A);
3823 MaybeAlign InheritAlign =
3824 getAssociatedValue().getPointerAlignment(A.getDataLayout());
3825 if (InheritAlign.valueOrOne() >= getAssumedAlign())
3826 Changed = ChangeStatus::UNCHANGED;
3827 return Changed;
Johannes Doerfert5a5a1392019-08-23 20:20:10 +00003828 }
3829
Johannes Doerfertdada8132019-12-31 01:27:50 -06003830 /// See AbstractAttribute::updateImpl(Attributor &A).
3831 ChangeStatus updateImpl(Attributor &A) override {
3832 ChangeStatus Changed = AAAlignFloating::updateImpl(A);
3833 if (Argument *Arg = getAssociatedArgument()) {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003834 // We only take known information from the argument
3835 // so we do not need to track a dependence.
Johannes Doerfertdada8132019-12-31 01:27:50 -06003836 const auto &ArgAlignAA = A.getAAFor<AAAlign>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06003837 *this, IRPosition::argument(*Arg), /* TrackDependence */ false);
Johannes Doerfertdada8132019-12-31 01:27:50 -06003838 takeKnownMaximum(ArgAlignAA.getKnownAlign());
3839 }
3840 return Changed;
3841 }
3842
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003843 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003844 void trackStatistics() const override { STATS_DECLTRACK_CSARG_ATTR(aligned) }
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00003845};
3846
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003847/// Align attribute deduction for a call site return value.
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003848struct AAAlignCallSiteReturned final
3849 : AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3850 AAAlignImpl> {
3851 using Base =
3852 AACallSiteReturnedFromReturnedAndMustBeExecutedContext<AAAlign,
3853 AAAlignImpl>;
3854 AAAlignCallSiteReturned(const IRPosition &IRP) : Base(IRP) {}
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003855
3856 /// See AbstractAttribute::initialize(...).
3857 void initialize(Attributor &A) override {
Hideto Ueno88b04ef2019-11-12 06:36:49 +00003858 Base::initialize(A);
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003859 Function *F = getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003860 if (!F)
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003861 indicatePessimisticFixpoint();
3862 }
3863
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003864 /// See AbstractAttribute::trackStatistics()
3865 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(align); }
3866};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003867
Johannes Doerferte83f3032019-08-05 23:22:05 +00003868/// ------------------ Function No-Return Attribute ----------------------------
Johannes Doerfert344d0382019-08-07 22:34:26 +00003869struct AANoReturnImpl : public AANoReturn {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003870 AANoReturnImpl(const IRPosition &IRP) : AANoReturn(IRP) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00003871
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003872 /// See AbstractAttribute::initialize(...).
3873 void initialize(Attributor &A) override {
3874 AANoReturn::initialize(A);
3875 Function *F = getAssociatedFunction();
Johannes Doerfert1b6041a2019-11-01 20:17:48 -05003876 if (!F)
Johannes Doerfert0cc2b612019-10-13 21:25:53 +00003877 indicatePessimisticFixpoint();
3878 }
3879
Johannes Doerferte83f3032019-08-05 23:22:05 +00003880 /// See AbstractAttribute::getAsStr().
3881 const std::string getAsStr() const override {
3882 return getAssumed() ? "noreturn" : "may-return";
3883 }
3884
Johannes Doerferte83f3032019-08-05 23:22:05 +00003885 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfertece81902019-08-12 22:05:53 +00003886 virtual ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003887 auto CheckForNoReturn = [](Instruction &) { return false; };
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003888 if (!A.checkForAllInstructions(CheckForNoReturn, *this,
Johannes Doerfertd0f64002019-08-06 00:32:43 +00003889 {(unsigned)Instruction::Ret}))
Johannes Doerferte83f3032019-08-05 23:22:05 +00003890 return indicatePessimisticFixpoint();
Johannes Doerferte83f3032019-08-05 23:22:05 +00003891 return ChangeStatus::UNCHANGED;
3892 }
3893};
3894
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003895struct AANoReturnFunction final : AANoReturnImpl {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00003896 AANoReturnFunction(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00003897
3898 /// See AbstractAttribute::trackStatistics()
Johannes Doerfert17b578b2019-08-14 21:46:25 +00003899 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(noreturn) }
Johannes Doerfertfb69f762019-08-05 23:32:31 +00003900};
3901
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003902/// NoReturn attribute deduction for a call sites.
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003903struct AANoReturnCallSite final : AANoReturnImpl {
3904 AANoReturnCallSite(const IRPosition &IRP) : AANoReturnImpl(IRP) {}
3905
Johannes Doerfert3fac6682019-08-30 15:24:52 +00003906 /// See AbstractAttribute::updateImpl(...).
3907 ChangeStatus updateImpl(Attributor &A) override {
3908 // TODO: Once we have call site specific value information we can provide
3909 // call site specific liveness information and then it makes
3910 // sense to specialize attributes for call sites arguments instead of
3911 // redirecting requests to the callee argument.
3912 Function *F = getAssociatedFunction();
3913 const IRPosition &FnPos = IRPosition::function(*F);
3914 auto &FnAA = A.getAAFor<AANoReturn>(*this, FnPos);
3915 return clampStateAndIndicateChange(
3916 getState(),
3917 static_cast<const AANoReturn::StateType &>(FnAA.getState()));
3918 }
3919
3920 /// See AbstractAttribute::trackStatistics()
3921 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(noreturn); }
3922};
Johannes Doerfert66cf87e2019-08-16 19:49:00 +00003923
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003924/// ----------------------- Variable Capturing ---------------------------------
3925
3926/// A class to hold the state of for no-capture attributes.
3927struct AANoCaptureImpl : public AANoCapture {
3928 AANoCaptureImpl(const IRPosition &IRP) : AANoCapture(IRP) {}
3929
3930 /// See AbstractAttribute::initialize(...).
3931 void initialize(Attributor &A) override {
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003932 if (hasAttr(getAttrKind(), /* IgnoreSubsumingPositions */ true)) {
3933 indicateOptimisticFixpoint();
3934 return;
3935 }
3936 Function *AnchorScope = getAnchorScope();
3937 if (isFnInterfaceKind() &&
3938 (!AnchorScope || !AnchorScope->hasExactDefinition())) {
3939 indicatePessimisticFixpoint();
3940 return;
3941 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003942
Johannes Doerfert72adda12019-10-10 05:33:21 +00003943 // You cannot "capture" null in the default address space.
3944 if (isa<ConstantPointerNull>(getAssociatedValue()) &&
3945 getAssociatedValue().getType()->getPointerAddressSpace() == 0) {
3946 indicateOptimisticFixpoint();
3947 return;
3948 }
3949
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003950 const Function *F = getArgNo() >= 0 ? getAssociatedFunction() : AnchorScope;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003951
3952 // Check what state the associated function can actually capture.
3953 if (F)
Johannes Doerfert0437bfc2019-10-31 20:03:13 -05003954 determineFunctionCaptureCapabilities(getIRPosition(), *F, *this);
Johannes Doerfertb0412e42019-09-04 16:16:13 +00003955 else
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003956 indicatePessimisticFixpoint();
3957 }
3958
3959 /// See AbstractAttribute::updateImpl(...).
3960 ChangeStatus updateImpl(Attributor &A) override;
3961
3962 /// see AbstractAttribute::isAssumedNoCaptureMaybeReturned(...).
3963 virtual void
3964 getDeducedAttributes(LLVMContext &Ctx,
3965 SmallVectorImpl<Attribute> &Attrs) const override {
3966 if (!isAssumedNoCaptureMaybeReturned())
3967 return;
3968
Hideto Ueno37367642019-09-11 06:52:11 +00003969 if (getArgNo() >= 0) {
3970 if (isAssumedNoCapture())
3971 Attrs.emplace_back(Attribute::get(Ctx, Attribute::NoCapture));
3972 else if (ManifestInternal)
3973 Attrs.emplace_back(Attribute::get(Ctx, "no-capture-maybe-returned"));
3974 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003975 }
3976
3977 /// Set the NOT_CAPTURED_IN_MEM and NOT_CAPTURED_IN_RET bits in \p Known
3978 /// depending on the ability of the function associated with \p IRP to capture
3979 /// state in memory and through "returning/throwing", respectively.
Johannes Doerfert3839b572019-10-21 00:48:42 +00003980 static void determineFunctionCaptureCapabilities(const IRPosition &IRP,
3981 const Function &F,
Johannes Doerfert1a746452019-10-20 22:28:49 -05003982 BitIntegerState &State) {
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00003983 // TODO: Once we have memory behavior attributes we should use them here.
3984
3985 // If we know we cannot communicate or write to memory, we do not care about
3986 // ptr2int anymore.
3987 if (F.onlyReadsMemory() && F.doesNotThrow() &&
3988 F.getReturnType()->isVoidTy()) {
3989 State.addKnownBits(NO_CAPTURE);
3990 return;
3991 }
3992
3993 // A function cannot capture state in memory if it only reads memory, it can
3994 // however return/throw state and the state might be influenced by the
3995 // pointer value, e.g., loading from a returned pointer might reveal a bit.
3996 if (F.onlyReadsMemory())
3997 State.addKnownBits(NOT_CAPTURED_IN_MEM);
3998
3999 // A function cannot communicate state back if it does not through
4000 // exceptions and doesn not return values.
4001 if (F.doesNotThrow() && F.getReturnType()->isVoidTy())
4002 State.addKnownBits(NOT_CAPTURED_IN_RET);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004003
4004 // Check existing "returned" attributes.
4005 int ArgNo = IRP.getArgNo();
4006 if (F.doesNotThrow() && ArgNo >= 0) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01004007 for (unsigned u = 0, e = F.arg_size(); u < e; ++u)
Johannes Doerfert3839b572019-10-21 00:48:42 +00004008 if (F.hasParamAttribute(u, Attribute::Returned)) {
Johannes Doerfert9d5ad5e2019-10-21 01:29:10 +00004009 if (u == unsigned(ArgNo))
Johannes Doerfert3839b572019-10-21 00:48:42 +00004010 State.removeAssumedBits(NOT_CAPTURED_IN_RET);
4011 else if (F.onlyReadsMemory())
4012 State.addKnownBits(NO_CAPTURE);
4013 else
4014 State.addKnownBits(NOT_CAPTURED_IN_RET);
4015 break;
4016 }
4017 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004018 }
4019
4020 /// See AbstractState::getAsStr().
4021 const std::string getAsStr() const override {
4022 if (isKnownNoCapture())
4023 return "known not-captured";
4024 if (isAssumedNoCapture())
4025 return "assumed not-captured";
4026 if (isKnownNoCaptureMaybeReturned())
4027 return "known not-captured-maybe-returned";
4028 if (isAssumedNoCaptureMaybeReturned())
4029 return "assumed not-captured-maybe-returned";
4030 return "assumed-captured";
4031 }
4032};
4033
4034/// Attributor-aware capture tracker.
4035struct AACaptureUseTracker final : public CaptureTracker {
4036
4037 /// Create a capture tracker that can lookup in-flight abstract attributes
4038 /// through the Attributor \p A.
4039 ///
4040 /// If a use leads to a potential capture, \p CapturedInMemory is set and the
4041 /// search is stopped. If a use leads to a return instruction,
4042 /// \p CommunicatedBack is set to true and \p CapturedInMemory is not changed.
4043 /// If a use leads to a ptr2int which may capture the value,
4044 /// \p CapturedInInteger is set. If a use is found that is currently assumed
4045 /// "no-capture-maybe-returned", the user is added to the \p PotentialCopies
4046 /// set. All values in \p PotentialCopies are later tracked as well. For every
4047 /// explored use we decrement \p RemainingUsesToExplore. Once it reaches 0,
4048 /// the search is stopped with \p CapturedInMemory and \p CapturedInInteger
4049 /// conservatively set to true.
4050 AACaptureUseTracker(Attributor &A, AANoCapture &NoCaptureAA,
Johannes Doerfert31784242019-10-29 23:18:49 -05004051 const AAIsDead &IsDeadAA, AANoCapture::StateType &State,
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004052 SmallVectorImpl<const Value *> &PotentialCopies,
4053 unsigned &RemainingUsesToExplore)
4054 : A(A), NoCaptureAA(NoCaptureAA), IsDeadAA(IsDeadAA), State(State),
4055 PotentialCopies(PotentialCopies),
4056 RemainingUsesToExplore(RemainingUsesToExplore) {}
4057
4058 /// Determine if \p V maybe captured. *Also updates the state!*
4059 bool valueMayBeCaptured(const Value *V) {
4060 if (V->getType()->isPointerTy()) {
4061 PointerMayBeCaptured(V, this);
4062 } else {
4063 State.indicatePessimisticFixpoint();
4064 }
4065 return State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4066 }
4067
4068 /// See CaptureTracker::tooManyUses().
4069 void tooManyUses() override {
4070 State.removeAssumedBits(AANoCapture::NO_CAPTURE);
4071 }
4072
4073 bool isDereferenceableOrNull(Value *O, const DataLayout &DL) override {
4074 if (CaptureTracker::isDereferenceableOrNull(O, DL))
4075 return true;
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004076 const auto &DerefAA = A.getAAFor<AADereferenceable>(
4077 NoCaptureAA, IRPosition::value(*O), /* TrackDependence */ true,
4078 DepClassTy::OPTIONAL);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004079 return DerefAA.getAssumedDereferenceableBytes();
4080 }
4081
4082 /// See CaptureTracker::captured(...).
4083 bool captured(const Use *U) override {
4084 Instruction *UInst = cast<Instruction>(U->getUser());
4085 LLVM_DEBUG(dbgs() << "Check use: " << *U->get() << " in " << *UInst
4086 << "\n");
4087
4088 // Because we may reuse the tracker multiple times we keep track of the
4089 // number of explored uses ourselves as well.
4090 if (RemainingUsesToExplore-- == 0) {
4091 LLVM_DEBUG(dbgs() << " - too many uses to explore!\n");
4092 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4093 /* Return */ true);
4094 }
4095
4096 // Deal with ptr2int by following uses.
4097 if (isa<PtrToIntInst>(UInst)) {
4098 LLVM_DEBUG(dbgs() << " - ptr2int assume the worst!\n");
4099 return valueMayBeCaptured(UInst);
4100 }
4101
4102 // Explicitly catch return instructions.
4103 if (isa<ReturnInst>(UInst))
4104 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4105 /* Return */ true);
4106
4107 // For now we only use special logic for call sites. However, the tracker
4108 // itself knows about a lot of other non-capturing cases already.
4109 CallSite CS(UInst);
4110 if (!CS || !CS.isArgOperand(U))
4111 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4112 /* Return */ true);
4113
4114 unsigned ArgNo = CS.getArgumentNo(U);
4115 const IRPosition &CSArgPos = IRPosition::callsite_argument(CS, ArgNo);
4116 // If we have a abstract no-capture attribute for the argument we can use
4117 // it to justify a non-capture attribute here. This allows recursion!
4118 auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(NoCaptureAA, CSArgPos);
4119 if (ArgNoCaptureAA.isAssumedNoCapture())
4120 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4121 /* Return */ false);
4122 if (ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
4123 addPotentialCopy(CS);
4124 return isCapturedIn(/* Memory */ false, /* Integer */ false,
4125 /* Return */ false);
4126 }
4127
4128 // Lastly, we could not find a reason no-capture can be assumed so we don't.
4129 return isCapturedIn(/* Memory */ true, /* Integer */ true,
4130 /* Return */ true);
4131 }
4132
4133 /// Register \p CS as potential copy of the value we are checking.
4134 void addPotentialCopy(CallSite CS) {
4135 PotentialCopies.push_back(CS.getInstruction());
4136 }
4137
4138 /// See CaptureTracker::shouldExplore(...).
4139 bool shouldExplore(const Use *U) override {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004140 // Check liveness, if it is used to stop exploring we need a dependence.
4141 if (IsDeadAA.isAssumedDead(cast<Instruction>(U->getUser()))) {
4142 A.recordDependence(IsDeadAA, NoCaptureAA, DepClassTy::OPTIONAL);
4143 return false;
4144 }
4145 return true;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004146 }
4147
4148 /// Update the state according to \p CapturedInMem, \p CapturedInInt, and
4149 /// \p CapturedInRet, then return the appropriate value for use in the
4150 /// CaptureTracker::captured() interface.
4151 bool isCapturedIn(bool CapturedInMem, bool CapturedInInt,
4152 bool CapturedInRet) {
4153 LLVM_DEBUG(dbgs() << " - captures [Mem " << CapturedInMem << "|Int "
4154 << CapturedInInt << "|Ret " << CapturedInRet << "]\n");
4155 if (CapturedInMem)
4156 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_MEM);
4157 if (CapturedInInt)
4158 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_INT);
4159 if (CapturedInRet)
4160 State.removeAssumedBits(AANoCapture::NOT_CAPTURED_IN_RET);
4161 return !State.isAssumed(AANoCapture::NO_CAPTURE_MAYBE_RETURNED);
4162 }
4163
4164private:
4165 /// The attributor providing in-flight abstract attributes.
4166 Attributor &A;
4167
4168 /// The abstract attribute currently updated.
4169 AANoCapture &NoCaptureAA;
4170
4171 /// The abstract liveness state.
4172 const AAIsDead &IsDeadAA;
4173
4174 /// The state currently updated.
Johannes Doerfert31784242019-10-29 23:18:49 -05004175 AANoCapture::StateType &State;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004176
4177 /// Set of potential copies of the tracked value.
4178 SmallVectorImpl<const Value *> &PotentialCopies;
4179
4180 /// Global counter to limit the number of explored uses.
4181 unsigned &RemainingUsesToExplore;
4182};
4183
4184ChangeStatus AANoCaptureImpl::updateImpl(Attributor &A) {
4185 const IRPosition &IRP = getIRPosition();
4186 const Value *V =
4187 getArgNo() >= 0 ? IRP.getAssociatedArgument() : &IRP.getAssociatedValue();
4188 if (!V)
4189 return indicatePessimisticFixpoint();
4190
4191 const Function *F =
4192 getArgNo() >= 0 ? IRP.getAssociatedFunction() : IRP.getAnchorScope();
4193 assert(F && "Expected a function!");
Johannes Doerfert3839b572019-10-21 00:48:42 +00004194 const IRPosition &FnPos = IRPosition::function(*F);
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004195 const auto &IsDeadAA =
4196 A.getAAFor<AAIsDead>(*this, FnPos, /* TrackDependence */ false);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004197
4198 AANoCapture::StateType T;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004199
Johannes Doerfert3839b572019-10-21 00:48:42 +00004200 // Readonly means we cannot capture through memory.
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004201 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(
4202 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004203 if (FnMemAA.isAssumedReadOnly()) {
4204 T.addKnownBits(NOT_CAPTURED_IN_MEM);
4205 if (FnMemAA.isKnownReadOnly())
4206 addKnownBits(NOT_CAPTURED_IN_MEM);
4207 }
4208
4209 // Make sure all returned values are different than the underlying value.
4210 // TODO: we could do this in a more sophisticated way inside
4211 // AAReturnedValues, e.g., track all values that escape through returns
4212 // directly somehow.
4213 auto CheckReturnedArgs = [&](const AAReturnedValues &RVAA) {
4214 bool SeenConstant = false;
4215 for (auto &It : RVAA.returned_values()) {
4216 if (isa<Constant>(It.first)) {
4217 if (SeenConstant)
4218 return false;
4219 SeenConstant = true;
4220 } else if (!isa<Argument>(It.first) ||
4221 It.first == getAssociatedArgument())
4222 return false;
4223 }
4224 return true;
4225 };
4226
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004227 const auto &NoUnwindAA = A.getAAFor<AANoUnwind>(
4228 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004229 if (NoUnwindAA.isAssumedNoUnwind()) {
4230 bool IsVoidTy = F->getReturnType()->isVoidTy();
4231 const AAReturnedValues *RVAA =
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06004232 IsVoidTy ? nullptr
4233 : &A.getAAFor<AAReturnedValues>(*this, FnPos,
4234 /* TrackDependence */ true,
4235 DepClassTy::OPTIONAL);
Johannes Doerfert3839b572019-10-21 00:48:42 +00004236 if (IsVoidTy || CheckReturnedArgs(*RVAA)) {
4237 T.addKnownBits(NOT_CAPTURED_IN_RET);
4238 if (T.isKnown(NOT_CAPTURED_IN_MEM))
4239 return ChangeStatus::UNCHANGED;
4240 if (NoUnwindAA.isKnownNoUnwind() &&
4241 (IsVoidTy || RVAA->getState().isAtFixpoint())) {
4242 addKnownBits(NOT_CAPTURED_IN_RET);
4243 if (isKnown(NOT_CAPTURED_IN_MEM))
4244 return indicateOptimisticFixpoint();
4245 }
4246 }
4247 }
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004248
4249 // Use the CaptureTracker interface and logic with the specialized tracker,
4250 // defined in AACaptureUseTracker, that can look at in-flight abstract
4251 // attributes and directly updates the assumed state.
4252 SmallVector<const Value *, 4> PotentialCopies;
4253 unsigned RemainingUsesToExplore = DefaultMaxUsesToExplore;
4254 AACaptureUseTracker Tracker(A, *this, IsDeadAA, T, PotentialCopies,
4255 RemainingUsesToExplore);
4256
4257 // Check all potential copies of the associated value until we can assume
4258 // none will be captured or we have to assume at least one might be.
4259 unsigned Idx = 0;
4260 PotentialCopies.push_back(V);
4261 while (T.isAssumed(NO_CAPTURE_MAYBE_RETURNED) && Idx < PotentialCopies.size())
4262 Tracker.valueMayBeCaptured(PotentialCopies[Idx++]);
4263
Johannes Doerfert1a746452019-10-20 22:28:49 -05004264 AANoCapture::StateType &S = getState();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004265 auto Assumed = S.getAssumed();
4266 S.intersectAssumedBits(T.getAssumed());
Johannes Doerfert31784242019-10-29 23:18:49 -05004267 if (!isAssumedNoCaptureMaybeReturned())
4268 return indicatePessimisticFixpoint();
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004269 return Assumed == S.getAssumed() ? ChangeStatus::UNCHANGED
4270 : ChangeStatus::CHANGED;
4271}
4272
4273/// NoCapture attribute for function arguments.
4274struct AANoCaptureArgument final : AANoCaptureImpl {
4275 AANoCaptureArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4276
4277 /// See AbstractAttribute::trackStatistics()
4278 void trackStatistics() const override { STATS_DECLTRACK_ARG_ATTR(nocapture) }
4279};
4280
4281/// NoCapture attribute for call site arguments.
4282struct AANoCaptureCallSiteArgument final : AANoCaptureImpl {
4283 AANoCaptureCallSiteArgument(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4284
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06004285 /// See AbstractAttribute::initialize(...).
4286 void initialize(Attributor &A) override {
4287 if (Argument *Arg = getAssociatedArgument())
4288 if (Arg->hasByValAttr())
4289 indicateOptimisticFixpoint();
4290 AANoCaptureImpl::initialize(A);
4291 }
4292
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00004293 /// See AbstractAttribute::updateImpl(...).
4294 ChangeStatus updateImpl(Attributor &A) override {
4295 // TODO: Once we have call site specific value information we can provide
4296 // call site specific liveness information and then it makes
4297 // sense to specialize attributes for call sites arguments instead of
4298 // redirecting requests to the callee argument.
4299 Argument *Arg = getAssociatedArgument();
4300 if (!Arg)
4301 return indicatePessimisticFixpoint();
4302 const IRPosition &ArgPos = IRPosition::argument(*Arg);
4303 auto &ArgAA = A.getAAFor<AANoCapture>(*this, ArgPos);
4304 return clampStateAndIndicateChange(
4305 getState(),
4306 static_cast<const AANoCapture::StateType &>(ArgAA.getState()));
4307 }
4308
4309 /// See AbstractAttribute::trackStatistics()
4310 void trackStatistics() const override{STATS_DECLTRACK_CSARG_ATTR(nocapture)};
4311};
4312
4313/// NoCapture attribute for floating values.
4314struct AANoCaptureFloating final : AANoCaptureImpl {
4315 AANoCaptureFloating(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4316
4317 /// See AbstractAttribute::trackStatistics()
4318 void trackStatistics() const override {
4319 STATS_DECLTRACK_FLOATING_ATTR(nocapture)
4320 }
4321};
4322
4323/// NoCapture attribute for function return value.
4324struct AANoCaptureReturned final : AANoCaptureImpl {
4325 AANoCaptureReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {
4326 llvm_unreachable("NoCapture is not applicable to function returns!");
4327 }
4328
4329 /// See AbstractAttribute::initialize(...).
4330 void initialize(Attributor &A) override {
4331 llvm_unreachable("NoCapture is not applicable to function returns!");
4332 }
4333
4334 /// See AbstractAttribute::updateImpl(...).
4335 ChangeStatus updateImpl(Attributor &A) override {
4336 llvm_unreachable("NoCapture is not applicable to function returns!");
4337 }
4338
4339 /// See AbstractAttribute::trackStatistics()
4340 void trackStatistics() const override {}
4341};
4342
4343/// NoCapture attribute deduction for a call site return value.
4344struct AANoCaptureCallSiteReturned final : AANoCaptureImpl {
4345 AANoCaptureCallSiteReturned(const IRPosition &IRP) : AANoCaptureImpl(IRP) {}
4346
4347 /// See AbstractAttribute::trackStatistics()
4348 void trackStatistics() const override {
4349 STATS_DECLTRACK_CSRET_ATTR(nocapture)
4350 }
4351};
4352
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004353/// ------------------ Value Simplify Attribute ----------------------------
4354struct AAValueSimplifyImpl : AAValueSimplify {
4355 AAValueSimplifyImpl(const IRPosition &IRP) : AAValueSimplify(IRP) {}
4356
Johannes Doerfert9dcf8892020-01-11 23:59:36 -06004357 /// See AbstractAttribute::initialize(...).
4358 void initialize(Attributor &A) override {
4359 if (getAssociatedValue().getType()->isVoidTy())
4360 indicatePessimisticFixpoint();
4361 }
4362
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004363 /// See AbstractAttribute::getAsStr().
4364 const std::string getAsStr() const override {
4365 return getAssumed() ? (getKnown() ? "simplified" : "maybe-simple")
4366 : "not-simple";
4367 }
4368
4369 /// See AbstractAttribute::trackStatistics()
4370 void trackStatistics() const override {}
4371
4372 /// See AAValueSimplify::getAssumedSimplifiedValue()
4373 Optional<Value *> getAssumedSimplifiedValue(Attributor &A) const override {
4374 if (!getAssumed())
4375 return const_cast<Value *>(&getAssociatedValue());
4376 return SimplifiedAssociatedValue;
4377 }
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004378
4379 /// Helper function for querying AAValueSimplify and updating candicate.
4380 /// \param QueryingValue Value trying to unify with SimplifiedValue
4381 /// \param AccumulatedSimplifiedValue Current simplification result.
4382 static bool checkAndUpdate(Attributor &A, const AbstractAttribute &QueryingAA,
4383 Value &QueryingValue,
4384 Optional<Value *> &AccumulatedSimplifiedValue) {
4385 // FIXME: Add a typecast support.
4386
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004387 auto &ValueSimplifyAA = A.getAAFor<AAValueSimplify>(
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004388 QueryingAA, IRPosition::value(QueryingValue));
4389
4390 Optional<Value *> QueryingValueSimplified =
Johannes Doerfertd07b5a52020-01-12 00:00:33 -06004391 ValueSimplifyAA.getAssumedSimplifiedValue(A);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004392
4393 if (!QueryingValueSimplified.hasValue())
4394 return true;
4395
4396 if (!QueryingValueSimplified.getValue())
4397 return false;
4398
4399 Value &QueryingValueSimplifiedUnwrapped =
4400 *QueryingValueSimplified.getValue();
4401
4402 if (isa<UndefValue>(QueryingValueSimplifiedUnwrapped))
4403 return true;
4404
4405 if (AccumulatedSimplifiedValue.hasValue())
4406 return AccumulatedSimplifiedValue == QueryingValueSimplified;
4407
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004408 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << QueryingValue
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004409 << " is assumed to be "
4410 << QueryingValueSimplifiedUnwrapped << "\n");
4411
4412 AccumulatedSimplifiedValue = QueryingValueSimplified;
4413 return true;
4414 }
4415
Hideto Ueno188f9a32020-01-15 15:25:52 +09004416 bool askSimplifiedValueForAAValueConstantRange(Attributor &A) {
4417 if (!getAssociatedValue().getType()->isIntegerTy())
4418 return false;
4419
4420 const auto &ValueConstantRangeAA =
4421 A.getAAFor<AAValueConstantRange>(*this, getIRPosition());
4422
4423 Optional<ConstantInt *> COpt =
4424 ValueConstantRangeAA.getAssumedConstantInt(A);
4425 if (COpt.hasValue()) {
4426 if (auto *C = COpt.getValue())
4427 SimplifiedAssociatedValue = C;
4428 else
4429 return false;
4430 } else {
Johannes Doerfert63adbb92020-02-09 20:21:56 -06004431 SimplifiedAssociatedValue = llvm::None;
Hideto Ueno188f9a32020-01-15 15:25:52 +09004432 }
4433 return true;
4434 }
4435
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004436 /// See AbstractAttribute::manifest(...).
4437 ChangeStatus manifest(Attributor &A) override {
4438 ChangeStatus Changed = ChangeStatus::UNCHANGED;
4439
4440 if (!SimplifiedAssociatedValue.hasValue() ||
4441 !SimplifiedAssociatedValue.getValue())
4442 return Changed;
4443
4444 if (auto *C = dyn_cast<Constant>(SimplifiedAssociatedValue.getValue())) {
4445 // We can replace the AssociatedValue with the constant.
4446 Value &V = getAssociatedValue();
4447 if (!V.user_empty() && &V != C && V.getType() == C->getType()) {
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004448 LLVM_DEBUG(dbgs() << "[ValueSimplify] " << V << " -> " << *C
4449 << " :: " << *this << "\n");
Johannes Doerfert4c62a352020-01-12 00:17:08 -06004450 if (A.changeValueAfterManifest(V, *C))
4451 Changed = ChangeStatus::CHANGED;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004452 }
4453 }
4454
4455 return Changed | AAValueSimplify::manifest(A);
4456 }
4457
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004458 /// See AbstractState::indicatePessimisticFixpoint(...).
4459 ChangeStatus indicatePessimisticFixpoint() override {
4460 // NOTE: Associated value will be returned in a pessimistic fixpoint and is
4461 // regarded as known. That's why`indicateOptimisticFixpoint` is called.
4462 SimplifiedAssociatedValue = &getAssociatedValue();
Johannes Doerferta4b35882019-12-31 13:25:47 -06004463 indicateOptimisticFixpoint();
4464 return ChangeStatus::CHANGED;
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004465 }
4466
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004467protected:
4468 // An assumed simplified value. Initially, it is set to Optional::None, which
4469 // means that the value is not clear under current assumption. If in the
4470 // pessimistic state, getAssumedSimplifiedValue doesn't return this value but
4471 // returns orignal associated value.
4472 Optional<Value *> SimplifiedAssociatedValue;
4473};
4474
4475struct AAValueSimplifyArgument final : AAValueSimplifyImpl {
4476 AAValueSimplifyArgument(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4477
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004478 void initialize(Attributor &A) override {
4479 AAValueSimplifyImpl::initialize(A);
4480 if (!getAssociatedFunction() || getAssociatedFunction()->isDeclaration())
4481 indicatePessimisticFixpoint();
4482 if (hasAttr({Attribute::InAlloca, Attribute::StructRet, Attribute::Nest},
4483 /* IgnoreSubsumingPositions */ true))
4484 indicatePessimisticFixpoint();
4485 }
4486
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004487 /// See AbstractAttribute::updateImpl(...).
4488 ChangeStatus updateImpl(Attributor &A) override {
Johannes Doerfert15cd90a2019-11-01 13:42:54 -05004489 // Byval is only replacable if it is readonly otherwise we would write into
4490 // the replaced value and not the copy that byval creates implicitly.
4491 Argument *Arg = getAssociatedArgument();
4492 if (Arg->hasByValAttr()) {
4493 const auto &MemAA = A.getAAFor<AAMemoryBehavior>(*this, getIRPosition());
4494 if (!MemAA.isAssumedReadOnly())
4495 return indicatePessimisticFixpoint();
4496 }
4497
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004498 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4499
Johannes Doerfert661db042019-10-07 23:14:58 +00004500 auto PredForCallSite = [&](AbstractCallSite ACS) {
4501 // Check if we have an associated argument or not (which can happen for
4502 // callback calls).
Johannes Doerferte360ee62019-11-01 18:45:25 -05004503 Value *ArgOp = ACS.getCallArgOperand(getArgNo());
4504 if (!ArgOp)
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004505 return false;
Johannes Doerferte360ee62019-11-01 18:45:25 -05004506 // We can only propagate thread independent values through callbacks.
4507 // This is different to direct/indirect call sites because for them we
4508 // know the thread executing the caller and callee is the same. For
4509 // callbacks this is not guaranteed, thus a thread dependent value could
4510 // be different for the caller and callee, making it invalid to propagate.
4511 if (ACS.isCallbackCall())
Hideto Ueno4ecf2552019-12-12 13:42:40 +00004512 if (auto *C = dyn_cast<Constant>(ArgOp))
Johannes Doerferte360ee62019-11-01 18:45:25 -05004513 if (C->isThreadDependent())
4514 return false;
4515 return checkAndUpdate(A, *this, *ArgOp, SimplifiedAssociatedValue);
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004516 };
4517
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004518 bool AllCallSitesKnown;
4519 if (!A.checkForAllCallSites(PredForCallSite, *this, true,
4520 AllCallSitesKnown))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004521 if (!askSimplifiedValueForAAValueConstantRange(A))
4522 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004523
4524 // If a candicate was found in this update, return CHANGED.
4525 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4526 ? ChangeStatus::UNCHANGED
4527 : ChangeStatus ::CHANGED;
4528 }
4529
4530 /// See AbstractAttribute::trackStatistics()
4531 void trackStatistics() const override {
4532 STATS_DECLTRACK_ARG_ATTR(value_simplify)
4533 }
4534};
4535
4536struct AAValueSimplifyReturned : AAValueSimplifyImpl {
4537 AAValueSimplifyReturned(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4538
4539 /// See AbstractAttribute::updateImpl(...).
4540 ChangeStatus updateImpl(Attributor &A) override {
4541 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4542
4543 auto PredForReturned = [&](Value &V) {
4544 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4545 };
4546
4547 if (!A.checkForAllReturnedValues(PredForReturned, *this))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004548 if (!askSimplifiedValueForAAValueConstantRange(A))
4549 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004550
4551 // If a candicate was found in this update, return CHANGED.
4552 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4553 ? ChangeStatus::UNCHANGED
4554 : ChangeStatus ::CHANGED;
4555 }
4556 /// See AbstractAttribute::trackStatistics()
4557 void trackStatistics() const override {
4558 STATS_DECLTRACK_FNRET_ATTR(value_simplify)
4559 }
4560};
4561
4562struct AAValueSimplifyFloating : AAValueSimplifyImpl {
4563 AAValueSimplifyFloating(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4564
4565 /// See AbstractAttribute::initialize(...).
4566 void initialize(Attributor &A) override {
4567 Value &V = getAnchorValue();
4568
4569 // TODO: add other stuffs
Hideto Ueno1d5d0742019-12-25 14:14:32 +09004570 if (isa<Constant>(V))
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004571 indicatePessimisticFixpoint();
4572 }
4573
4574 /// See AbstractAttribute::updateImpl(...).
4575 ChangeStatus updateImpl(Attributor &A) override {
4576 bool HasValueBefore = SimplifiedAssociatedValue.hasValue();
4577
Johannes Doerfert76843ba2020-01-28 23:51:25 -06004578 auto VisitValueCB = [&](Value &V, bool &, bool Stripped) -> bool {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004579 auto &AA = A.getAAFor<AAValueSimplify>(*this, IRPosition::value(V));
4580 if (!Stripped && this == &AA) {
4581 // TODO: Look the instruction and check recursively.
Hideto Ueno188f9a32020-01-15 15:25:52 +09004582
Johannes Doerfert02bd8182020-01-28 11:49:35 -06004583 LLVM_DEBUG(dbgs() << "[ValueSimplify] Can't be stripped more : " << V
4584 << "\n");
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004585 return false;
4586 }
4587 return checkAndUpdate(A, *this, V, SimplifiedAssociatedValue);
4588 };
4589
Johannes Doerfert76843ba2020-01-28 23:51:25 -06004590 bool Dummy = false;
Johannes Doerfert6626d1b2020-01-28 11:49:59 -06004591 if (!genericValueTraversal<AAValueSimplify, bool>(A, getIRPosition(), *this,
4592 Dummy, VisitValueCB))
Hideto Ueno188f9a32020-01-15 15:25:52 +09004593 if (!askSimplifiedValueForAAValueConstantRange(A))
4594 return indicatePessimisticFixpoint();
Hideto Uenof2b9dc42019-09-07 07:03:05 +00004595
4596 // If a candicate was found in this update, return CHANGED.
4597
4598 return HasValueBefore == SimplifiedAssociatedValue.hasValue()
4599 ? ChangeStatus::UNCHANGED
4600 : ChangeStatus ::CHANGED;
4601 }
4602
4603 /// See AbstractAttribute::trackStatistics()
4604 void trackStatistics() const override {
4605 STATS_DECLTRACK_FLOATING_ATTR(value_simplify)
4606 }
4607};
4608
4609struct AAValueSimplifyFunction : AAValueSimplifyImpl {
4610 AAValueSimplifyFunction(const IRPosition &IRP) : AAValueSimplifyImpl(IRP) {}
4611
4612 /// See AbstractAttribute::initialize(...).
4613 void initialize(Attributor &A) override {
4614 SimplifiedAssociatedValue = &getAnchorValue();
4615 indicateOptimisticFixpoint();
4616 }
4617 /// See AbstractAttribute::initialize(...).
4618 ChangeStatus updateImpl(Attributor &A) override {
4619 llvm_unreachable(
4620 "AAValueSimplify(Function|CallSite)::updateImpl will not be called");
4621 }
4622 /// See AbstractAttribute::trackStatistics()
4623 void trackStatistics() const override {
4624 STATS_DECLTRACK_FN_ATTR(value_simplify)
4625 }
4626};
4627
4628struct AAValueSimplifyCallSite : AAValueSimplifyFunction {
4629 AAValueSimplifyCallSite(const IRPosition &IRP)
4630 : AAValueSimplifyFunction(IRP) {}
4631 /// See AbstractAttribute::trackStatistics()
4632 void trackStatistics() const override {
4633 STATS_DECLTRACK_CS_ATTR(value_simplify)
4634 }
4635};
4636
4637struct AAValueSimplifyCallSiteReturned : AAValueSimplifyReturned {
4638 AAValueSimplifyCallSiteReturned(const IRPosition &IRP)
4639 : AAValueSimplifyReturned(IRP) {}
4640
4641 void trackStatistics() const override {
4642 STATS_DECLTRACK_CSRET_ATTR(value_simplify)
4643 }
4644};
4645struct AAValueSimplifyCallSiteArgument : AAValueSimplifyFloating {
4646 AAValueSimplifyCallSiteArgument(const IRPosition &IRP)
4647 : AAValueSimplifyFloating(IRP) {}
4648
4649 void trackStatistics() const override {
4650 STATS_DECLTRACK_CSARG_ATTR(value_simplify)
4651 }
4652};
4653
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004654/// ----------------------- Heap-To-Stack Conversion ---------------------------
4655struct AAHeapToStackImpl : public AAHeapToStack {
4656 AAHeapToStackImpl(const IRPosition &IRP) : AAHeapToStack(IRP) {}
4657
4658 const std::string getAsStr() const override {
4659 return "[H2S] Mallocs: " + std::to_string(MallocCalls.size());
4660 }
4661
4662 ChangeStatus manifest(Attributor &A) override {
4663 assert(getState().isValidState() &&
4664 "Attempted to manifest an invalid state!");
4665
4666 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
4667 Function *F = getAssociatedFunction();
4668 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4669
4670 for (Instruction *MallocCall : MallocCalls) {
4671 // This malloc cannot be replaced.
4672 if (BadMallocCalls.count(MallocCall))
4673 continue;
4674
4675 for (Instruction *FreeCall : FreesForMalloc[MallocCall]) {
4676 LLVM_DEBUG(dbgs() << "H2S: Removing free call: " << *FreeCall << "\n");
4677 A.deleteAfterManifest(*FreeCall);
4678 HasChanged = ChangeStatus::CHANGED;
4679 }
4680
4681 LLVM_DEBUG(dbgs() << "H2S: Removing malloc call: " << *MallocCall
4682 << "\n");
4683
4684 Constant *Size;
4685 if (isCallocLikeFn(MallocCall, TLI)) {
4686 auto *Num = cast<ConstantInt>(MallocCall->getOperand(0));
4687 auto *SizeT = dyn_cast<ConstantInt>(MallocCall->getOperand(1));
4688 APInt TotalSize = SizeT->getValue() * Num->getValue();
4689 Size =
4690 ConstantInt::get(MallocCall->getOperand(0)->getType(), TotalSize);
4691 } else {
4692 Size = cast<ConstantInt>(MallocCall->getOperand(0));
4693 }
4694
4695 unsigned AS = cast<PointerType>(MallocCall->getType())->getAddressSpace();
4696 Instruction *AI = new AllocaInst(Type::getInt8Ty(F->getContext()), AS,
4697 Size, "", MallocCall->getNextNode());
4698
4699 if (AI->getType() != MallocCall->getType())
4700 AI = new BitCastInst(AI, MallocCall->getType(), "malloc_bc",
4701 AI->getNextNode());
4702
Johannes Doerfert4c62a352020-01-12 00:17:08 -06004703 A.changeValueAfterManifest(*MallocCall, *AI);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004704
4705 if (auto *II = dyn_cast<InvokeInst>(MallocCall)) {
4706 auto *NBB = II->getNormalDest();
4707 BranchInst::Create(NBB, MallocCall->getParent());
4708 A.deleteAfterManifest(*MallocCall);
4709 } else {
4710 A.deleteAfterManifest(*MallocCall);
4711 }
4712
4713 if (isCallocLikeFn(MallocCall, TLI)) {
4714 auto *BI = new BitCastInst(AI, MallocCall->getType(), "calloc_bc",
4715 AI->getNextNode());
4716 Value *Ops[] = {
4717 BI, ConstantInt::get(F->getContext(), APInt(8, 0, false)), Size,
4718 ConstantInt::get(Type::getInt1Ty(F->getContext()), false)};
4719
4720 Type *Tys[] = {BI->getType(), MallocCall->getOperand(0)->getType()};
4721 Module *M = F->getParent();
4722 Function *Fn = Intrinsic::getDeclaration(M, Intrinsic::memset, Tys);
4723 CallInst::Create(Fn, Ops, "", BI->getNextNode());
4724 }
4725 HasChanged = ChangeStatus::CHANGED;
4726 }
4727
4728 return HasChanged;
4729 }
4730
4731 /// Collection of all malloc calls in a function.
4732 SmallSetVector<Instruction *, 4> MallocCalls;
4733
4734 /// Collection of malloc calls that cannot be converted.
4735 DenseSet<const Instruction *> BadMallocCalls;
4736
4737 /// A map for each malloc call to the set of associated free calls.
4738 DenseMap<Instruction *, SmallPtrSet<Instruction *, 4>> FreesForMalloc;
4739
4740 ChangeStatus updateImpl(Attributor &A) override;
4741};
4742
4743ChangeStatus AAHeapToStackImpl::updateImpl(Attributor &A) {
4744 const Function *F = getAssociatedFunction();
4745 const auto *TLI = A.getInfoCache().getTargetLibraryInfoForFunction(*F);
4746
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004747 MustBeExecutedContextExplorer &Explorer =
4748 A.getInfoCache().getMustBeExecutedContextExplorer();
4749
4750 auto FreeCheck = [&](Instruction &I) {
4751 const auto &Frees = FreesForMalloc.lookup(&I);
4752 if (Frees.size() != 1)
4753 return false;
4754 Instruction *UniqueFree = *Frees.begin();
4755 return Explorer.findInContextOf(UniqueFree, I.getNextNode());
4756 };
4757
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004758 auto UsesCheck = [&](Instruction &I) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004759 bool ValidUsesOnly = true;
4760 bool MustUse = true;
Hideto Ueno827bade2019-12-12 12:26:30 +00004761 auto Pred = [&](const Use &U, bool &Follow) -> bool {
4762 Instruction *UserI = cast<Instruction>(U.getUser());
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004763 if (isa<LoadInst>(UserI))
Hideto Ueno827bade2019-12-12 12:26:30 +00004764 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004765 if (auto *SI = dyn_cast<StoreInst>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004766 if (SI->getValueOperand() == U.get()) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004767 LLVM_DEBUG(dbgs()
4768 << "[H2S] escaping store to memory: " << *UserI << "\n");
4769 ValidUsesOnly = false;
4770 } else {
4771 // A store into the malloc'ed memory is fine.
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004772 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004773 return true;
Johannes Doerfertaf6e4792019-10-13 04:14:15 +00004774 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004775 if (auto *CB = dyn_cast<CallBase>(UserI)) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004776 if (!CB->isArgOperand(&U) || CB->isLifetimeStartOrEnd())
4777 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004778 // Record malloc.
4779 if (isFreeCall(UserI, TLI)) {
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004780 if (MustUse) {
Hideto Ueno827bade2019-12-12 12:26:30 +00004781 FreesForMalloc[&I].insert(UserI);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004782 } else {
4783 LLVM_DEBUG(dbgs() << "[H2S] free potentially on different mallocs: "
4784 << *UserI << "\n");
4785 ValidUsesOnly = false;
4786 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004787 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004788 }
4789
Hideto Ueno827bade2019-12-12 12:26:30 +00004790 unsigned ArgNo = CB->getArgOperandNo(&U);
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004791
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004792 const auto &NoCaptureAA = A.getAAFor<AANoCapture>(
4793 *this, IRPosition::callsite_argument(*CB, ArgNo));
4794
Stefan Stipanovica516fba2019-11-17 21:35:04 +01004795 // If a callsite argument use is nofree, we are fine.
4796 const auto &ArgNoFreeAA = A.getAAFor<AANoFree>(
4797 *this, IRPosition::callsite_argument(*CB, ArgNo));
4798
Hideto Ueno827bade2019-12-12 12:26:30 +00004799 if (!NoCaptureAA.isAssumedNoCapture() ||
4800 !ArgNoFreeAA.isAssumedNoFree()) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004801 LLVM_DEBUG(dbgs() << "[H2S] Bad user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004802 ValidUsesOnly = false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004803 }
Hideto Ueno827bade2019-12-12 12:26:30 +00004804 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004805 }
4806
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004807 if (isa<GetElementPtrInst>(UserI) || isa<BitCastInst>(UserI) ||
4808 isa<PHINode>(UserI) || isa<SelectInst>(UserI)) {
4809 MustUse &= !(isa<PHINode>(UserI) || isa<SelectInst>(UserI));
Hideto Ueno827bade2019-12-12 12:26:30 +00004810 Follow = true;
4811 return true;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004812 }
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004813 // Unknown user for which we can not track uses further (in a way that
4814 // makes sense).
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004815 LLVM_DEBUG(dbgs() << "[H2S] Unknown user: " << *UserI << "\n");
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004816 ValidUsesOnly = false;
Hideto Ueno827bade2019-12-12 12:26:30 +00004817 return true;
4818 };
4819 A.checkForAllUses(Pred, *this, I);
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004820 return ValidUsesOnly;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004821 };
4822
4823 auto MallocCallocCheck = [&](Instruction &I) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004824 if (BadMallocCalls.count(&I))
4825 return true;
4826
4827 bool IsMalloc = isMallocLikeFn(&I, TLI);
4828 bool IsCalloc = !IsMalloc && isCallocLikeFn(&I, TLI);
4829 if (!IsMalloc && !IsCalloc) {
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004830 BadMallocCalls.insert(&I);
4831 return true;
4832 }
4833
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004834 if (IsMalloc) {
4835 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(0)))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004836 if (Size->getValue().ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004837 if (UsesCheck(I) || FreeCheck(I)) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004838 MallocCalls.insert(&I);
4839 return true;
4840 }
4841 } else if (IsCalloc) {
4842 bool Overflow = false;
4843 if (auto *Num = dyn_cast<ConstantInt>(I.getOperand(0)))
4844 if (auto *Size = dyn_cast<ConstantInt>(I.getOperand(1)))
4845 if ((Size->getValue().umul_ov(Num->getValue(), Overflow))
Stefan Stipanovicfff8ec92019-12-17 20:41:09 +01004846 .ule(MaxHeapToStackSize))
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004847 if (!Overflow && (UsesCheck(I) || FreeCheck(I))) {
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004848 MallocCalls.insert(&I);
4849 return true;
4850 }
4851 }
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004852
Johannes Doerfertd20f8072019-10-13 03:54:08 +00004853 BadMallocCalls.insert(&I);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004854 return true;
4855 };
4856
4857 size_t NumBadMallocs = BadMallocCalls.size();
4858
4859 A.checkForAllCallLikeInstructions(MallocCallocCheck, *this);
4860
4861 if (NumBadMallocs != BadMallocCalls.size())
4862 return ChangeStatus::CHANGED;
4863
4864 return ChangeStatus::UNCHANGED;
4865}
4866
4867struct AAHeapToStackFunction final : public AAHeapToStackImpl {
4868 AAHeapToStackFunction(const IRPosition &IRP) : AAHeapToStackImpl(IRP) {}
4869
4870 /// See AbstractAttribute::trackStatistics()
4871 void trackStatistics() const override {
4872 STATS_DECL(MallocCalls, Function,
Johannes Doerfert0be9cf22019-10-14 17:29:05 -05004873 "Number of malloc calls converted to allocas");
4874 for (auto *C : MallocCalls)
4875 if (!BadMallocCalls.count(C))
4876 ++BUILD_STAT_NAME(MallocCalls, Function);
Stefan Stipanovic431141c2019-09-15 21:47:41 +00004877 }
4878};
4879
Johannes Doerfert89c2e732019-10-30 17:20:20 -05004880/// ----------------------- Privatizable Pointers ------------------------------
4881struct AAPrivatizablePtrImpl : public AAPrivatizablePtr {
4882 AAPrivatizablePtrImpl(const IRPosition &IRP)
4883 : AAPrivatizablePtr(IRP), PrivatizableType(llvm::None) {}
4884
4885 ChangeStatus indicatePessimisticFixpoint() override {
4886 AAPrivatizablePtr::indicatePessimisticFixpoint();
4887 PrivatizableType = nullptr;
4888 return ChangeStatus::CHANGED;
4889 }
4890
4891 /// Identify the type we can chose for a private copy of the underlying
4892 /// argument. None means it is not clear yet, nullptr means there is none.
4893 virtual Optional<Type *> identifyPrivatizableType(Attributor &A) = 0;
4894
4895 /// Return a privatizable type that encloses both T0 and T1.
4896 /// TODO: This is merely a stub for now as we should manage a mapping as well.
4897 Optional<Type *> combineTypes(Optional<Type *> T0, Optional<Type *> T1) {
4898 if (!T0.hasValue())
4899 return T1;
4900 if (!T1.hasValue())
4901 return T0;
4902 if (T0 == T1)
4903 return T0;
4904 return nullptr;
4905 }
4906
4907 Optional<Type *> getPrivatizableType() const override {
4908 return PrivatizableType;
4909 }
4910
4911 const std::string getAsStr() const override {
4912 return isAssumedPrivatizablePtr() ? "[priv]" : "[no-priv]";
4913 }
4914
4915protected:
4916 Optional<Type *> PrivatizableType;
4917};
4918
4919// TODO: Do this for call site arguments (probably also other values) as well.
4920
4921struct AAPrivatizablePtrArgument final : public AAPrivatizablePtrImpl {
4922 AAPrivatizablePtrArgument(const IRPosition &IRP)
4923 : AAPrivatizablePtrImpl(IRP) {}
4924
4925 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
4926 Optional<Type *> identifyPrivatizableType(Attributor &A) override {
4927 // If this is a byval argument and we know all the call sites (so we can
4928 // rewrite them), there is no need to check them explicitly.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004929 bool AllCallSitesKnown;
Johannes Doerfert89c2e732019-10-30 17:20:20 -05004930 if (getIRPosition().hasAttr(Attribute::ByVal) &&
4931 A.checkForAllCallSites([](AbstractCallSite ACS) { return true; }, *this,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004932 true, AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05004933 return getAssociatedValue().getType()->getPointerElementType();
4934
4935 Optional<Type *> Ty;
4936 unsigned ArgNo = getIRPosition().getArgNo();
4937
4938 // Make sure the associated call site argument has the same type at all call
4939 // sites and it is an allocation we know is safe to privatize, for now that
4940 // means we only allow alloca instructions.
4941 // TODO: We can additionally analyze the accesses in the callee to create
4942 // the type from that information instead. That is a little more
4943 // involved and will be done in a follow up patch.
4944 auto CallSiteCheck = [&](AbstractCallSite ACS) {
4945 IRPosition ACSArgPos = IRPosition::callsite_argument(ACS, ArgNo);
4946 // Check if a coresponding argument was found or if it is one not
4947 // associated (which can happen for callback calls).
4948 if (ACSArgPos.getPositionKind() == IRPosition::IRP_INVALID)
4949 return false;
4950
4951 // Check that all call sites agree on a type.
4952 auto &PrivCSArgAA = A.getAAFor<AAPrivatizablePtr>(*this, ACSArgPos);
4953 Optional<Type *> CSTy = PrivCSArgAA.getPrivatizableType();
4954
4955 LLVM_DEBUG({
4956 dbgs() << "[AAPrivatizablePtr] ACSPos: " << ACSArgPos << ", CSTy: ";
4957 if (CSTy.hasValue() && CSTy.getValue())
4958 CSTy.getValue()->print(dbgs());
4959 else if (CSTy.hasValue())
4960 dbgs() << "<nullptr>";
4961 else
4962 dbgs() << "<none>";
4963 });
4964
4965 Ty = combineTypes(Ty, CSTy);
4966
4967 LLVM_DEBUG({
4968 dbgs() << " : New Type: ";
4969 if (Ty.hasValue() && Ty.getValue())
4970 Ty.getValue()->print(dbgs());
4971 else if (Ty.hasValue())
4972 dbgs() << "<nullptr>";
4973 else
4974 dbgs() << "<none>";
4975 dbgs() << "\n";
4976 });
4977
4978 return !Ty.hasValue() || Ty.getValue();
4979 };
4980
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06004981 if (!A.checkForAllCallSites(CallSiteCheck, *this, true, AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05004982 return nullptr;
4983 return Ty;
4984 }
4985
4986 /// See AbstractAttribute::updateImpl(...).
4987 ChangeStatus updateImpl(Attributor &A) override {
4988 PrivatizableType = identifyPrivatizableType(A);
4989 if (!PrivatizableType.hasValue())
4990 return ChangeStatus::UNCHANGED;
4991 if (!PrivatizableType.getValue())
4992 return indicatePessimisticFixpoint();
4993
4994 // Avoid arguments with padding for now.
4995 if (!getIRPosition().hasAttr(Attribute::ByVal) &&
4996 !ArgumentPromotionPass::isDenselyPacked(PrivatizableType.getValue(),
4997 A.getInfoCache().getDL())) {
4998 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Padding detected\n");
4999 return indicatePessimisticFixpoint();
5000 }
5001
5002 // Verify callee and caller agree on how the promoted argument would be
5003 // passed.
5004 // TODO: The use of the ArgumentPromotion interface here is ugly, we need a
5005 // specialized form of TargetTransformInfo::areFunctionArgsABICompatible
5006 // which doesn't require the arguments ArgumentPromotion wanted to pass.
5007 Function &Fn = *getIRPosition().getAnchorScope();
5008 SmallPtrSet<Argument *, 1> ArgsToPromote, Dummy;
5009 ArgsToPromote.insert(getAssociatedArgument());
5010 const auto *TTI =
5011 A.getInfoCache().getAnalysisResultForFunction<TargetIRAnalysis>(Fn);
5012 if (!TTI ||
5013 !ArgumentPromotionPass::areFunctionArgsABICompatible(
5014 Fn, *TTI, ArgsToPromote, Dummy) ||
5015 ArgsToPromote.empty()) {
5016 LLVM_DEBUG(
5017 dbgs() << "[AAPrivatizablePtr] ABI incompatibility detected for "
5018 << Fn.getName() << "\n");
5019 return indicatePessimisticFixpoint();
5020 }
5021
5022 // Collect the types that will replace the privatizable type in the function
5023 // signature.
5024 SmallVector<Type *, 16> ReplacementTypes;
5025 identifyReplacementTypes(PrivatizableType.getValue(), ReplacementTypes);
5026
5027 // Register a rewrite of the argument.
5028 Argument *Arg = getAssociatedArgument();
5029 if (!A.isValidFunctionSignatureRewrite(*Arg, ReplacementTypes)) {
5030 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Rewrite not valid\n");
5031 return indicatePessimisticFixpoint();
5032 }
5033
5034 unsigned ArgNo = Arg->getArgNo();
5035
5036 // Helper to check if for the given call site the associated argument is
5037 // passed to a callback where the privatization would be different.
5038 auto IsCompatiblePrivArgOfCallback = [&](CallSite CS) {
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005039 SmallVector<const Use *, 4> CBUses;
5040 AbstractCallSite::getCallbackUses(CS, CBUses);
5041 for (const Use *U : CBUses) {
5042 AbstractCallSite CBACS(U);
5043 assert(CBACS && CBACS.isCallbackCall());
5044 for (Argument &CBArg : CBACS.getCalledFunction()->args()) {
5045 int CBArgNo = CBACS.getCallArgOperandNo(CBArg);
5046
5047 LLVM_DEBUG({
5048 dbgs()
5049 << "[AAPrivatizablePtr] Argument " << *Arg
5050 << "check if can be privatized in the context of its parent ("
5051 << Arg->getParent()->getName()
5052 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5053 "callback ("
5054 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
5055 << ")\n[AAPrivatizablePtr] " << CBArg << " : "
Michael Forster676c2962020-01-30 10:20:49 +01005056 << CBACS.getCallArgOperand(CBArg) << " vs "
5057 << CS.getArgOperand(ArgNo) << "\n"
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005058 << "[AAPrivatizablePtr] " << CBArg << " : "
5059 << CBACS.getCallArgOperandNo(CBArg) << " vs " << ArgNo << "\n";
5060 });
5061
5062 if (CBArgNo != int(ArgNo))
5063 continue;
5064 const auto &CBArgPrivAA =
5065 A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(CBArg));
5066 if (CBArgPrivAA.isValidState()) {
5067 auto CBArgPrivTy = CBArgPrivAA.getPrivatizableType();
5068 if (!CBArgPrivTy.hasValue())
5069 continue;
5070 if (CBArgPrivTy.getValue() == PrivatizableType)
5071 continue;
5072 }
5073
5074 LLVM_DEBUG({
5075 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5076 << " cannot be privatized in the context of its parent ("
5077 << Arg->getParent()->getName()
5078 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5079 "callback ("
5080 << CBArgNo << "@" << CBACS.getCalledFunction()->getName()
5081 << ").\n[AAPrivatizablePtr] for which the argument "
5082 "privatization is not compatible.\n";
5083 });
5084 return false;
5085 }
5086 }
5087 return true;
5088 };
5089
5090 // Helper to check if for the given call site the associated argument is
5091 // passed to a direct call where the privatization would be different.
5092 auto IsCompatiblePrivArgOfDirectCS = [&](AbstractCallSite ACS) {
5093 CallBase *DC = cast<CallBase>(ACS.getInstruction());
5094 int DCArgNo = ACS.getCallArgOperandNo(ArgNo);
5095 assert(DCArgNo >= 0 && unsigned(DCArgNo) < DC->getNumArgOperands() &&
5096 "Expected a direct call operand for callback call operand");
5097
5098 LLVM_DEBUG({
5099 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5100 << " check if be privatized in the context of its parent ("
5101 << Arg->getParent()->getName()
5102 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5103 "direct call of ("
5104 << DCArgNo << "@" << DC->getCalledFunction()->getName()
5105 << ").\n";
5106 });
5107
5108 Function *DCCallee = DC->getCalledFunction();
5109 if (unsigned(DCArgNo) < DCCallee->arg_size()) {
5110 const auto &DCArgPrivAA = A.getAAFor<AAPrivatizablePtr>(
5111 *this, IRPosition::argument(*DCCallee->getArg(DCArgNo)));
5112 if (DCArgPrivAA.isValidState()) {
5113 auto DCArgPrivTy = DCArgPrivAA.getPrivatizableType();
5114 if (!DCArgPrivTy.hasValue())
5115 return true;
5116 if (DCArgPrivTy.getValue() == PrivatizableType)
5117 return true;
5118 }
5119 }
5120
5121 LLVM_DEBUG({
5122 dbgs() << "[AAPrivatizablePtr] Argument " << *Arg
5123 << " cannot be privatized in the context of its parent ("
5124 << Arg->getParent()->getName()
5125 << ")\n[AAPrivatizablePtr] because it is an argument in a "
5126 "direct call of ("
5127 << ACS.getCallSite().getCalledFunction()->getName()
5128 << ").\n[AAPrivatizablePtr] for which the argument "
5129 "privatization is not compatible.\n";
5130 });
5131 return false;
5132 };
5133
5134 // Helper to check if the associated argument is used at the given abstract
5135 // call site in a way that is incompatible with the privatization assumed
5136 // here.
5137 auto IsCompatiblePrivArgOfOtherCallSite = [&](AbstractCallSite ACS) {
5138 if (ACS.isDirectCall())
5139 return IsCompatiblePrivArgOfCallback(ACS.getCallSite());
5140 if (ACS.isCallbackCall())
5141 return IsCompatiblePrivArgOfDirectCS(ACS);
5142 return false;
5143 };
5144
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06005145 bool AllCallSitesKnown;
5146 if (!A.checkForAllCallSites(IsCompatiblePrivArgOfOtherCallSite, *this, true,
5147 AllCallSitesKnown))
Johannes Doerfert89c2e732019-10-30 17:20:20 -05005148 return indicatePessimisticFixpoint();
5149
5150 return ChangeStatus::UNCHANGED;
5151 }
5152
5153 /// Given a type to private \p PrivType, collect the constituates (which are
5154 /// used) in \p ReplacementTypes.
5155 static void
5156 identifyReplacementTypes(Type *PrivType,
5157 SmallVectorImpl<Type *> &ReplacementTypes) {
5158 // TODO: For now we expand the privatization type to the fullest which can
5159 // lead to dead arguments that need to be removed later.
5160 assert(PrivType && "Expected privatizable type!");
5161
5162 // Traverse the type, extract constituate types on the outermost level.
5163 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5164 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++)
5165 ReplacementTypes.push_back(PrivStructType->getElementType(u));
5166 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5167 ReplacementTypes.append(PrivArrayType->getNumElements(),
5168 PrivArrayType->getElementType());
5169 } else {
5170 ReplacementTypes.push_back(PrivType);
5171 }
5172 }
5173
5174 /// Initialize \p Base according to the type \p PrivType at position \p IP.
5175 /// The values needed are taken from the arguments of \p F starting at
5176 /// position \p ArgNo.
5177 static void createInitialization(Type *PrivType, Value &Base, Function &F,
5178 unsigned ArgNo, Instruction &IP) {
5179 assert(PrivType && "Expected privatizable type!");
5180
5181 IRBuilder<NoFolder> IRB(&IP);
5182 const DataLayout &DL = F.getParent()->getDataLayout();
5183
5184 // Traverse the type, build GEPs and stores.
5185 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5186 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
5187 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
5188 Type *PointeeTy = PrivStructType->getElementType(u)->getPointerTo();
5189 Value *Ptr = constructPointer(
5190 PointeeTy, &Base, PrivStructLayout->getElementOffset(u), IRB, DL);
5191 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
5192 }
5193 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5194 Type *PointeePtrTy = PrivArrayType->getElementType()->getPointerTo();
5195 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeePtrTy);
5196 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
5197 Value *Ptr =
5198 constructPointer(PointeePtrTy, &Base, u * PointeeTySize, IRB, DL);
5199 new StoreInst(F.getArg(ArgNo + u), Ptr, &IP);
5200 }
5201 } else {
5202 new StoreInst(F.getArg(ArgNo), &Base, &IP);
5203 }
5204 }
5205
5206 /// Extract values from \p Base according to the type \p PrivType at the
5207 /// call position \p ACS. The values are appended to \p ReplacementValues.
5208 void createReplacementValues(Type *PrivType, AbstractCallSite ACS,
5209 Value *Base,
5210 SmallVectorImpl<Value *> &ReplacementValues) {
5211 assert(Base && "Expected base value!");
5212 assert(PrivType && "Expected privatizable type!");
5213 Instruction *IP = ACS.getInstruction();
5214
5215 IRBuilder<NoFolder> IRB(IP);
5216 const DataLayout &DL = IP->getModule()->getDataLayout();
5217
5218 if (Base->getType()->getPointerElementType() != PrivType)
5219 Base = BitCastInst::CreateBitOrPointerCast(Base, PrivType->getPointerTo(),
5220 "", ACS.getInstruction());
5221
5222 // TODO: Improve the alignment of the loads.
5223 // Traverse the type, build GEPs and loads.
5224 if (auto *PrivStructType = dyn_cast<StructType>(PrivType)) {
5225 const StructLayout *PrivStructLayout = DL.getStructLayout(PrivStructType);
5226 for (unsigned u = 0, e = PrivStructType->getNumElements(); u < e; u++) {
5227 Type *PointeeTy = PrivStructType->getElementType(u);
5228 Value *Ptr =
5229 constructPointer(PointeeTy->getPointerTo(), Base,
5230 PrivStructLayout->getElementOffset(u), IRB, DL);
5231 LoadInst *L = new LoadInst(PointeeTy, Ptr, "", IP);
5232 L->setAlignment(MaybeAlign(1));
5233 ReplacementValues.push_back(L);
5234 }
5235 } else if (auto *PrivArrayType = dyn_cast<ArrayType>(PrivType)) {
5236 Type *PointeeTy = PrivArrayType->getElementType();
5237 uint64_t PointeeTySize = DL.getTypeStoreSize(PointeeTy);
5238 Type *PointeePtrTy = PointeeTy->getPointerTo();
5239 for (unsigned u = 0, e = PrivArrayType->getNumElements(); u < e; u++) {
5240 Value *Ptr =
5241 constructPointer(PointeePtrTy, Base, u * PointeeTySize, IRB, DL);
5242 LoadInst *L = new LoadInst(PointeePtrTy, Ptr, "", IP);
5243 L->setAlignment(MaybeAlign(1));
5244 ReplacementValues.push_back(L);
5245 }
5246 } else {
5247 LoadInst *L = new LoadInst(PrivType, Base, "", IP);
5248 L->setAlignment(MaybeAlign(1));
5249 ReplacementValues.push_back(L);
5250 }
5251 }
5252
5253 /// See AbstractAttribute::manifest(...)
5254 ChangeStatus manifest(Attributor &A) override {
5255 if (!PrivatizableType.hasValue())
5256 return ChangeStatus::UNCHANGED;
5257 assert(PrivatizableType.getValue() && "Expected privatizable type!");
5258
5259 // Collect all tail calls in the function as we cannot allow new allocas to
5260 // escape into tail recursion.
5261 // TODO: Be smarter about new allocas escaping into tail calls.
5262 SmallVector<CallInst *, 16> TailCalls;
5263 if (!A.checkForAllInstructions(
5264 [&](Instruction &I) {
5265 CallInst &CI = cast<CallInst>(I);
5266 if (CI.isTailCall())
5267 TailCalls.push_back(&CI);
5268 return true;
5269 },
5270 *this, {Instruction::Call}))
5271 return ChangeStatus::UNCHANGED;
5272
5273 Argument *Arg = getAssociatedArgument();
5274
5275 // Callback to repair the associated function. A new alloca is placed at the
5276 // beginning and initialized with the values passed through arguments. The
5277 // new alloca replaces the use of the old pointer argument.
5278 Attributor::ArgumentReplacementInfo::CalleeRepairCBTy FnRepairCB =
5279 [=](const Attributor::ArgumentReplacementInfo &ARI,
5280 Function &ReplacementFn, Function::arg_iterator ArgIt) {
5281 BasicBlock &EntryBB = ReplacementFn.getEntryBlock();
5282 Instruction *IP = &*EntryBB.getFirstInsertionPt();
5283 auto *AI = new AllocaInst(PrivatizableType.getValue(), 0,
5284 Arg->getName() + ".priv", IP);
5285 createInitialization(PrivatizableType.getValue(), *AI, ReplacementFn,
5286 ArgIt->getArgNo(), *IP);
5287 Arg->replaceAllUsesWith(AI);
5288
5289 for (CallInst *CI : TailCalls)
5290 CI->setTailCall(false);
5291 };
5292
5293 // Callback to repair a call site of the associated function. The elements
5294 // of the privatizable type are loaded prior to the call and passed to the
5295 // new function version.
5296 Attributor::ArgumentReplacementInfo::ACSRepairCBTy ACSRepairCB =
5297 [=](const Attributor::ArgumentReplacementInfo &ARI,
5298 AbstractCallSite ACS, SmallVectorImpl<Value *> &NewArgOperands) {
5299 createReplacementValues(
5300 PrivatizableType.getValue(), ACS,
5301 ACS.getCallArgOperand(ARI.getReplacedArg().getArgNo()),
5302 NewArgOperands);
5303 };
5304
5305 // Collect the types that will replace the privatizable type in the function
5306 // signature.
5307 SmallVector<Type *, 16> ReplacementTypes;
5308 identifyReplacementTypes(PrivatizableType.getValue(), ReplacementTypes);
5309
5310 // Register a rewrite of the argument.
5311 if (A.registerFunctionSignatureRewrite(*Arg, ReplacementTypes,
5312 std::move(FnRepairCB),
5313 std::move(ACSRepairCB)))
5314 return ChangeStatus::CHANGED;
5315 return ChangeStatus::UNCHANGED;
5316 }
5317
5318 /// See AbstractAttribute::trackStatistics()
5319 void trackStatistics() const override {
5320 STATS_DECLTRACK_ARG_ATTR(privatizable_ptr);
5321 }
5322};
5323
5324struct AAPrivatizablePtrFloating : public AAPrivatizablePtrImpl {
5325 AAPrivatizablePtrFloating(const IRPosition &IRP)
5326 : AAPrivatizablePtrImpl(IRP) {}
5327
5328 /// See AbstractAttribute::initialize(...).
5329 virtual void initialize(Attributor &A) override {
5330 // TODO: We can privatize more than arguments.
5331 indicatePessimisticFixpoint();
5332 }
5333
5334 ChangeStatus updateImpl(Attributor &A) override {
5335 llvm_unreachable("AAPrivatizablePtr(Floating|Returned|CallSiteReturned)::"
5336 "updateImpl will not be called");
5337 }
5338
5339 /// See AAPrivatizablePtrImpl::identifyPrivatizableType(...)
5340 Optional<Type *> identifyPrivatizableType(Attributor &A) override {
5341 Value *Obj =
5342 GetUnderlyingObject(&getAssociatedValue(), A.getInfoCache().getDL());
5343 if (!Obj) {
5344 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] No underlying object found!\n");
5345 return nullptr;
5346 }
5347
5348 if (auto *AI = dyn_cast<AllocaInst>(Obj))
5349 if (auto *CI = dyn_cast<ConstantInt>(AI->getArraySize()))
5350 if (CI->isOne())
5351 return Obj->getType()->getPointerElementType();
5352 if (auto *Arg = dyn_cast<Argument>(Obj)) {
5353 auto &PrivArgAA =
5354 A.getAAFor<AAPrivatizablePtr>(*this, IRPosition::argument(*Arg));
5355 if (PrivArgAA.isAssumedPrivatizablePtr())
5356 return Obj->getType()->getPointerElementType();
5357 }
5358
5359 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] Underlying object neither valid "
5360 "alloca nor privatizable argument: "
5361 << *Obj << "!\n");
5362 return nullptr;
5363 }
5364
5365 /// See AbstractAttribute::trackStatistics()
5366 void trackStatistics() const override {
5367 STATS_DECLTRACK_FLOATING_ATTR(privatizable_ptr);
5368 }
5369};
5370
5371struct AAPrivatizablePtrCallSiteArgument final
5372 : public AAPrivatizablePtrFloating {
5373 AAPrivatizablePtrCallSiteArgument(const IRPosition &IRP)
5374 : AAPrivatizablePtrFloating(IRP) {}
5375
5376 /// See AbstractAttribute::initialize(...).
5377 void initialize(Attributor &A) override {
5378 if (getIRPosition().hasAttr(Attribute::ByVal))
5379 indicateOptimisticFixpoint();
5380 }
5381
5382 /// See AbstractAttribute::updateImpl(...).
5383 ChangeStatus updateImpl(Attributor &A) override {
5384 PrivatizableType = identifyPrivatizableType(A);
5385 if (!PrivatizableType.hasValue())
5386 return ChangeStatus::UNCHANGED;
5387 if (!PrivatizableType.getValue())
5388 return indicatePessimisticFixpoint();
5389
5390 const IRPosition &IRP = getIRPosition();
5391 auto &NoCaptureAA = A.getAAFor<AANoCapture>(*this, IRP);
5392 if (!NoCaptureAA.isAssumedNoCapture()) {
5393 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might be captured!\n");
5394 return indicatePessimisticFixpoint();
5395 }
5396
5397 auto &NoAliasAA = A.getAAFor<AANoAlias>(*this, IRP);
5398 if (!NoAliasAA.isAssumedNoAlias()) {
5399 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer might alias!\n");
5400 return indicatePessimisticFixpoint();
5401 }
5402
5403 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(*this, IRP);
5404 if (!MemBehaviorAA.isAssumedReadOnly()) {
5405 LLVM_DEBUG(dbgs() << "[AAPrivatizablePtr] pointer is written!\n");
5406 return indicatePessimisticFixpoint();
5407 }
5408
5409 return ChangeStatus::UNCHANGED;
5410 }
5411
5412 /// See AbstractAttribute::trackStatistics()
5413 void trackStatistics() const override {
5414 STATS_DECLTRACK_CSARG_ATTR(privatizable_ptr);
5415 }
5416};
5417
5418struct AAPrivatizablePtrCallSiteReturned final
5419 : public AAPrivatizablePtrFloating {
5420 AAPrivatizablePtrCallSiteReturned(const IRPosition &IRP)
5421 : AAPrivatizablePtrFloating(IRP) {}
5422
5423 /// See AbstractAttribute::initialize(...).
5424 void initialize(Attributor &A) override {
5425 // TODO: We can privatize more than arguments.
5426 indicatePessimisticFixpoint();
5427 }
5428
5429 /// See AbstractAttribute::trackStatistics()
5430 void trackStatistics() const override {
5431 STATS_DECLTRACK_CSRET_ATTR(privatizable_ptr);
5432 }
5433};
5434
5435struct AAPrivatizablePtrReturned final : public AAPrivatizablePtrFloating {
5436 AAPrivatizablePtrReturned(const IRPosition &IRP)
5437 : AAPrivatizablePtrFloating(IRP) {}
5438
5439 /// See AbstractAttribute::initialize(...).
5440 void initialize(Attributor &A) override {
5441 // TODO: We can privatize more than arguments.
5442 indicatePessimisticFixpoint();
5443 }
5444
5445 /// See AbstractAttribute::trackStatistics()
5446 void trackStatistics() const override {
5447 STATS_DECLTRACK_FNRET_ATTR(privatizable_ptr);
5448 }
5449};
5450
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005451/// -------------------- Memory Behavior Attributes ----------------------------
5452/// Includes read-none, read-only, and write-only.
5453/// ----------------------------------------------------------------------------
5454struct AAMemoryBehaviorImpl : public AAMemoryBehavior {
5455 AAMemoryBehaviorImpl(const IRPosition &IRP) : AAMemoryBehavior(IRP) {}
5456
5457 /// See AbstractAttribute::initialize(...).
5458 void initialize(Attributor &A) override {
5459 intersectAssumedBits(BEST_STATE);
5460 getKnownStateFromValue(getIRPosition(), getState());
5461 IRAttribute::initialize(A);
5462 }
5463
5464 /// Return the memory behavior information encoded in the IR for \p IRP.
5465 static void getKnownStateFromValue(const IRPosition &IRP,
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005466 BitIntegerState &State,
5467 bool IgnoreSubsumingPositions = false) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005468 SmallVector<Attribute, 2> Attrs;
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005469 IRP.getAttrs(AttrKinds, Attrs, IgnoreSubsumingPositions);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005470 for (const Attribute &Attr : Attrs) {
5471 switch (Attr.getKindAsEnum()) {
5472 case Attribute::ReadNone:
5473 State.addKnownBits(NO_ACCESSES);
5474 break;
5475 case Attribute::ReadOnly:
5476 State.addKnownBits(NO_WRITES);
5477 break;
5478 case Attribute::WriteOnly:
5479 State.addKnownBits(NO_READS);
5480 break;
5481 default:
5482 llvm_unreachable("Unexpcted attribute!");
5483 }
5484 }
5485
5486 if (auto *I = dyn_cast<Instruction>(&IRP.getAnchorValue())) {
5487 if (!I->mayReadFromMemory())
5488 State.addKnownBits(NO_READS);
5489 if (!I->mayWriteToMemory())
5490 State.addKnownBits(NO_WRITES);
5491 }
5492 }
5493
5494 /// See AbstractAttribute::getDeducedAttributes(...).
5495 void getDeducedAttributes(LLVMContext &Ctx,
5496 SmallVectorImpl<Attribute> &Attrs) const override {
5497 assert(Attrs.size() == 0);
5498 if (isAssumedReadNone())
5499 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadNone));
5500 else if (isAssumedReadOnly())
5501 Attrs.push_back(Attribute::get(Ctx, Attribute::ReadOnly));
5502 else if (isAssumedWriteOnly())
5503 Attrs.push_back(Attribute::get(Ctx, Attribute::WriteOnly));
5504 assert(Attrs.size() <= 1);
5505 }
5506
5507 /// See AbstractAttribute::manifest(...).
5508 ChangeStatus manifest(Attributor &A) override {
Johannes Doerfertb2083c52019-10-20 22:46:48 -05005509 const IRPosition &IRP = getIRPosition();
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005510
5511 // Check if we would improve the existing attributes first.
5512 SmallVector<Attribute, 4> DeducedAttrs;
5513 getDeducedAttributes(IRP.getAnchorValue().getContext(), DeducedAttrs);
5514 if (llvm::all_of(DeducedAttrs, [&](const Attribute &Attr) {
5515 return IRP.hasAttr(Attr.getKindAsEnum(),
5516 /* IgnoreSubsumingPositions */ true);
5517 }))
5518 return ChangeStatus::UNCHANGED;
5519
5520 // Clear existing attributes.
5521 IRP.removeAttrs(AttrKinds);
5522
5523 // Use the generic manifest method.
5524 return IRAttribute::manifest(A);
5525 }
5526
5527 /// See AbstractState::getAsStr().
5528 const std::string getAsStr() const override {
5529 if (isAssumedReadNone())
5530 return "readnone";
5531 if (isAssumedReadOnly())
5532 return "readonly";
5533 if (isAssumedWriteOnly())
5534 return "writeonly";
5535 return "may-read/write";
5536 }
5537
5538 /// The set of IR attributes AAMemoryBehavior deals with.
5539 static const Attribute::AttrKind AttrKinds[3];
5540};
5541
5542const Attribute::AttrKind AAMemoryBehaviorImpl::AttrKinds[] = {
5543 Attribute::ReadNone, Attribute::ReadOnly, Attribute::WriteOnly};
5544
5545/// Memory behavior attribute for a floating value.
5546struct AAMemoryBehaviorFloating : AAMemoryBehaviorImpl {
5547 AAMemoryBehaviorFloating(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5548
5549 /// See AbstractAttribute::initialize(...).
5550 void initialize(Attributor &A) override {
5551 AAMemoryBehaviorImpl::initialize(A);
5552 // Initialize the use vector with all direct uses of the associated value.
5553 for (const Use &U : getAssociatedValue().uses())
5554 Uses.insert(&U);
5555 }
5556
5557 /// See AbstractAttribute::updateImpl(...).
5558 ChangeStatus updateImpl(Attributor &A) override;
5559
5560 /// See AbstractAttribute::trackStatistics()
5561 void trackStatistics() const override {
5562 if (isAssumedReadNone())
5563 STATS_DECLTRACK_FLOATING_ATTR(readnone)
5564 else if (isAssumedReadOnly())
5565 STATS_DECLTRACK_FLOATING_ATTR(readonly)
5566 else if (isAssumedWriteOnly())
5567 STATS_DECLTRACK_FLOATING_ATTR(writeonly)
5568 }
5569
5570private:
5571 /// Return true if users of \p UserI might access the underlying
5572 /// variable/location described by \p U and should therefore be analyzed.
5573 bool followUsersOfUseIn(Attributor &A, const Use *U,
5574 const Instruction *UserI);
5575
5576 /// Update the state according to the effect of use \p U in \p UserI.
5577 void analyzeUseIn(Attributor &A, const Use *U, const Instruction *UserI);
5578
5579protected:
5580 /// Container for (transitive) uses of the associated argument.
5581 SetVector<const Use *> Uses;
5582};
5583
5584/// Memory behavior attribute for function argument.
5585struct AAMemoryBehaviorArgument : AAMemoryBehaviorFloating {
5586 AAMemoryBehaviorArgument(const IRPosition &IRP)
5587 : AAMemoryBehaviorFloating(IRP) {}
5588
5589 /// See AbstractAttribute::initialize(...).
5590 void initialize(Attributor &A) override {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005591 intersectAssumedBits(BEST_STATE);
5592 const IRPosition &IRP = getIRPosition();
5593 // TODO: Make IgnoreSubsumingPositions a property of an IRAttribute so we
5594 // can query it when we use has/getAttr. That would allow us to reuse the
5595 // initialize of the base class here.
5596 bool HasByVal =
5597 IRP.hasAttr({Attribute::ByVal}, /* IgnoreSubsumingPositions */ true);
5598 getKnownStateFromValue(IRP, getState(),
5599 /* IgnoreSubsumingPositions */ HasByVal);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005600
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005601 // Initialize the use vector with all direct uses of the associated value.
5602 Argument *Arg = getAssociatedArgument();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005603 if (!Arg || !Arg->getParent()->hasExactDefinition()) {
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005604 indicatePessimisticFixpoint();
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005605 } else {
5606 // Initialize the use vector with all direct uses of the associated value.
5607 for (const Use &U : Arg->uses())
5608 Uses.insert(&U);
5609 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005610 }
5611
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005612 ChangeStatus manifest(Attributor &A) override {
5613 // TODO: From readattrs.ll: "inalloca parameters are always
5614 // considered written"
5615 if (hasAttr({Attribute::InAlloca})) {
5616 removeKnownBits(NO_WRITES);
5617 removeAssumedBits(NO_WRITES);
5618 }
5619 return AAMemoryBehaviorFloating::manifest(A);
5620 }
5621
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005622 /// See AbstractAttribute::trackStatistics()
5623 void trackStatistics() const override {
5624 if (isAssumedReadNone())
5625 STATS_DECLTRACK_ARG_ATTR(readnone)
5626 else if (isAssumedReadOnly())
5627 STATS_DECLTRACK_ARG_ATTR(readonly)
5628 else if (isAssumedWriteOnly())
5629 STATS_DECLTRACK_ARG_ATTR(writeonly)
5630 }
5631};
5632
5633struct AAMemoryBehaviorCallSiteArgument final : AAMemoryBehaviorArgument {
5634 AAMemoryBehaviorCallSiteArgument(const IRPosition &IRP)
5635 : AAMemoryBehaviorArgument(IRP) {}
5636
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005637 /// See AbstractAttribute::initialize(...).
5638 void initialize(Attributor &A) override {
5639 if (Argument *Arg = getAssociatedArgument()) {
5640 if (Arg->hasByValAttr()) {
5641 addKnownBits(NO_WRITES);
5642 removeKnownBits(NO_READS);
5643 removeAssumedBits(NO_READS);
5644 }
5645 } else {
5646 }
5647 AAMemoryBehaviorArgument::initialize(A);
5648 }
5649
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005650 /// See AbstractAttribute::updateImpl(...).
5651 ChangeStatus updateImpl(Attributor &A) override {
5652 // TODO: Once we have call site specific value information we can provide
5653 // call site specific liveness liveness information and then it makes
5654 // sense to specialize attributes for call sites arguments instead of
5655 // redirecting requests to the callee argument.
5656 Argument *Arg = getAssociatedArgument();
5657 const IRPosition &ArgPos = IRPosition::argument(*Arg);
5658 auto &ArgAA = A.getAAFor<AAMemoryBehavior>(*this, ArgPos);
5659 return clampStateAndIndicateChange(
5660 getState(),
Johannes Doerfert31784242019-10-29 23:18:49 -05005661 static_cast<const AAMemoryBehavior::StateType &>(ArgAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005662 }
5663
5664 /// See AbstractAttribute::trackStatistics()
5665 void trackStatistics() const override {
5666 if (isAssumedReadNone())
5667 STATS_DECLTRACK_CSARG_ATTR(readnone)
5668 else if (isAssumedReadOnly())
5669 STATS_DECLTRACK_CSARG_ATTR(readonly)
5670 else if (isAssumedWriteOnly())
5671 STATS_DECLTRACK_CSARG_ATTR(writeonly)
5672 }
5673};
5674
5675/// Memory behavior attribute for a call site return position.
5676struct AAMemoryBehaviorCallSiteReturned final : AAMemoryBehaviorFloating {
5677 AAMemoryBehaviorCallSiteReturned(const IRPosition &IRP)
5678 : AAMemoryBehaviorFloating(IRP) {}
5679
5680 /// See AbstractAttribute::manifest(...).
5681 ChangeStatus manifest(Attributor &A) override {
5682 // We do not annotate returned values.
5683 return ChangeStatus::UNCHANGED;
5684 }
5685
5686 /// See AbstractAttribute::trackStatistics()
5687 void trackStatistics() const override {}
5688};
5689
5690/// An AA to represent the memory behavior function attributes.
5691struct AAMemoryBehaviorFunction final : public AAMemoryBehaviorImpl {
5692 AAMemoryBehaviorFunction(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5693
5694 /// See AbstractAttribute::updateImpl(Attributor &A).
5695 virtual ChangeStatus updateImpl(Attributor &A) override;
5696
5697 /// See AbstractAttribute::manifest(...).
5698 ChangeStatus manifest(Attributor &A) override {
5699 Function &F = cast<Function>(getAnchorValue());
5700 if (isAssumedReadNone()) {
5701 F.removeFnAttr(Attribute::ArgMemOnly);
5702 F.removeFnAttr(Attribute::InaccessibleMemOnly);
5703 F.removeFnAttr(Attribute::InaccessibleMemOrArgMemOnly);
5704 }
5705 return AAMemoryBehaviorImpl::manifest(A);
5706 }
5707
5708 /// See AbstractAttribute::trackStatistics()
5709 void trackStatistics() const override {
5710 if (isAssumedReadNone())
5711 STATS_DECLTRACK_FN_ATTR(readnone)
5712 else if (isAssumedReadOnly())
5713 STATS_DECLTRACK_FN_ATTR(readonly)
5714 else if (isAssumedWriteOnly())
5715 STATS_DECLTRACK_FN_ATTR(writeonly)
5716 }
5717};
5718
5719/// AAMemoryBehavior attribute for call sites.
5720struct AAMemoryBehaviorCallSite final : AAMemoryBehaviorImpl {
5721 AAMemoryBehaviorCallSite(const IRPosition &IRP) : AAMemoryBehaviorImpl(IRP) {}
5722
5723 /// See AbstractAttribute::initialize(...).
5724 void initialize(Attributor &A) override {
5725 AAMemoryBehaviorImpl::initialize(A);
5726 Function *F = getAssociatedFunction();
5727 if (!F || !F->hasExactDefinition())
5728 indicatePessimisticFixpoint();
5729 }
5730
5731 /// See AbstractAttribute::updateImpl(...).
5732 ChangeStatus updateImpl(Attributor &A) override {
5733 // TODO: Once we have call site specific value information we can provide
5734 // call site specific liveness liveness information and then it makes
5735 // sense to specialize attributes for call sites arguments instead of
5736 // redirecting requests to the callee argument.
5737 Function *F = getAssociatedFunction();
5738 const IRPosition &FnPos = IRPosition::function(*F);
5739 auto &FnAA = A.getAAFor<AAMemoryBehavior>(*this, FnPos);
5740 return clampStateAndIndicateChange(
Johannes Doerfert1a746452019-10-20 22:28:49 -05005741 getState(),
5742 static_cast<const AAMemoryBehavior::StateType &>(FnAA.getState()));
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005743 }
5744
5745 /// See AbstractAttribute::trackStatistics()
5746 void trackStatistics() const override {
5747 if (isAssumedReadNone())
5748 STATS_DECLTRACK_CS_ATTR(readnone)
5749 else if (isAssumedReadOnly())
5750 STATS_DECLTRACK_CS_ATTR(readonly)
5751 else if (isAssumedWriteOnly())
5752 STATS_DECLTRACK_CS_ATTR(writeonly)
5753 }
5754};
Benjamin Kramerc5d1d562019-10-12 11:01:52 +00005755} // namespace
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005756
5757ChangeStatus AAMemoryBehaviorFunction::updateImpl(Attributor &A) {
5758
5759 // The current assumed state used to determine a change.
5760 auto AssumedState = getAssumed();
5761
5762 auto CheckRWInst = [&](Instruction &I) {
5763 // If the instruction has an own memory behavior state, use it to restrict
5764 // the local state. No further analysis is required as the other memory
5765 // state is as optimistic as it gets.
5766 if (ImmutableCallSite ICS = ImmutableCallSite(&I)) {
5767 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
5768 *this, IRPosition::callsite_function(ICS));
5769 intersectAssumedBits(MemBehaviorAA.getAssumed());
5770 return !isAtFixpoint();
5771 }
5772
5773 // Remove access kind modifiers if necessary.
5774 if (I.mayReadFromMemory())
5775 removeAssumedBits(NO_READS);
5776 if (I.mayWriteToMemory())
5777 removeAssumedBits(NO_WRITES);
5778 return !isAtFixpoint();
5779 };
5780
5781 if (!A.checkForAllReadWriteInstructions(CheckRWInst, *this))
5782 return indicatePessimisticFixpoint();
5783
5784 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5785 : ChangeStatus::UNCHANGED;
5786}
5787
5788ChangeStatus AAMemoryBehaviorFloating::updateImpl(Attributor &A) {
5789
5790 const IRPosition &IRP = getIRPosition();
5791 const IRPosition &FnPos = IRPosition::function_scope(IRP);
5792 AAMemoryBehavior::StateType &S = getState();
5793
5794 // First, check the function scope. We take the known information and we avoid
5795 // work if the assumed information implies the current assumed information for
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005796 // this attribute. This is a valid for all but byval arguments.
5797 Argument *Arg = IRP.getAssociatedArgument();
5798 AAMemoryBehavior::base_t FnMemAssumedState =
5799 AAMemoryBehavior::StateType::getWorstState();
5800 if (!Arg || !Arg->hasByValAttr()) {
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005801 const auto &FnMemAA = A.getAAFor<AAMemoryBehavior>(
5802 *this, FnPos, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005803 FnMemAssumedState = FnMemAA.getAssumed();
5804 S.addKnownBits(FnMemAA.getKnown());
5805 if ((S.getAssumed() & FnMemAA.getAssumed()) == S.getAssumed())
5806 return ChangeStatus::UNCHANGED;
5807 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005808
5809 // Make sure the value is not captured (except through "return"), if
5810 // it is, any information derived would be irrelevant anyway as we cannot
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005811 // check the potential aliases introduced by the capture. However, no need
5812 // to fall back to anythign less optimistic than the function state.
Johannes Doerfert28880192019-12-31 00:57:00 -06005813 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
5814 *this, IRP, /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005815 if (!ArgNoCaptureAA.isAssumedNoCaptureMaybeReturned()) {
Johannes Doerfert6abd01e2019-12-12 15:02:36 -06005816 S.intersectAssumedBits(FnMemAssumedState);
Johannes Doerfert8ee410c2019-10-13 20:47:16 +00005817 return ChangeStatus::CHANGED;
5818 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005819
5820 // The current assumed state used to determine a change.
5821 auto AssumedState = S.getAssumed();
5822
5823 // Liveness information to exclude dead users.
5824 // TODO: Take the FnPos once we have call site specific liveness information.
5825 const auto &LivenessAA = A.getAAFor<AAIsDead>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005826 *this, IRPosition::function(*IRP.getAssociatedFunction()),
5827 /* TrackDependence */ false);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005828
5829 // Visit and expand uses until all are analyzed or a fixpoint is reached.
5830 for (unsigned i = 0; i < Uses.size() && !isAtFixpoint(); i++) {
5831 const Use *U = Uses[i];
5832 Instruction *UserI = cast<Instruction>(U->getUser());
5833 LLVM_DEBUG(dbgs() << "[AAMemoryBehavior] Use: " << **U << " in " << *UserI
5834 << " [Dead: " << (LivenessAA.isAssumedDead(UserI))
5835 << "]\n");
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005836 if (LivenessAA.isAssumedDead(UserI)) {
5837 A.recordDependence(LivenessAA, *this, DepClassTy::OPTIONAL);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005838 continue;
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005839 }
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005840
5841 // Check if the users of UserI should also be visited.
5842 if (followUsersOfUseIn(A, U, UserI))
5843 for (const Use &UserIUse : UserI->uses())
5844 Uses.insert(&UserIUse);
5845
5846 // If UserI might touch memory we analyze the use in detail.
5847 if (UserI->mayReadOrWriteMemory())
5848 analyzeUseIn(A, U, UserI);
5849 }
5850
5851 return (AssumedState != getAssumed()) ? ChangeStatus::CHANGED
5852 : ChangeStatus::UNCHANGED;
5853}
5854
5855bool AAMemoryBehaviorFloating::followUsersOfUseIn(Attributor &A, const Use *U,
5856 const Instruction *UserI) {
5857 // The loaded value is unrelated to the pointer argument, no need to
5858 // follow the users of the load.
5859 if (isa<LoadInst>(UserI))
5860 return false;
5861
5862 // By default we follow all uses assuming UserI might leak information on U,
5863 // we have special handling for call sites operands though.
5864 ImmutableCallSite ICS(UserI);
5865 if (!ICS || !ICS.isArgOperand(U))
5866 return true;
5867
5868 // If the use is a call argument known not to be captured, the users of
5869 // the call do not need to be visited because they have to be unrelated to
5870 // the input. Note that this check is not trivial even though we disallow
5871 // general capturing of the underlying argument. The reason is that the
5872 // call might the argument "through return", which we allow and for which we
5873 // need to check call users.
Johannes Doerfertff6254d2020-01-10 12:32:24 -06005874 if (U->get()->getType()->isPointerTy()) {
5875 unsigned ArgNo = ICS.getArgumentNo(U);
5876 const auto &ArgNoCaptureAA = A.getAAFor<AANoCapture>(
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005877 *this, IRPosition::callsite_argument(ICS, ArgNo),
5878 /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfertff6254d2020-01-10 12:32:24 -06005879 return !ArgNoCaptureAA.isAssumedNoCapture();
5880 }
5881
5882 return true;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005883}
5884
5885void AAMemoryBehaviorFloating::analyzeUseIn(Attributor &A, const Use *U,
5886 const Instruction *UserI) {
5887 assert(UserI->mayReadOrWriteMemory());
5888
5889 switch (UserI->getOpcode()) {
5890 default:
5891 // TODO: Handle all atomics and other side-effect operations we know of.
5892 break;
5893 case Instruction::Load:
5894 // Loads cause the NO_READS property to disappear.
5895 removeAssumedBits(NO_READS);
5896 return;
5897
5898 case Instruction::Store:
5899 // Stores cause the NO_WRITES property to disappear if the use is the
5900 // pointer operand. Note that we do assume that capturing was taken care of
5901 // somewhere else.
5902 if (cast<StoreInst>(UserI)->getPointerOperand() == U->get())
5903 removeAssumedBits(NO_WRITES);
5904 return;
5905
5906 case Instruction::Call:
5907 case Instruction::CallBr:
5908 case Instruction::Invoke: {
5909 // For call sites we look at the argument memory behavior attribute (this
5910 // could be recursive!) in order to restrict our own state.
5911 ImmutableCallSite ICS(UserI);
5912
5913 // Give up on operand bundles.
5914 if (ICS.isBundleOperand(U)) {
5915 indicatePessimisticFixpoint();
5916 return;
5917 }
5918
5919 // Calling a function does read the function pointer, maybe write it if the
5920 // function is self-modifying.
5921 if (ICS.isCallee(U)) {
5922 removeAssumedBits(NO_READS);
5923 break;
5924 }
5925
5926 // Adjust the possible access behavior based on the information on the
5927 // argument.
Johannes Doerfertff6254d2020-01-10 12:32:24 -06005928 IRPosition Pos;
5929 if (U->get()->getType()->isPointerTy())
5930 Pos = IRPosition::callsite_argument(ICS, ICS.getArgumentNo(U));
5931 else
5932 Pos = IRPosition::callsite_function(ICS);
Johannes Doerfert7ad17e02020-01-12 00:11:56 -06005933 const auto &MemBehaviorAA = A.getAAFor<AAMemoryBehavior>(
5934 *this, Pos,
5935 /* TrackDependence */ true, DepClassTy::OPTIONAL);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00005936 // "assumed" has at most the same bits as the MemBehaviorAA assumed
5937 // and at least "known".
5938 intersectAssumedBits(MemBehaviorAA.getAssumed());
5939 return;
5940 }
5941 };
5942
5943 // Generally, look at the "may-properties" and adjust the assumed state if we
5944 // did not trigger special handling before.
5945 if (UserI->mayReadFromMemory())
5946 removeAssumedBits(NO_READS);
5947 if (UserI->mayWriteToMemory())
5948 removeAssumedBits(NO_WRITES);
5949}
Hideto Ueno188f9a32020-01-15 15:25:52 +09005950/// ------------------ Value Constant Range Attribute -------------------------
Hideto Uenoe9963032020-01-01 15:25:19 +09005951
Hideto Ueno188f9a32020-01-15 15:25:52 +09005952struct AAValueConstantRangeImpl : AAValueConstantRange {
5953 using StateType = IntegerRangeState;
5954 AAValueConstantRangeImpl(const IRPosition &IRP) : AAValueConstantRange(IRP) {}
5955
5956 /// See AbstractAttribute::getAsStr().
5957 const std::string getAsStr() const override {
5958 std::string Str;
5959 llvm::raw_string_ostream OS(Str);
5960 OS << "range(" << getBitWidth() << ")<";
5961 getKnown().print(OS);
5962 OS << " / ";
5963 getAssumed().print(OS);
5964 OS << ">";
5965 return OS.str();
5966 }
5967
5968 /// Helper function to get a SCEV expr for the associated value at program
5969 /// point \p I.
5970 const SCEV *getSCEV(Attributor &A, const Instruction *I = nullptr) const {
5971 if (!getAnchorScope())
5972 return nullptr;
5973
5974 ScalarEvolution *SE =
5975 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
5976 *getAnchorScope());
5977
5978 LoopInfo *LI = A.getInfoCache().getAnalysisResultForFunction<LoopAnalysis>(
5979 *getAnchorScope());
5980
5981 if (!SE || !LI)
5982 return nullptr;
5983
5984 const SCEV *S = SE->getSCEV(&getAssociatedValue());
5985 if (!I)
5986 return S;
5987
5988 return SE->getSCEVAtScope(S, LI->getLoopFor(I->getParent()));
5989 }
5990
5991 /// Helper function to get a range from SCEV for the associated value at
5992 /// program point \p I.
5993 ConstantRange getConstantRangeFromSCEV(Attributor &A,
5994 const Instruction *I = nullptr) const {
5995 if (!getAnchorScope())
5996 return getWorstState(getBitWidth());
5997
5998 ScalarEvolution *SE =
5999 A.getInfoCache().getAnalysisResultForFunction<ScalarEvolutionAnalysis>(
6000 *getAnchorScope());
6001
6002 const SCEV *S = getSCEV(A, I);
6003 if (!SE || !S)
6004 return getWorstState(getBitWidth());
6005
6006 return SE->getUnsignedRange(S);
6007 }
6008
6009 /// Helper function to get a range from LVI for the associated value at
6010 /// program point \p I.
6011 ConstantRange
6012 getConstantRangeFromLVI(Attributor &A,
6013 const Instruction *CtxI = nullptr) const {
6014 if (!getAnchorScope())
6015 return getWorstState(getBitWidth());
6016
6017 LazyValueInfo *LVI =
6018 A.getInfoCache().getAnalysisResultForFunction<LazyValueAnalysis>(
6019 *getAnchorScope());
6020
6021 if (!LVI || !CtxI)
6022 return getWorstState(getBitWidth());
6023 return LVI->getConstantRange(&getAssociatedValue(),
6024 const_cast<BasicBlock *>(CtxI->getParent()),
6025 const_cast<Instruction *>(CtxI));
6026 }
6027
6028 /// See AAValueConstantRange::getKnownConstantRange(..).
6029 ConstantRange
6030 getKnownConstantRange(Attributor &A,
6031 const Instruction *CtxI = nullptr) const override {
6032 if (!CtxI || CtxI == getCtxI())
6033 return getKnown();
6034
6035 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
6036 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
6037 return getKnown().intersectWith(SCEVR).intersectWith(LVIR);
6038 }
6039
6040 /// See AAValueConstantRange::getAssumedConstantRange(..).
6041 ConstantRange
6042 getAssumedConstantRange(Attributor &A,
6043 const Instruction *CtxI = nullptr) const override {
6044 // TODO: Make SCEV use Attributor assumption.
6045 // We may be able to bound a variable range via assumptions in
6046 // Attributor. ex.) If x is assumed to be in [1, 3] and y is known to
6047 // evolve to x^2 + x, then we can say that y is in [2, 12].
6048
6049 if (!CtxI || CtxI == getCtxI())
6050 return getAssumed();
6051
6052 ConstantRange LVIR = getConstantRangeFromLVI(A, CtxI);
6053 ConstantRange SCEVR = getConstantRangeFromSCEV(A, CtxI);
6054 return getAssumed().intersectWith(SCEVR).intersectWith(LVIR);
6055 }
6056
6057 /// See AbstractAttribute::initialize(..).
6058 void initialize(Attributor &A) override {
6059 // Intersect a range given by SCEV.
6060 intersectKnown(getConstantRangeFromSCEV(A, getCtxI()));
6061
6062 // Intersect a range given by LVI.
6063 intersectKnown(getConstantRangeFromLVI(A, getCtxI()));
6064 }
6065
6066 /// Helper function to create MDNode for range metadata.
6067 static MDNode *
6068 getMDNodeForConstantRange(Type *Ty, LLVMContext &Ctx,
6069 const ConstantRange &AssumedConstantRange) {
6070 Metadata *LowAndHigh[] = {ConstantAsMetadata::get(ConstantInt::get(
6071 Ty, AssumedConstantRange.getLower())),
6072 ConstantAsMetadata::get(ConstantInt::get(
6073 Ty, AssumedConstantRange.getUpper()))};
6074 return MDNode::get(Ctx, LowAndHigh);
6075 }
6076
6077 /// Return true if \p Assumed is included in \p KnownRanges.
6078 static bool isBetterRange(const ConstantRange &Assumed, MDNode *KnownRanges) {
6079
6080 if (Assumed.isFullSet())
6081 return false;
6082
6083 if (!KnownRanges)
6084 return true;
6085
6086 // If multiple ranges are annotated in IR, we give up to annotate assumed
6087 // range for now.
6088
6089 // TODO: If there exists a known range which containts assumed range, we
6090 // can say assumed range is better.
6091 if (KnownRanges->getNumOperands() > 2)
6092 return false;
6093
6094 ConstantInt *Lower =
6095 mdconst::extract<ConstantInt>(KnownRanges->getOperand(0));
6096 ConstantInt *Upper =
6097 mdconst::extract<ConstantInt>(KnownRanges->getOperand(1));
6098
6099 ConstantRange Known(Lower->getValue(), Upper->getValue());
6100 return Known.contains(Assumed) && Known != Assumed;
6101 }
6102
6103 /// Helper function to set range metadata.
6104 static bool
6105 setRangeMetadataIfisBetterRange(Instruction *I,
6106 const ConstantRange &AssumedConstantRange) {
6107 auto *OldRangeMD = I->getMetadata(LLVMContext::MD_range);
6108 if (isBetterRange(AssumedConstantRange, OldRangeMD)) {
6109 if (!AssumedConstantRange.isEmptySet()) {
6110 I->setMetadata(LLVMContext::MD_range,
6111 getMDNodeForConstantRange(I->getType(), I->getContext(),
6112 AssumedConstantRange));
6113 return true;
6114 }
6115 }
6116 return false;
6117 }
6118
6119 /// See AbstractAttribute::manifest()
6120 ChangeStatus manifest(Attributor &A) override {
6121 ChangeStatus Changed = ChangeStatus::UNCHANGED;
6122 ConstantRange AssumedConstantRange = getAssumedConstantRange(A);
6123 assert(!AssumedConstantRange.isFullSet() && "Invalid state");
6124
6125 auto &V = getAssociatedValue();
6126 if (!AssumedConstantRange.isEmptySet() &&
6127 !AssumedConstantRange.isSingleElement()) {
6128 if (Instruction *I = dyn_cast<Instruction>(&V))
6129 if (isa<CallInst>(I) || isa<LoadInst>(I))
6130 if (setRangeMetadataIfisBetterRange(I, AssumedConstantRange))
6131 Changed = ChangeStatus::CHANGED;
6132 }
6133
6134 return Changed;
6135 }
6136};
6137
Johannes Doerfertea5fabe2020-01-28 09:46:15 -06006138struct AAValueConstantRangeArgument final
6139 : AAArgumentFromCallSiteArguments<
6140 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState> {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006141 AAValueConstantRangeArgument(const IRPosition &IRP)
Johannes Doerfertea5fabe2020-01-28 09:46:15 -06006142 : AAArgumentFromCallSiteArguments<
6143 AAValueConstantRange, AAValueConstantRangeImpl, IntegerRangeState>(
6144 IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006145
6146 /// See AbstractAttribute::trackStatistics()
6147 void trackStatistics() const override {
6148 STATS_DECLTRACK_ARG_ATTR(value_range)
6149 }
6150};
6151
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006152struct AAValueConstantRangeReturned
6153 : AAReturnedFromReturnedValues<AAValueConstantRange,
6154 AAValueConstantRangeImpl> {
6155 using Base = AAReturnedFromReturnedValues<AAValueConstantRange,
6156 AAValueConstantRangeImpl>;
6157 AAValueConstantRangeReturned(const IRPosition &IRP) : Base(IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006158
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006159 /// See AbstractAttribute::initialize(...).
6160 void initialize(Attributor &A) override {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006161
6162 /// See AbstractAttribute::trackStatistics()
6163 void trackStatistics() const override {
6164 STATS_DECLTRACK_FNRET_ATTR(value_range)
6165 }
6166};
6167
6168struct AAValueConstantRangeFloating : AAValueConstantRangeImpl {
6169 AAValueConstantRangeFloating(const IRPosition &IRP)
6170 : AAValueConstantRangeImpl(IRP) {}
6171
6172 /// See AbstractAttribute::initialize(...).
6173 void initialize(Attributor &A) override {
Johannes Doerfert028db8c42020-02-09 19:05:15 -06006174 AAValueConstantRangeImpl::initialize(A);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006175 Value &V = getAssociatedValue();
6176
6177 if (auto *C = dyn_cast<ConstantInt>(&V)) {
6178 unionAssumed(ConstantRange(C->getValue()));
6179 indicateOptimisticFixpoint();
6180 return;
6181 }
6182
6183 if (isa<UndefValue>(&V)) {
6184 indicateOptimisticFixpoint();
6185 return;
6186 }
6187
6188 if (auto *I = dyn_cast<Instruction>(&V))
6189 if (isa<BinaryOperator>(I) || isa<CmpInst>(I)) {
6190 Value *LHS = I->getOperand(0);
6191 Value *RHS = I->getOperand(1);
6192
6193 if (LHS->getType()->isIntegerTy() && RHS->getType()->isIntegerTy())
6194 return;
6195 }
6196
6197 // If it is a load instruction with range metadata, use it.
6198 if (LoadInst *LI = dyn_cast<LoadInst>(&V))
6199 if (auto *RangeMD = LI->getMetadata(LLVMContext::MD_range)) {
6200 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
6201 return;
6202 }
6203
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006204 // We handle casts in the updateImpl.
6205 // TODO: Allow non integers as well.
6206 if (CastInst *CI = dyn_cast<CastInst>(&V))
6207 if (CI->getOperand(0)->getType()->isIntegerTy())
6208 return;
6209
Johannes Doerfert81554392020-02-09 20:14:35 -06006210 // We can work with PHI and select instruction as we traverse their operands
Johannes Doerfert7e7e6592020-02-09 19:08:04 -06006211 // during update.
Johannes Doerfert81554392020-02-09 20:14:35 -06006212 if (isa<SelectInst>(V) || isa<PHINode>(V))
Johannes Doerfert7e7e6592020-02-09 19:08:04 -06006213 return;
6214
Hideto Ueno188f9a32020-01-15 15:25:52 +09006215 // Otherwise we give up.
6216 indicatePessimisticFixpoint();
6217
Johannes Doerfert02bd8182020-01-28 11:49:35 -06006218 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] We give up: "
6219 << getAssociatedValue() << "\n");
Hideto Ueno188f9a32020-01-15 15:25:52 +09006220 }
6221
Johannes Doerfert81554392020-02-09 20:14:35 -06006222 bool calculateBinaryOperator(
6223 Attributor &A, BinaryOperator *BinOp, IntegerRangeState &T,
6224 Instruction *CtxI,
6225 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006226 Value *LHS = BinOp->getOperand(0);
6227 Value *RHS = BinOp->getOperand(1);
6228
6229 auto &LHSAA =
6230 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006231 QuerriedAAs.push_back(&LHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006232 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
6233
6234 auto &RHSAA =
6235 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006236 QuerriedAAs.push_back(&RHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006237 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
6238
6239 auto AssumedRange = LHSAARange.binaryOp(BinOp->getOpcode(), RHSAARange);
6240
6241 T.unionAssumed(AssumedRange);
6242
6243 // TODO: Track a known state too.
6244
6245 return T.isValidState();
6246 }
6247
Johannes Doerfert81554392020-02-09 20:14:35 -06006248 bool calculateCastInst(
6249 Attributor &A, CastInst *CastI, IntegerRangeState &T, Instruction *CtxI,
6250 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006251 assert(CastI->getNumOperands() == 1 && "Expected cast to be unary!");
6252 // TODO: Allow non integers as well.
6253 Value &OpV = *CastI->getOperand(0);
6254 assert(OpV.getType()->isIntegerTy() && "Expected integer cast");
6255
6256 auto &OpAA =
6257 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(OpV));
Johannes Doerfert81554392020-02-09 20:14:35 -06006258 QuerriedAAs.push_back(&OpAA);
Johannes Doerfertffdbd2a2020-02-09 19:07:30 -06006259 T.unionAssumed(
6260 OpAA.getAssumed().castOp(CastI->getOpcode(), getState().getBitWidth()));
6261 return T.isValidState();
6262 }
6263
Johannes Doerfert81554392020-02-09 20:14:35 -06006264 bool
6265 calculateCmpInst(Attributor &A, CmpInst *CmpI, IntegerRangeState &T,
6266 Instruction *CtxI,
6267 SmallVectorImpl<const AAValueConstantRange *> &QuerriedAAs) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006268 Value *LHS = CmpI->getOperand(0);
6269 Value *RHS = CmpI->getOperand(1);
6270
6271 auto &LHSAA =
6272 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*LHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006273 QuerriedAAs.push_back(&LHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006274 auto &RHSAA =
6275 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(*RHS));
Johannes Doerfert81554392020-02-09 20:14:35 -06006276 QuerriedAAs.push_back(&RHSAA);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006277
6278 auto LHSAARange = LHSAA.getAssumedConstantRange(A, CtxI);
6279 auto RHSAARange = RHSAA.getAssumedConstantRange(A, CtxI);
6280
6281 // If one of them is empty set, we can't decide.
6282 if (LHSAARange.isEmptySet() || RHSAARange.isEmptySet())
6283 return true;
6284
6285 bool MustTrue = false, MustFalse = false;
6286
6287 auto AllowedRegion =
6288 ConstantRange::makeAllowedICmpRegion(CmpI->getPredicate(), RHSAARange);
6289
6290 auto SatisfyingRegion = ConstantRange::makeSatisfyingICmpRegion(
6291 CmpI->getPredicate(), RHSAARange);
6292
6293 if (AllowedRegion.intersectWith(LHSAARange).isEmptySet())
6294 MustFalse = true;
6295
6296 if (SatisfyingRegion.contains(LHSAARange))
6297 MustTrue = true;
6298
6299 assert((!MustTrue || !MustFalse) &&
6300 "Either MustTrue or MustFalse should be false!");
6301
6302 if (MustTrue)
6303 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 1)));
6304 else if (MustFalse)
6305 T.unionAssumed(ConstantRange(APInt(/* numBits */ 1, /* val */ 0)));
6306 else
6307 T.unionAssumed(ConstantRange(/* BitWidth */ 1, /* isFullSet */ true));
6308
6309 LLVM_DEBUG(dbgs() << "[AAValueConstantRange] " << *CmpI << " " << LHSAA
6310 << " " << RHSAA << "\n");
6311
6312 // TODO: Track a known state too.
6313 return T.isValidState();
6314 }
6315
6316 /// See AbstractAttribute::updateImpl(...).
6317 ChangeStatus updateImpl(Attributor &A) override {
6318 Instruction *CtxI = getCtxI();
6319 auto VisitValueCB = [&](Value &V, IntegerRangeState &T,
6320 bool Stripped) -> bool {
6321 Instruction *I = dyn_cast<Instruction>(&V);
6322 if (!I) {
6323
6324 // If the value is not instruction, we query AA to Attributor.
6325 const auto &AA =
6326 A.getAAFor<AAValueConstantRange>(*this, IRPosition::value(V));
6327
6328 // Clamp operator is not used to utilize a program point CtxI.
6329 T.unionAssumed(AA.getAssumedConstantRange(A, CtxI));
6330
6331 return T.isValidState();
6332 }
6333
Johannes Doerfert81554392020-02-09 20:14:35 -06006334 SmallVector<const AAValueConstantRange *, 4> QuerriedAAs;
6335 if (auto *BinOp = dyn_cast<BinaryOperator>(I)) {
6336 if (!calculateBinaryOperator(A, BinOp, T, CtxI, QuerriedAAs))
6337 return false;
6338 } else if (auto *CmpI = dyn_cast<CmpInst>(I)) {
6339 if (!calculateCmpInst(A, CmpI, T, CtxI, QuerriedAAs))
6340 return false;
6341 } else if (auto *CastI = dyn_cast<CastInst>(I)) {
6342 if (!calculateCastInst(A, CastI, T, CtxI, QuerriedAAs))
6343 return false;
6344 } else {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006345 // Give up with other instructions.
6346 // TODO: Add other instructions
6347
6348 T.indicatePessimisticFixpoint();
6349 return false;
6350 }
Johannes Doerfert81554392020-02-09 20:14:35 -06006351
6352 // Catch circular reasoning in a pessimistic way for now.
6353 // TODO: Check how the range evolves and if we stripped anything, see also
6354 // AADereferenceable or AAAlign for similar situations.
6355 for (const AAValueConstantRange *QueriedAA : QuerriedAAs) {
6356 if (QueriedAA != this)
6357 continue;
6358 // If we are in a stady state we do not need to worry.
6359 if (T.getAssumed() == getState().getAssumed())
6360 continue;
6361 T.indicatePessimisticFixpoint();
6362 }
6363
6364 return T.isValidState();
Hideto Ueno188f9a32020-01-15 15:25:52 +09006365 };
6366
6367 IntegerRangeState T(getBitWidth());
6368
6369 if (!genericValueTraversal<AAValueConstantRange, IntegerRangeState>(
6370 A, getIRPosition(), *this, T, VisitValueCB))
6371 return indicatePessimisticFixpoint();
6372
6373 return clampStateAndIndicateChange(getState(), T);
6374 }
6375
6376 /// See AbstractAttribute::trackStatistics()
6377 void trackStatistics() const override {
6378 STATS_DECLTRACK_FLOATING_ATTR(value_range)
6379 }
6380};
6381
6382struct AAValueConstantRangeFunction : AAValueConstantRangeImpl {
6383 AAValueConstantRangeFunction(const IRPosition &IRP)
6384 : AAValueConstantRangeImpl(IRP) {}
6385
6386 /// See AbstractAttribute::initialize(...).
6387 ChangeStatus updateImpl(Attributor &A) override {
6388 llvm_unreachable("AAValueConstantRange(Function|CallSite)::updateImpl will "
6389 "not be called");
6390 }
6391
6392 /// See AbstractAttribute::trackStatistics()
6393 void trackStatistics() const override { STATS_DECLTRACK_FN_ATTR(value_range) }
6394};
6395
6396struct AAValueConstantRangeCallSite : AAValueConstantRangeFunction {
6397 AAValueConstantRangeCallSite(const IRPosition &IRP)
6398 : AAValueConstantRangeFunction(IRP) {}
6399
6400 /// See AbstractAttribute::trackStatistics()
6401 void trackStatistics() const override { STATS_DECLTRACK_CS_ATTR(value_range) }
6402};
6403
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006404struct AAValueConstantRangeCallSiteReturned
6405 : AACallSiteReturnedFromReturned<AAValueConstantRange,
6406 AAValueConstantRangeImpl> {
Hideto Ueno188f9a32020-01-15 15:25:52 +09006407 AAValueConstantRangeCallSiteReturned(const IRPosition &IRP)
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006408 : AACallSiteReturnedFromReturned<AAValueConstantRange,
6409 AAValueConstantRangeImpl>(IRP) {}
Hideto Ueno188f9a32020-01-15 15:25:52 +09006410
6411 /// See AbstractAttribute::initialize(...).
6412 void initialize(Attributor &A) override {
6413 // If it is a load instruction with range metadata, use the metadata.
6414 if (CallInst *CI = dyn_cast<CallInst>(&getAssociatedValue()))
6415 if (auto *RangeMD = CI->getMetadata(LLVMContext::MD_range))
6416 intersectKnown(getConstantRangeFromMetadata(*RangeMD));
6417
Johannes Doerfert791c9f12020-01-29 18:02:42 -06006418 AAValueConstantRangeImpl::initialize(A);
Hideto Ueno188f9a32020-01-15 15:25:52 +09006419 }
6420
6421 /// See AbstractAttribute::trackStatistics()
6422 void trackStatistics() const override {
6423 STATS_DECLTRACK_CSRET_ATTR(value_range)
6424 }
6425};
6426struct AAValueConstantRangeCallSiteArgument : AAValueConstantRangeFloating {
6427 AAValueConstantRangeCallSiteArgument(const IRPosition &IRP)
6428 : AAValueConstantRangeFloating(IRP) {}
6429
6430 /// See AbstractAttribute::trackStatistics()
6431 void trackStatistics() const override {
6432 STATS_DECLTRACK_CSARG_ATTR(value_range)
6433 }
6434};
Johannes Doerfertaade7822019-06-05 03:02:24 +00006435/// ----------------------------------------------------------------------------
6436/// Attributor
6437/// ----------------------------------------------------------------------------
6438
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006439bool Attributor::isAssumedDead(const AbstractAttribute &AA,
6440 const AAIsDead *LivenessAA) {
6441 const Instruction *CtxI = AA.getIRPosition().getCtxI();
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006442 if (!CtxI || !Functions.count(const_cast<Function *>(CtxI->getFunction())))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006443 return false;
6444
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006445 // TODO: Find a good way to utilize fine and coarse grained liveness
6446 // information.
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006447 if (!LivenessAA)
6448 LivenessAA =
Johannes Doerfert19b00432019-08-26 17:48:05 +00006449 &getAAFor<AAIsDead>(AA, IRPosition::function(*CtxI->getFunction()),
6450 /* TrackDependence */ false);
Stefan Stipanovic26121ae2019-08-20 23:16:57 +00006451
6452 // Don't check liveness for AAIsDead.
6453 if (&AA == LivenessAA)
6454 return false;
6455
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006456 if (!LivenessAA->isAssumedDead(CtxI))
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006457 return false;
6458
Johannes Doerfert19b00432019-08-26 17:48:05 +00006459 // We actually used liveness information so we have to record a dependence.
Johannes Doerfert680f6382019-11-02 02:48:05 -05006460 recordDependence(*LivenessAA, AA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006461
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006462 return true;
6463}
6464
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006465bool Attributor::checkForAllUses(
6466 const function_ref<bool(const Use &, bool &)> &Pred,
6467 const AbstractAttribute &QueryingAA, const Value &V) {
6468 const IRPosition &IRP = QueryingAA.getIRPosition();
6469 SmallVector<const Use *, 16> Worklist;
6470 SmallPtrSet<const Use *, 16> Visited;
6471
6472 for (const Use &U : V.uses())
6473 Worklist.push_back(&U);
6474
6475 LLVM_DEBUG(dbgs() << "[Attributor] Got " << Worklist.size()
6476 << " initial uses to check\n");
6477
6478 if (Worklist.empty())
6479 return true;
6480
6481 bool AnyDead = false;
6482 const Function *ScopeFn = IRP.getAnchorScope();
6483 const auto *LivenessAA =
6484 ScopeFn ? &getAAFor<AAIsDead>(QueryingAA, IRPosition::function(*ScopeFn),
6485 /* TrackDependence */ false)
6486 : nullptr;
6487
6488 while (!Worklist.empty()) {
6489 const Use *U = Worklist.pop_back_val();
6490 if (!Visited.insert(U).second)
6491 continue;
Johannes Doerfert8e629682020-02-11 00:10:35 -06006492 LLVM_DEBUG(dbgs() << "[Attributor] Check use: " << **U << " [" << LivenessAA
6493 << "]\n");
6494 if (LivenessAA) {
6495 if (Instruction *UserI = dyn_cast<Instruction>(U->getUser())) {
6496 if (LivenessAA->isAssumedDead(UserI)) {
6497 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
6498 << *LivenessAA << "\n");
6499 AnyDead = true;
6500 continue;
6501 }
6502 if (PHINode *PHI = dyn_cast<PHINode>(UserI)) {
6503 BasicBlock *IncomingBB = PHI->getIncomingBlock(*U);
6504 if (LivenessAA->isAssumedDead(IncomingBB->getTerminator())) {
6505 LLVM_DEBUG(dbgs() << "[Attributor] Dead user: " << *UserI << ": "
6506 << *LivenessAA << "\n");
6507 AnyDead = true;
6508 continue;
6509 }
6510 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006511 }
Johannes Doerfert8e629682020-02-11 00:10:35 -06006512 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006513
6514 bool Follow = false;
6515 if (!Pred(*U, Follow))
6516 return false;
6517 if (!Follow)
6518 continue;
6519 for (const Use &UU : U->getUser()->uses())
6520 Worklist.push_back(&UU);
6521 }
6522
6523 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05006524 recordDependence(*LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006525
6526 return true;
6527}
6528
Johannes Doerfert661db042019-10-07 23:14:58 +00006529bool Attributor::checkForAllCallSites(
6530 const function_ref<bool(AbstractCallSite)> &Pred,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006531 const AbstractAttribute &QueryingAA, bool RequireAllCallSites,
6532 bool &AllCallSitesKnown) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006533 // We can try to determine information from
6534 // the call sites. However, this is only possible all call sites are known,
6535 // hence the function has internal linkage.
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006536 const IRPosition &IRP = QueryingAA.getIRPosition();
6537 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfert748538e2019-10-07 23:30:04 +00006538 if (!AssociatedFunction) {
6539 LLVM_DEBUG(dbgs() << "[Attributor] No function associated with " << IRP
6540 << "\n");
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006541 AllCallSitesKnown = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006542 return false;
Johannes Doerfert748538e2019-10-07 23:30:04 +00006543 }
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006544
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006545 return checkForAllCallSites(Pred, *AssociatedFunction, RequireAllCallSites,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006546 &QueryingAA, AllCallSitesKnown);
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006547}
6548
6549bool Attributor::checkForAllCallSites(
6550 const function_ref<bool(AbstractCallSite)> &Pred, const Function &Fn,
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006551 bool RequireAllCallSites, const AbstractAttribute *QueryingAA,
6552 bool &AllCallSitesKnown) {
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006553 if (RequireAllCallSites && !Fn.hasLocalLinkage()) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006554 LLVM_DEBUG(
6555 dbgs()
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006556 << "[Attributor] Function " << Fn.getName()
Hideto Ueno54869ec2019-07-15 06:49:04 +00006557 << " has no internal linkage, hence not all call sites are known\n");
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006558 AllCallSitesKnown = false;
Hideto Ueno54869ec2019-07-15 06:49:04 +00006559 return false;
6560 }
6561
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006562 // If we do not require all call sites we might not see all.
6563 AllCallSitesKnown = RequireAllCallSites;
6564
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006565 for (const Use &U : Fn.uses()) {
Johannes Doerfert661db042019-10-07 23:14:58 +00006566 AbstractCallSite ACS(&U);
6567 if (!ACS) {
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006568 LLVM_DEBUG(dbgs() << "[Attributor] Function " << Fn.getName()
Johannes Doerfert661db042019-10-07 23:14:58 +00006569 << " has non call site use " << *U.get() << " in "
6570 << *U.getUser() << "\n");
Johannes Doerfert2d77b0c2019-11-01 22:35:18 -05006571 // BlockAddress users are allowed.
6572 if (isa<BlockAddress>(U.getUser()))
6573 continue;
Johannes Doerfertd98f9752019-08-21 21:48:56 +00006574 return false;
Johannes Doerfert661db042019-10-07 23:14:58 +00006575 }
Johannes Doerfertd98f9752019-08-21 21:48:56 +00006576
Johannes Doerfert661db042019-10-07 23:14:58 +00006577 Instruction *I = ACS.getInstruction();
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006578 Function *Caller = I->getFunction();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00006579
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006580 const auto *LivenessAA =
6581 lookupAAFor<AAIsDead>(IRPosition::function(*Caller), QueryingAA,
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006582 /* TrackDependence */ false);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00006583
6584 // Skip dead calls.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006585 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
Johannes Doerfert19b00432019-08-26 17:48:05 +00006586 // We actually used liveness information so we have to record a
6587 // dependence.
Johannes Doerfert3753aa72019-10-13 04:16:02 +00006588 if (QueryingAA)
Johannes Doerfert680f6382019-11-02 02:48:05 -05006589 recordDependence(*LivenessAA, *QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06006590 AllCallSitesKnown = false;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00006591 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00006592 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00006593
Johannes Doerfert661db042019-10-07 23:14:58 +00006594 const Use *EffectiveUse =
6595 ACS.isCallbackCall() ? &ACS.getCalleeUseForCallback() : &U;
6596 if (!ACS.isCallee(EffectiveUse)) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00006597 if (!RequireAllCallSites)
6598 continue;
Johannes Doerfert661db042019-10-07 23:14:58 +00006599 LLVM_DEBUG(dbgs() << "[Attributor] User " << EffectiveUse->getUser()
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006600 << " is an invalid use of " << Fn.getName() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00006601 return false;
6602 }
6603
Johannes Doerfert661db042019-10-07 23:14:58 +00006604 if (Pred(ACS))
Hideto Ueno54869ec2019-07-15 06:49:04 +00006605 continue;
6606
Johannes Doerfert5304b722019-08-14 22:04:28 +00006607 LLVM_DEBUG(dbgs() << "[Attributor] Call site callback failed for "
Johannes Doerfert661db042019-10-07 23:14:58 +00006608 << *ACS.getInstruction() << "\n");
Hideto Ueno54869ec2019-07-15 06:49:04 +00006609 return false;
6610 }
6611
6612 return true;
6613}
6614
Johannes Doerfert14a04932019-08-07 22:27:24 +00006615bool Attributor::checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00006616 const function_ref<bool(Value &, const SmallSetVector<ReturnInst *, 4> &)>
Johannes Doerfert14a04932019-08-07 22:27:24 +00006617 &Pred,
6618 const AbstractAttribute &QueryingAA) {
6619
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006620 const IRPosition &IRP = QueryingAA.getIRPosition();
6621 // Since we need to provide return instructions we have to have an exact
6622 // definition.
6623 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006624 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00006625 return false;
6626
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006627 // If this is a call site query we use the call site specific return values
6628 // and liveness information.
Johannes Doerfert07a5c122019-08-28 14:09:14 +00006629 // TODO: use the function scope once we have call site AAReturnedValues.
6630 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006631 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006632 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006633 return false;
6634
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006635 return AARetVal.checkForAllReturnedValuesAndReturnInsts(Pred);
Johannes Doerfert14a04932019-08-07 22:27:24 +00006636}
6637
6638bool Attributor::checkForAllReturnedValues(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006639 const function_ref<bool(Value &)> &Pred,
Johannes Doerfert14a04932019-08-07 22:27:24 +00006640 const AbstractAttribute &QueryingAA) {
6641
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006642 const IRPosition &IRP = QueryingAA.getIRPosition();
6643 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006644 if (!AssociatedFunction)
Johannes Doerfert14a04932019-08-07 22:27:24 +00006645 return false;
6646
Johannes Doerfert07a5c122019-08-28 14:09:14 +00006647 // TODO: use the function scope once we have call site AAReturnedValues.
6648 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006649 const auto &AARetVal = getAAFor<AAReturnedValues>(QueryingAA, QueryIRP);
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006650 if (!AARetVal.getState().isValidState())
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006651 return false;
6652
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006653 return AARetVal.checkForAllReturnedValuesAndReturnInsts(
Johannes Doerfert695089e2019-08-23 15:23:49 +00006654 [&](Value &RV, const SmallSetVector<ReturnInst *, 4> &) {
Johannes Doerfertdef99282019-08-14 21:29:37 +00006655 return Pred(RV);
6656 });
Johannes Doerfert14a04932019-08-07 22:27:24 +00006657}
6658
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006659static bool
6660checkForAllInstructionsImpl(InformationCache::OpcodeInstMapTy &OpcodeInstMap,
6661 const function_ref<bool(Instruction &)> &Pred,
6662 const AAIsDead *LivenessAA, bool &AnyDead,
6663 const ArrayRef<unsigned> &Opcodes) {
6664 for (unsigned Opcode : Opcodes) {
6665 for (Instruction *I : OpcodeInstMap[Opcode]) {
6666 // Skip dead instructions.
6667 if (LivenessAA && LivenessAA->isAssumedDead(I)) {
6668 AnyDead = true;
6669 continue;
6670 }
6671
6672 if (!Pred(*I))
6673 return false;
6674 }
6675 }
6676 return true;
6677}
6678
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006679bool Attributor::checkForAllInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006680 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00006681 const AbstractAttribute &QueryingAA, const ArrayRef<unsigned> &Opcodes) {
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006682
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006683 const IRPosition &IRP = QueryingAA.getIRPosition();
6684 // Since we need to provide instructions we have to have an exact definition.
6685 const Function *AssociatedFunction = IRP.getAssociatedFunction();
Johannes Doerfertb0412e42019-09-04 16:16:13 +00006686 if (!AssociatedFunction)
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006687 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006688
Johannes Doerfert07a5c122019-08-28 14:09:14 +00006689 // TODO: use the function scope once we have call site AAReturnedValues.
6690 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006691 const auto &LivenessAA =
6692 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
6693 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006694
6695 auto &OpcodeInstMap =
6696 InfoCache.getOpcodeInstMapForFunction(*AssociatedFunction);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00006697 if (!checkForAllInstructionsImpl(OpcodeInstMap, Pred, &LivenessAA, AnyDead,
6698 Opcodes))
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00006699 return false;
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006700
Johannes Doerfert19b00432019-08-26 17:48:05 +00006701 // If we actually used liveness information so we have to record a dependence.
6702 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05006703 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006704
Johannes Doerfertd0f64002019-08-06 00:32:43 +00006705 return true;
6706}
6707
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006708bool Attributor::checkForAllReadWriteInstructions(
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006709 const llvm::function_ref<bool(Instruction &)> &Pred,
Johannes Doerfertece81902019-08-12 22:05:53 +00006710 AbstractAttribute &QueryingAA) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006711
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006712 const Function *AssociatedFunction =
6713 QueryingAA.getIRPosition().getAssociatedFunction();
6714 if (!AssociatedFunction)
6715 return false;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006716
Johannes Doerfert07a5c122019-08-28 14:09:14 +00006717 // TODO: use the function scope once we have call site AAReturnedValues.
6718 const IRPosition &QueryIRP = IRPosition::function(*AssociatedFunction);
6719 const auto &LivenessAA =
6720 getAAFor<AAIsDead>(QueryingAA, QueryIRP, /* TrackDependence */ false);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006721 bool AnyDead = false;
Johannes Doerfert710ebb02019-08-14 21:18:01 +00006722
6723 for (Instruction *I :
6724 InfoCache.getReadOrWriteInstsForFunction(*AssociatedFunction)) {
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006725 // Skip dead instructions.
Johannes Doerfert19b00432019-08-26 17:48:05 +00006726 if (LivenessAA.isAssumedDead(I)) {
6727 AnyDead = true;
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006728 continue;
Johannes Doerfert19b00432019-08-26 17:48:05 +00006729 }
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006730
6731 if (!Pred(*I))
6732 return false;
6733 }
6734
Johannes Doerfert19b00432019-08-26 17:48:05 +00006735 // If we actually used liveness information so we have to record a dependence.
6736 if (AnyDead)
Johannes Doerfert680f6382019-11-02 02:48:05 -05006737 recordDependence(LivenessAA, QueryingAA, DepClassTy::OPTIONAL);
Johannes Doerfert19b00432019-08-26 17:48:05 +00006738
Stefan Stipanovicaaa52702019-08-07 18:26:02 +00006739 return true;
6740}
6741
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006742ChangeStatus Attributor::run() {
Johannes Doerfertaade7822019-06-05 03:02:24 +00006743 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
6744 << AllAbstractAttributes.size()
6745 << " abstract attributes.\n");
6746
Stefan Stipanovic53605892019-06-27 11:27:54 +00006747 // Now that all abstract attributes are collected and initialized we start
6748 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00006749
6750 unsigned IterationCounter = 1;
6751
6752 SmallVector<AbstractAttribute *, 64> ChangedAAs;
Johannes Doerfert680f6382019-11-02 02:48:05 -05006753 SetVector<AbstractAttribute *> Worklist, InvalidAAs;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006754 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
6755
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006756 bool RecomputeDependences = false;
6757
Johannes Doerfertaade7822019-06-05 03:02:24 +00006758 do {
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00006759 // Remember the size to determine new attributes.
6760 size_t NumAAs = AllAbstractAttributes.size();
Johannes Doerfertaade7822019-06-05 03:02:24 +00006761 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
6762 << ", Worklist size: " << Worklist.size() << "\n");
6763
Johannes Doerfert680f6382019-11-02 02:48:05 -05006764 // For invalid AAs we can fix dependent AAs that have a required dependence,
6765 // thereby folding long dependence chains in a single step without the need
6766 // to run updates.
6767 for (unsigned u = 0; u < InvalidAAs.size(); ++u) {
6768 AbstractAttribute *InvalidAA = InvalidAAs[u];
6769 auto &QuerriedAAs = QueryMap[InvalidAA];
6770 LLVM_DEBUG(dbgs() << "[Attributor] InvalidAA: " << *InvalidAA << " has "
6771 << QuerriedAAs.RequiredAAs.size() << "/"
6772 << QuerriedAAs.OptionalAAs.size()
6773 << " required/optional dependences\n");
6774 for (AbstractAttribute *DepOnInvalidAA : QuerriedAAs.RequiredAAs) {
6775 AbstractState &DOIAAState = DepOnInvalidAA->getState();
6776 DOIAAState.indicatePessimisticFixpoint();
6777 ++NumAttributesFixedDueToRequiredDependences;
6778 assert(DOIAAState.isAtFixpoint() && "Expected fixpoint state!");
6779 if (!DOIAAState.isValidState())
6780 InvalidAAs.insert(DepOnInvalidAA);
Johannes Doerfert22408542020-01-28 09:38:07 -06006781 else
6782 ChangedAAs.push_back(DepOnInvalidAA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05006783 }
6784 if (!RecomputeDependences)
6785 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
6786 QuerriedAAs.OptionalAAs.end());
6787 }
6788
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006789 // If dependences (=QueryMap) are recomputed we have to look at all abstract
6790 // attributes again, regardless of what changed in the last iteration.
6791 if (RecomputeDependences) {
6792 LLVM_DEBUG(
6793 dbgs() << "[Attributor] Run all AAs to recompute dependences\n");
6794 QueryMap.clear();
6795 ChangedAAs.clear();
6796 Worklist.insert(AllAbstractAttributes.begin(),
6797 AllAbstractAttributes.end());
6798 }
6799
Johannes Doerfertaade7822019-06-05 03:02:24 +00006800 // Add all abstract attributes that are potentially dependent on one that
6801 // changed to the work list.
6802 for (AbstractAttribute *ChangedAA : ChangedAAs) {
6803 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05006804 Worklist.insert(QuerriedAAs.OptionalAAs.begin(),
6805 QuerriedAAs.OptionalAAs.end());
6806 Worklist.insert(QuerriedAAs.RequiredAAs.begin(),
6807 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00006808 }
6809
Johannes Doerfertb504eb82019-08-26 18:55:47 +00006810 LLVM_DEBUG(dbgs() << "[Attributor] #Iteration: " << IterationCounter
6811 << ", Worklist+Dependent size: " << Worklist.size()
6812 << "\n");
6813
Johannes Doerfert680f6382019-11-02 02:48:05 -05006814 // Reset the changed and invalid set.
Johannes Doerfertaade7822019-06-05 03:02:24 +00006815 ChangedAAs.clear();
Johannes Doerfert680f6382019-11-02 02:48:05 -05006816 InvalidAAs.clear();
Johannes Doerfertaade7822019-06-05 03:02:24 +00006817
6818 // Update all abstract attribute in the work list and record the ones that
6819 // changed.
6820 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006821 if (!AA->getState().isAtFixpoint() && !isAssumedDead(*AA, nullptr)) {
6822 QueriedNonFixAA = false;
6823 if (AA->update(*this) == ChangeStatus::CHANGED) {
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006824 ChangedAAs.push_back(AA);
Johannes Doerfert680f6382019-11-02 02:48:05 -05006825 if (!AA->getState().isValidState())
6826 InvalidAAs.insert(AA);
Johannes Doerfert2dad7292019-10-13 21:10:31 -05006827 } else if (!QueriedNonFixAA) {
6828 // If the attribute did not query any non-fix information, the state
6829 // will not change and we can indicate that right away.
6830 AA->getState().indicateOptimisticFixpoint();
6831 }
6832 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00006833
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006834 // Check if we recompute the dependences in the next iteration.
6835 RecomputeDependences = (DepRecomputeInterval > 0 &&
6836 IterationCounter % DepRecomputeInterval == 0);
6837
Johannes Doerfert9543f142019-08-23 15:24:57 +00006838 // Add attributes to the changed set if they have been created in the last
6839 // iteration.
6840 ChangedAAs.append(AllAbstractAttributes.begin() + NumAAs,
6841 AllAbstractAttributes.end());
6842
Johannes Doerfertaade7822019-06-05 03:02:24 +00006843 // Reset the work list and repopulate with the changed abstract attributes.
6844 // Note that dependent ones are added above.
6845 Worklist.clear();
6846 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
6847
Johannes Doerfertbf112132019-08-29 01:29:44 +00006848 } while (!Worklist.empty() && (IterationCounter++ < MaxFixpointIterations ||
6849 VerifyMaxFixpointIterations));
Johannes Doerfertf7ca0fe2019-08-28 16:58:52 +00006850
Johannes Doerfertaade7822019-06-05 03:02:24 +00006851 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
6852 << IterationCounter << "/" << MaxFixpointIterations
6853 << " iterations\n");
6854
Johannes Doerfertbf112132019-08-29 01:29:44 +00006855 size_t NumFinalAAs = AllAbstractAttributes.size();
Johannes Doerfertb504eb82019-08-26 18:55:47 +00006856
Johannes Doerfertaade7822019-06-05 03:02:24 +00006857 // Reset abstract arguments not settled in a sound fixpoint by now. This
6858 // happens when we stopped the fixpoint iteration early. Note that only the
6859 // ones marked as "changed" *and* the ones transitively depending on them
6860 // need to be reverted to a pessimistic state. Others might not be in a
6861 // fixpoint state but we can use the optimistic results for them anyway.
6862 SmallPtrSet<AbstractAttribute *, 32> Visited;
6863 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
6864 AbstractAttribute *ChangedAA = ChangedAAs[u];
6865 if (!Visited.insert(ChangedAA).second)
6866 continue;
6867
6868 AbstractState &State = ChangedAA->getState();
6869 if (!State.isAtFixpoint()) {
6870 State.indicatePessimisticFixpoint();
6871
6872 NumAttributesTimedOut++;
6873 }
6874
6875 auto &QuerriedAAs = QueryMap[ChangedAA];
Johannes Doerfert680f6382019-11-02 02:48:05 -05006876 ChangedAAs.append(QuerriedAAs.OptionalAAs.begin(),
6877 QuerriedAAs.OptionalAAs.end());
6878 ChangedAAs.append(QuerriedAAs.RequiredAAs.begin(),
6879 QuerriedAAs.RequiredAAs.end());
Johannes Doerfertaade7822019-06-05 03:02:24 +00006880 }
6881
6882 LLVM_DEBUG({
6883 if (!Visited.empty())
6884 dbgs() << "\n[Attributor] Finalized " << Visited.size()
6885 << " abstract attributes.\n";
6886 });
6887
6888 unsigned NumManifested = 0;
6889 unsigned NumAtFixpoint = 0;
6890 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
6891 for (AbstractAttribute *AA : AllAbstractAttributes) {
6892 AbstractState &State = AA->getState();
6893
6894 // If there is not already a fixpoint reached, we can now take the
6895 // optimistic state. This is correct because we enforced a pessimistic one
6896 // on abstract attributes that were transitively dependent on a changed one
6897 // already above.
6898 if (!State.isAtFixpoint())
6899 State.indicateOptimisticFixpoint();
6900
6901 // If the state is invalid, we do not try to manifest it.
6902 if (!State.isValidState())
6903 continue;
6904
Johannes Doerfert9a1a1f92019-08-14 21:25:08 +00006905 // Skip dead code.
6906 if (isAssumedDead(*AA, nullptr))
6907 continue;
Johannes Doerfertaade7822019-06-05 03:02:24 +00006908 // Manifest the state and record if we changed the IR.
6909 ChangeStatus LocalChange = AA->manifest(*this);
Johannes Doerfertd1b79e02019-08-07 22:46:11 +00006910 if (LocalChange == ChangeStatus::CHANGED && AreStatisticsEnabled())
6911 AA->trackStatistics();
6912
Johannes Doerfertaade7822019-06-05 03:02:24 +00006913 ManifestChange = ManifestChange | LocalChange;
6914
6915 NumAtFixpoint++;
6916 NumManifested += (LocalChange == ChangeStatus::CHANGED);
6917 }
6918
6919 (void)NumManifested;
6920 (void)NumAtFixpoint;
6921 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
6922 << " arguments while " << NumAtFixpoint
6923 << " were in a valid fixpoint state\n");
6924
Johannes Doerfertaade7822019-06-05 03:02:24 +00006925 NumAttributesManifested += NumManifested;
6926 NumAttributesValidFixpoint += NumAtFixpoint;
6927
Fangrui Songf1826172019-08-20 07:21:43 +00006928 (void)NumFinalAAs;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006929 assert(NumFinalAAs == AllAbstractAttributes.size() &&
6930 "Expected the final number of abstract attributes to remain "
6931 "unchanged!");
Johannes Doerfert39681e72019-08-27 04:57:54 +00006932
6933 // Delete stuff at the end to avoid invalid references and a nice order.
Johannes Doerfert2f622062019-09-04 16:35:20 +00006934 {
6935 LLVM_DEBUG(dbgs() << "\n[Attributor] Delete at least "
6936 << ToBeDeletedFunctions.size() << " functions and "
6937 << ToBeDeletedBlocks.size() << " blocks and "
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006938 << ToBeDeletedInsts.size() << " instructions and "
6939 << ToBeChangedUses.size() << " uses\n");
6940
Alina Sbirlea9e66c4e2020-01-23 14:21:08 -08006941 SmallVector<WeakTrackingVH, 32> DeadInsts;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006942 SmallVector<Instruction *, 32> TerminatorsToFold;
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006943
6944 for (auto &It : ToBeChangedUses) {
6945 Use *U = It.first;
6946 Value *NewV = It.second;
6947 Value *OldV = U->get();
6948 LLVM_DEBUG(dbgs() << "Use " << *NewV << " in " << *U->getUser()
6949 << " instead of " << *OldV << "\n");
6950 U->set(NewV);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006951 if (Instruction *I = dyn_cast<Instruction>(OldV)) {
6952 CGModifiedFunctions.insert(I->getFunction());
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01006953 if (!isa<PHINode>(I) && !ToBeDeletedInsts.count(I) &&
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006954 isInstructionTriviallyDead(I))
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006955 DeadInsts.push_back(I);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006956 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006957 if (isa<Constant>(NewV) && isa<BranchInst>(U->getUser())) {
6958 Instruction *UserI = cast<Instruction>(U->getUser());
6959 if (isa<UndefValue>(NewV)) {
Hideto Uenocb5eb132019-12-27 02:39:37 +09006960 ToBeChangedToUnreachableInsts.insert(UserI);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006961 } else {
6962 TerminatorsToFold.push_back(UserI);
6963 }
6964 }
Johannes Doerfert2f622062019-09-04 16:35:20 +00006965 }
Johannes Doerferta4088c72020-01-07 16:01:57 -06006966 for (auto &V : InvokeWithDeadSuccessor)
6967 if (InvokeInst *II = dyn_cast_or_null<InvokeInst>(V)) {
6968 bool UnwindBBIsDead = II->hasFnAttr(Attribute::NoUnwind);
6969 bool NormalBBIsDead = II->hasFnAttr(Attribute::NoReturn);
6970 bool Invoke2CallAllowed =
6971 !AAIsDeadFunction::mayCatchAsynchronousExceptions(
6972 *II->getFunction());
6973 assert((UnwindBBIsDead || NormalBBIsDead) &&
6974 "Invoke does not have dead successors!");
6975 BasicBlock *BB = II->getParent();
6976 BasicBlock *NormalDestBB = II->getNormalDest();
6977 if (UnwindBBIsDead) {
6978 Instruction *NormalNextIP = &NormalDestBB->front();
6979 if (Invoke2CallAllowed) {
6980 changeToCall(II);
6981 NormalNextIP = BB->getTerminator();
6982 }
6983 if (NormalBBIsDead)
6984 ToBeChangedToUnreachableInsts.insert(NormalNextIP);
6985 } else {
6986 assert(NormalBBIsDead && "Broken invariant!");
6987 if (!NormalDestBB->getUniquePredecessor())
6988 NormalDestBB = SplitBlockPredecessors(NormalDestBB, {BB}, ".dead");
6989 ToBeChangedToUnreachableInsts.insert(&NormalDestBB->front());
6990 }
6991 }
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06006992 for (auto &V : ToBeChangedToUnreachableInsts)
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006993 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
6994 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfert1e46eb72020-01-07 15:10:30 -06006995 changeToUnreachable(I, /* UseLLVMTrap */ false);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06006996 }
6997 for (Instruction *I : TerminatorsToFold) {
6998 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05006999 ConstantFoldTerminator(I->getParent());
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007000 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007001
Johannes Doerfert5429c822020-01-11 23:30:36 -06007002 for (auto &V : ToBeDeletedInsts) {
7003 if (Instruction *I = dyn_cast_or_null<Instruction>(V)) {
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007004 CGModifiedFunctions.insert(I->getFunction());
Johannes Doerfert5429c822020-01-11 23:30:36 -06007005 I->replaceAllUsesWith(UndefValue::get(I->getType()));
7006 if (!isa<PHINode>(I) && isInstructionTriviallyDead(I))
7007 DeadInsts.push_back(I);
7008 else
7009 I->eraseFromParent();
7010 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007011 }
7012
7013 RecursivelyDeleteTriviallyDeadInstructions(DeadInsts);
Johannes Doerfertb19cd272019-09-03 20:42:16 +00007014
Johannes Doerfert2f622062019-09-04 16:35:20 +00007015 if (unsigned NumDeadBlocks = ToBeDeletedBlocks.size()) {
7016 SmallVector<BasicBlock *, 8> ToBeDeletedBBs;
7017 ToBeDeletedBBs.reserve(NumDeadBlocks);
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007018 for (BasicBlock *BB : ToBeDeletedBlocks) {
7019 CGModifiedFunctions.insert(BB->getParent());
7020 ToBeDeletedBBs.push_back(BB);
7021 }
Johannes Doerfert5e442a52019-10-30 17:34:59 -05007022 // Actually we do not delete the blocks but squash them into a single
7023 // unreachable but untangling branches that jump here is something we need
7024 // to do in a more generic way.
7025 DetatchDeadBlocks(ToBeDeletedBBs, nullptr);
7026 STATS_DECL(AAIsDead, BasicBlock, "Number of dead basic blocks deleted.");
7027 BUILD_STAT_NAME(AAIsDead, BasicBlock) += ToBeDeletedBlocks.size();
Johannes Doerfert2f622062019-09-04 16:35:20 +00007028 }
Johannes Doerfertb19cd272019-09-03 20:42:16 +00007029
Johannes Doerfert2f622062019-09-04 16:35:20 +00007030 // Identify dead internal functions and delete them. This happens outside
7031 // the other fixpoint analysis as we might treat potentially dead functions
7032 // as live to lower the number of iterations. If they happen to be dead, the
7033 // below fixpoint loop will identify and eliminate them.
7034 SmallVector<Function *, 8> InternalFns;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007035 for (Function *F : Functions)
7036 if (F->hasLocalLinkage())
7037 InternalFns.push_back(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00007038
7039 bool FoundDeadFn = true;
7040 while (FoundDeadFn) {
7041 FoundDeadFn = false;
7042 for (unsigned u = 0, e = InternalFns.size(); u < e; ++u) {
7043 Function *F = InternalFns[u];
7044 if (!F)
7045 continue;
7046
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007047 bool AllCallSitesKnown;
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06007048 if (!checkForAllCallSites(
7049 [this](AbstractCallSite ACS) {
7050 return ToBeDeletedFunctions.count(
7051 ACS.getInstruction()->getFunction());
7052 },
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007053 *F, true, nullptr, AllCallSitesKnown))
Johannes Doerfert2f622062019-09-04 16:35:20 +00007054 continue;
7055
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007056 ToBeDeletedFunctions.insert(F);
Johannes Doerfert2f622062019-09-04 16:35:20 +00007057 InternalFns[u] = nullptr;
7058 FoundDeadFn = true;
7059 }
7060 }
Johannes Doerfert39681e72019-08-27 04:57:54 +00007061 }
7062
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007063 // Rewrite the functions as requested during manifest.
7064 ManifestChange =
7065 ManifestChange | rewriteFunctionSignatures(CGModifiedFunctions);
7066
7067 for (Function *Fn : CGModifiedFunctions)
7068 CGUpdater.reanalyzeFunction(*Fn);
7069
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007070 STATS_DECL(AAIsDead, Function, "Number of dead functions deleted.");
7071 BUILD_STAT_NAME(AAIsDead, Function) += ToBeDeletedFunctions.size();
7072
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007073 for (Function *Fn : ToBeDeletedFunctions)
7074 CGUpdater.removeFunction(*Fn);
Johannes Doerfert6b9ee2d2020-01-02 16:53:37 -06007075
Johannes Doerfertbf112132019-08-29 01:29:44 +00007076 if (VerifyMaxFixpointIterations &&
7077 IterationCounter != MaxFixpointIterations) {
7078 errs() << "\n[Attributor] Fixpoint iteration done after: "
7079 << IterationCounter << "/" << MaxFixpointIterations
7080 << " iterations\n";
7081 llvm_unreachable("The fixpoint was not reached with exactly the number of "
7082 "specified iterations!");
7083 }
7084
Johannes Doerfertaade7822019-06-05 03:02:24 +00007085 return ManifestChange;
7086}
7087
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007088bool Attributor::isValidFunctionSignatureRewrite(
7089 Argument &Arg, ArrayRef<Type *> ReplacementTypes) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007090
7091 auto CallSiteCanBeChanged = [](AbstractCallSite ACS) {
7092 // Forbid must-tail calls for now.
7093 return !ACS.isCallbackCall() && !ACS.getCallSite().isMustTailCall();
7094 };
7095
7096 Function *Fn = Arg.getParent();
7097 // Avoid var-arg functions for now.
7098 if (Fn->isVarArg()) {
7099 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite var-args functions\n");
7100 return false;
7101 }
7102
7103 // Avoid functions with complicated argument passing semantics.
7104 AttributeList FnAttributeList = Fn->getAttributes();
7105 if (FnAttributeList.hasAttrSomewhere(Attribute::Nest) ||
7106 FnAttributeList.hasAttrSomewhere(Attribute::StructRet) ||
7107 FnAttributeList.hasAttrSomewhere(Attribute::InAlloca)) {
7108 LLVM_DEBUG(
7109 dbgs() << "[Attributor] Cannot rewrite due to complex attribute\n");
7110 return false;
7111 }
7112
7113 // Avoid callbacks for now.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007114 bool AllCallSitesKnown;
7115 if (!checkForAllCallSites(CallSiteCanBeChanged, *Fn, true, nullptr,
7116 AllCallSitesKnown)) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007117 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite all call sites\n");
7118 return false;
7119 }
7120
7121 auto InstPred = [](Instruction &I) {
7122 if (auto *CI = dyn_cast<CallInst>(&I))
7123 return !CI->isMustTailCall();
7124 return true;
7125 };
7126
7127 // Forbid must-tail calls for now.
7128 // TODO:
7129 bool AnyDead;
7130 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(*Fn);
7131 if (!checkForAllInstructionsImpl(OpcodeInstMap, InstPred, nullptr, AnyDead,
7132 {Instruction::Call})) {
7133 LLVM_DEBUG(dbgs() << "[Attributor] Cannot rewrite due to instructions\n");
7134 return false;
7135 }
7136
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007137 return true;
7138}
7139
7140bool Attributor::registerFunctionSignatureRewrite(
7141 Argument &Arg, ArrayRef<Type *> ReplacementTypes,
7142 ArgumentReplacementInfo::CalleeRepairCBTy &&CalleeRepairCB,
7143 ArgumentReplacementInfo::ACSRepairCBTy &&ACSRepairCB) {
7144 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
7145 << Arg.getParent()->getName() << " with "
7146 << ReplacementTypes.size() << " replacements\n");
7147 assert(isValidFunctionSignatureRewrite(Arg, ReplacementTypes) &&
7148 "Cannot register an invalid rewrite");
7149
7150 Function *Fn = Arg.getParent();
Johannes Doerfert75133632019-10-10 01:39:16 -05007151 SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = ArgumentReplacementMap[Fn];
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007152 if (ARIs.empty())
Johannes Doerfert75133632019-10-10 01:39:16 -05007153 ARIs.resize(Fn->arg_size());
7154
7155 // If we have a replacement already with less than or equal new arguments,
7156 // ignore this request.
7157 ArgumentReplacementInfo *&ARI = ARIs[Arg.getArgNo()];
7158 if (ARI && ARI->getNumReplacementArgs() <= ReplacementTypes.size()) {
7159 LLVM_DEBUG(dbgs() << "[Attributor] Existing rewrite is preferred\n");
7160 return false;
7161 }
7162
7163 // If we have a replacement already but we like the new one better, delete
7164 // the old.
7165 if (ARI)
7166 delete ARI;
7167
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007168 LLVM_DEBUG(dbgs() << "[Attributor] Register new rewrite of " << Arg << " in "
7169 << Arg.getParent()->getName() << " with "
7170 << ReplacementTypes.size() << " replacements\n");
7171
Johannes Doerfert75133632019-10-10 01:39:16 -05007172 // Remember the replacement.
7173 ARI = new ArgumentReplacementInfo(*this, Arg, ReplacementTypes,
7174 std::move(CalleeRepairCB),
7175 std::move(ACSRepairCB));
7176
7177 return true;
7178}
7179
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007180ChangeStatus Attributor::rewriteFunctionSignatures(
7181 SmallPtrSetImpl<Function *> &ModifiedFns) {
Johannes Doerfert75133632019-10-10 01:39:16 -05007182 ChangeStatus Changed = ChangeStatus::UNCHANGED;
7183
7184 for (auto &It : ArgumentReplacementMap) {
7185 Function *OldFn = It.getFirst();
7186
7187 // Deleted functions do not require rewrites.
7188 if (ToBeDeletedFunctions.count(OldFn))
7189 continue;
7190
7191 const SmallVectorImpl<ArgumentReplacementInfo *> &ARIs = It.getSecond();
7192 assert(ARIs.size() == OldFn->arg_size() && "Inconsistent state!");
7193
7194 SmallVector<Type *, 16> NewArgumentTypes;
7195 SmallVector<AttributeSet, 16> NewArgumentAttributes;
7196
7197 // Collect replacement argument types and copy over existing attributes.
7198 AttributeList OldFnAttributeList = OldFn->getAttributes();
7199 for (Argument &Arg : OldFn->args()) {
7200 if (ArgumentReplacementInfo *ARI = ARIs[Arg.getArgNo()]) {
7201 NewArgumentTypes.append(ARI->ReplacementTypes.begin(),
7202 ARI->ReplacementTypes.end());
7203 NewArgumentAttributes.append(ARI->getNumReplacementArgs(),
7204 AttributeSet());
7205 } else {
7206 NewArgumentTypes.push_back(Arg.getType());
7207 NewArgumentAttributes.push_back(
7208 OldFnAttributeList.getParamAttributes(Arg.getArgNo()));
7209 }
7210 }
7211
7212 FunctionType *OldFnTy = OldFn->getFunctionType();
7213 Type *RetTy = OldFnTy->getReturnType();
7214
7215 // Construct the new function type using the new arguments types.
7216 FunctionType *NewFnTy =
7217 FunctionType::get(RetTy, NewArgumentTypes, OldFnTy->isVarArg());
7218
7219 LLVM_DEBUG(dbgs() << "[Attributor] Function rewrite '" << OldFn->getName()
7220 << "' from " << *OldFn->getFunctionType() << " to "
7221 << *NewFnTy << "\n");
7222
7223 // Create the new function body and insert it into the module.
7224 Function *NewFn = Function::Create(NewFnTy, OldFn->getLinkage(),
7225 OldFn->getAddressSpace(), "");
7226 OldFn->getParent()->getFunctionList().insert(OldFn->getIterator(), NewFn);
7227 NewFn->takeName(OldFn);
7228 NewFn->copyAttributesFrom(OldFn);
7229
7230 // Patch the pointer to LLVM function in debug info descriptor.
7231 NewFn->setSubprogram(OldFn->getSubprogram());
7232 OldFn->setSubprogram(nullptr);
7233
7234 // Recompute the parameter attributes list based on the new arguments for
7235 // the function.
7236 LLVMContext &Ctx = OldFn->getContext();
7237 NewFn->setAttributes(AttributeList::get(
7238 Ctx, OldFnAttributeList.getFnAttributes(),
7239 OldFnAttributeList.getRetAttributes(), NewArgumentAttributes));
7240
7241 // Since we have now created the new function, splice the body of the old
7242 // function right into the new function, leaving the old rotting hulk of the
7243 // function empty.
7244 NewFn->getBasicBlockList().splice(NewFn->begin(),
7245 OldFn->getBasicBlockList());
7246
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007247 // Set of all "call-like" instructions that invoke the old function mapped
7248 // to their new replacements.
7249 SmallVector<std::pair<CallBase *, CallBase *>, 8> CallSitePairs;
Johannes Doerfert75133632019-10-10 01:39:16 -05007250
7251 // Callback to create a new "call-like" instruction for a given one.
7252 auto CallSiteReplacementCreator = [&](AbstractCallSite ACS) {
7253 CallBase *OldCB = cast<CallBase>(ACS.getInstruction());
7254 const AttributeList &OldCallAttributeList = OldCB->getAttributes();
7255
7256 // Collect the new argument operands for the replacement call site.
7257 SmallVector<Value *, 16> NewArgOperands;
7258 SmallVector<AttributeSet, 16> NewArgOperandAttributes;
7259 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size(); ++OldArgNum) {
7260 unsigned NewFirstArgNum = NewArgOperands.size();
Ilya Biryukov4f82af82019-12-31 10:21:52 +01007261 (void)NewFirstArgNum; // only used inside assert.
Johannes Doerfert75133632019-10-10 01:39:16 -05007262 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
7263 if (ARI->ACSRepairCB)
7264 ARI->ACSRepairCB(*ARI, ACS, NewArgOperands);
7265 assert(ARI->getNumReplacementArgs() + NewFirstArgNum ==
7266 NewArgOperands.size() &&
7267 "ACS repair callback did not provide as many operand as new "
7268 "types were registered!");
7269 // TODO: Exose the attribute set to the ACS repair callback
7270 NewArgOperandAttributes.append(ARI->ReplacementTypes.size(),
7271 AttributeSet());
7272 } else {
7273 NewArgOperands.push_back(ACS.getCallArgOperand(OldArgNum));
7274 NewArgOperandAttributes.push_back(
7275 OldCallAttributeList.getParamAttributes(OldArgNum));
7276 }
7277 }
7278
7279 assert(NewArgOperands.size() == NewArgOperandAttributes.size() &&
7280 "Mismatch # argument operands vs. # argument operand attributes!");
7281 assert(NewArgOperands.size() == NewFn->arg_size() &&
7282 "Mismatch # argument operands vs. # function arguments!");
7283
7284 SmallVector<OperandBundleDef, 4> OperandBundleDefs;
7285 OldCB->getOperandBundlesAsDefs(OperandBundleDefs);
7286
7287 // Create a new call or invoke instruction to replace the old one.
7288 CallBase *NewCB;
7289 if (InvokeInst *II = dyn_cast<InvokeInst>(OldCB)) {
7290 NewCB =
7291 InvokeInst::Create(NewFn, II->getNormalDest(), II->getUnwindDest(),
7292 NewArgOperands, OperandBundleDefs, "", OldCB);
7293 } else {
7294 auto *NewCI = CallInst::Create(NewFn, NewArgOperands, OperandBundleDefs,
7295 "", OldCB);
7296 NewCI->setTailCallKind(cast<CallInst>(OldCB)->getTailCallKind());
7297 NewCB = NewCI;
7298 }
7299
7300 // Copy over various properties and the new attributes.
Johannes Doerfert75133632019-10-10 01:39:16 -05007301 uint64_t W;
7302 if (OldCB->extractProfTotalWeight(W))
7303 NewCB->setProfWeight(W);
7304 NewCB->setCallingConv(OldCB->getCallingConv());
7305 NewCB->setDebugLoc(OldCB->getDebugLoc());
7306 NewCB->takeName(OldCB);
7307 NewCB->setAttributes(AttributeList::get(
7308 Ctx, OldCallAttributeList.getFnAttributes(),
7309 OldCallAttributeList.getRetAttributes(), NewArgOperandAttributes));
7310
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007311 CallSitePairs.push_back({OldCB, NewCB});
Johannes Doerfert75133632019-10-10 01:39:16 -05007312 return true;
7313 };
7314
7315 // Use the CallSiteReplacementCreator to create replacement call sites.
Johannes Doerfert368f7ee2019-12-30 16:12:36 -06007316 bool AllCallSitesKnown;
7317 bool Success = checkForAllCallSites(CallSiteReplacementCreator, *OldFn,
7318 true, nullptr, AllCallSitesKnown);
Ilya Biryukov4f82af82019-12-31 10:21:52 +01007319 (void)Success;
Johannes Doerfert75133632019-10-10 01:39:16 -05007320 assert(Success && "Assumed call site replacement to succeed!");
7321
7322 // Rewire the arguments.
7323 auto OldFnArgIt = OldFn->arg_begin();
7324 auto NewFnArgIt = NewFn->arg_begin();
7325 for (unsigned OldArgNum = 0; OldArgNum < ARIs.size();
7326 ++OldArgNum, ++OldFnArgIt) {
7327 if (ArgumentReplacementInfo *ARI = ARIs[OldArgNum]) {
7328 if (ARI->CalleeRepairCB)
7329 ARI->CalleeRepairCB(*ARI, *NewFn, NewFnArgIt);
7330 NewFnArgIt += ARI->ReplacementTypes.size();
7331 } else {
7332 NewFnArgIt->takeName(&*OldFnArgIt);
7333 OldFnArgIt->replaceAllUsesWith(&*NewFnArgIt);
7334 ++NewFnArgIt;
7335 }
7336 }
7337
7338 // Eliminate the instructions *after* we visited all of them.
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007339 for (auto &CallSitePair : CallSitePairs) {
7340 CallBase &OldCB = *CallSitePair.first;
7341 CallBase &NewCB = *CallSitePair.second;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007342 // We do not modify the call graph here but simply reanalyze the old
7343 // function. This should be revisited once the old PM is gone.
7344 ModifiedFns.insert(OldCB.getFunction());
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007345 OldCB.replaceAllUsesWith(&NewCB);
7346 OldCB.eraseFromParent();
7347 }
Johannes Doerfert75133632019-10-10 01:39:16 -05007348
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007349 // Replace the function in the call graph (if any).
7350 CGUpdater.replaceFunctionWith(*OldFn, *NewFn);
7351
7352 // If the old function was modified and needed to be reanalyzed, the new one
7353 // does now.
7354 if (ModifiedFns.erase(OldFn))
7355 ModifiedFns.insert(NewFn);
Johannes Doerfertd2d2fb12020-01-02 17:20:47 -06007356
Johannes Doerfert75133632019-10-10 01:39:16 -05007357 Changed = ChangeStatus::CHANGED;
7358 }
7359
7360 return Changed;
7361}
7362
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007363void Attributor::initializeInformationCache(Function &F) {
7364
7365 // Walk all instructions to find interesting instructions that might be
7366 // queried by abstract attributes during their initialization or update.
7367 // This has to happen before we create attributes.
7368 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
7369 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
7370
7371 for (Instruction &I : instructions(&F)) {
7372 bool IsInterestingOpcode = false;
7373
7374 // To allow easy access to all instructions in a function with a given
7375 // opcode we store them in the InfoCache. As not all opcodes are interesting
7376 // to concrete attributes we only cache the ones that are as identified in
7377 // the following switch.
7378 // Note: There are no concrete attributes now so this is initially empty.
7379 switch (I.getOpcode()) {
7380 default:
7381 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
7382 "New call site/base instruction type needs to be known int the "
7383 "Attributor.");
7384 break;
7385 case Instruction::Load:
7386 // The alignment of a pointer is interesting for loads.
7387 case Instruction::Store:
7388 // The alignment of a pointer is interesting for stores.
7389 case Instruction::Call:
7390 case Instruction::CallBr:
7391 case Instruction::Invoke:
7392 case Instruction::CleanupRet:
7393 case Instruction::CatchSwitch:
Johannes Doerfert5732f562019-12-24 19:25:08 -06007394 case Instruction::AtomicRMW:
7395 case Instruction::AtomicCmpXchg:
Hideto Uenoef4febd2019-12-29 17:34:08 +09007396 case Instruction::Br:
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007397 case Instruction::Resume:
7398 case Instruction::Ret:
7399 IsInterestingOpcode = true;
7400 }
7401 if (IsInterestingOpcode)
7402 InstOpcodeMap[I.getOpcode()].push_back(&I);
7403 if (I.mayReadOrWriteMemory())
7404 ReadOrWriteInsts.push_back(&I);
7405 }
7406}
7407
Johannes Doerfert12173e62019-10-13 20:25:25 -05007408void Attributor::recordDependence(const AbstractAttribute &FromAA,
Johannes Doerfert680f6382019-11-02 02:48:05 -05007409 const AbstractAttribute &ToAA,
7410 DepClassTy DepClass) {
Johannes Doerfert2dad7292019-10-13 21:10:31 -05007411 if (FromAA.getState().isAtFixpoint())
7412 return;
7413
Johannes Doerfert680f6382019-11-02 02:48:05 -05007414 if (DepClass == DepClassTy::REQUIRED)
7415 QueryMap[&FromAA].RequiredAAs.insert(
7416 const_cast<AbstractAttribute *>(&ToAA));
7417 else
7418 QueryMap[&FromAA].OptionalAAs.insert(
7419 const_cast<AbstractAttribute *>(&ToAA));
Johannes Doerfert2dad7292019-10-13 21:10:31 -05007420 QueriedNonFixAA = true;
Johannes Doerfert12173e62019-10-13 20:25:25 -05007421}
7422
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00007423void Attributor::identifyDefaultAbstractAttributes(Function &F) {
Johannes Doerfert2f622062019-09-04 16:35:20 +00007424 if (!VisitedFunctions.insert(&F).second)
7425 return;
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05007426 if (F.isDeclaration())
7427 return;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007428
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007429 IRPosition FPos = IRPosition::function(F);
7430
Johannes Doerfert305b9612019-08-04 18:40:01 +00007431 // Check for dead BasicBlocks in every function.
Johannes Doerfert21fe0a32019-08-06 00:55:11 +00007432 // We need dead instruction detection because we do not want to deal with
7433 // broken IR in which SSA rules do not apply.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007434 getOrCreateAAFor<AAIsDead>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00007435
7436 // Every function might be "will-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007437 getOrCreateAAFor<AAWillReturn>(FPos);
Johannes Doerfert305b9612019-08-04 18:40:01 +00007438
Johannes Doerfert58f324a2019-12-24 18:48:50 -06007439 // Every function might contain instructions that cause "undefined behavior".
7440 getOrCreateAAFor<AAUndefinedBehavior>(FPos);
7441
Stefan Stipanovic53605892019-06-27 11:27:54 +00007442 // Every function can be nounwind.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007443 getOrCreateAAFor<AANoUnwind>(FPos);
Stefan Stipanovic53605892019-06-27 11:27:54 +00007444
Stefan Stipanovic06263672019-07-11 21:37:40 +00007445 // Every function might be marked "nosync"
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007446 getOrCreateAAFor<AANoSync>(FPos);
Stefan Stipanovic06263672019-07-11 21:37:40 +00007447
Hideto Ueno65bbaf92019-07-12 17:38:51 +00007448 // Every function might be "no-free".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007449 getOrCreateAAFor<AANoFree>(FPos);
Hideto Ueno65bbaf92019-07-12 17:38:51 +00007450
Johannes Doerferte83f3032019-08-05 23:22:05 +00007451 // Every function might be "no-return".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007452 getOrCreateAAFor<AANoReturn>(FPos);
Johannes Doerferte83f3032019-08-05 23:22:05 +00007453
Hideto Ueno63f60662019-09-21 15:13:19 +00007454 // Every function might be "no-recurse".
7455 getOrCreateAAFor<AANoRecurse>(FPos);
7456
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007457 // Every function might be "readnone/readonly/writeonly/...".
7458 getOrCreateAAFor<AAMemoryBehavior>(FPos);
7459
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007460 // Every function might be applicable for Heap-To-Stack conversion.
7461 if (EnableHeapToStack)
7462 getOrCreateAAFor<AAHeapToStack>(FPos);
7463
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00007464 // Return attributes are only appropriate if the return type is non void.
7465 Type *ReturnType = F.getReturnType();
7466 if (!ReturnType->isVoidTy()) {
7467 // Argument attribute "returned" --- Create only one per function even
7468 // though it is an argument attribute.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007469 getOrCreateAAFor<AAReturnedValues>(FPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00007470
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007471 IRPosition RetPos = IRPosition::returned(F);
7472
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007473 // Every returned value might be dead.
7474 getOrCreateAAFor<AAIsDead>(RetPos);
7475
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007476 // Every function might be simplified.
7477 getOrCreateAAFor<AAValueSimplify>(RetPos);
7478
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00007479 if (ReturnType->isPointerTy()) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007480
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00007481 // Every function with pointer return type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007482 getOrCreateAAFor<AAAlign>(RetPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00007483
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00007484 // Every function with pointer return type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007485 getOrCreateAAFor<AANonNull>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00007486
7487 // Every function with pointer return type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007488 getOrCreateAAFor<AANoAlias>(RetPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00007489
7490 // Every function with pointer return type might be marked
7491 // dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007492 getOrCreateAAFor<AADereferenceable>(RetPos);
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00007493 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00007494 }
7495
Hideto Ueno54869ec2019-07-15 06:49:04 +00007496 for (Argument &Arg : F.args()) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007497 IRPosition ArgPos = IRPosition::argument(Arg);
7498
7499 // Every argument might be simplified.
7500 getOrCreateAAFor<AAValueSimplify>(ArgPos);
7501
Hideto Ueno19c07af2019-07-23 08:16:17 +00007502 if (Arg.getType()->isPointerTy()) {
7503 // Every argument with pointer type might be marked nonnull.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007504 getOrCreateAAFor<AANonNull>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00007505
Hideto Uenocbab3342019-08-29 05:52:00 +00007506 // Every argument with pointer type might be marked noalias.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007507 getOrCreateAAFor<AANoAlias>(ArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00007508
Hideto Ueno19c07af2019-07-23 08:16:17 +00007509 // Every argument with pointer type might be marked dereferenceable.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007510 getOrCreateAAFor<AADereferenceable>(ArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00007511
7512 // Every argument with pointer type might be marked align.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007513 getOrCreateAAFor<AAAlign>(ArgPos);
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00007514
7515 // Every argument with pointer type might be marked nocapture.
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007516 getOrCreateAAFor<AANoCapture>(ArgPos);
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007517
7518 // Every argument with pointer type might be marked
7519 // "readnone/readonly/writeonly/..."
7520 getOrCreateAAFor<AAMemoryBehavior>(ArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007521
7522 // Every argument with pointer type might be marked nofree.
7523 getOrCreateAAFor<AANoFree>(ArgPos);
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007524
7525 // Every argument with pointer type might be privatizable (or promotable)
7526 getOrCreateAAFor<AAPrivatizablePtr>(ArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00007527 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00007528 }
7529
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007530 auto CallSitePred = [&](Instruction &I) -> bool {
Hideto Ueno54869ec2019-07-15 06:49:04 +00007531 CallSite CS(&I);
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007532 if (Function *Callee = CS.getCalledFunction()) {
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05007533 // Skip declerations except if annotations on their call sites were
7534 // explicitly requested.
Johannes Doerfert139c9ef2019-12-13 23:41:02 -06007535 if (!AnnotateDeclarationCallSites && Callee->isDeclaration() &&
7536 !Callee->hasMetadata(LLVMContext::MD_callback))
Johannes Doerfertc36e2eb2019-10-31 20:15:02 -05007537 return true;
7538
7539 if (!Callee->getReturnType()->isVoidTy() && !CS->use_empty()) {
Hideto Ueno188f9a32020-01-15 15:25:52 +09007540
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007541 IRPosition CSRetPos = IRPosition::callsite_returned(CS);
7542
7543 // Call site return values might be dead.
7544 getOrCreateAAFor<AAIsDead>(CSRetPos);
Hideto Ueno188f9a32020-01-15 15:25:52 +09007545
7546 // Call site return integer values might be limited by a constant range.
7547 if (Callee->getReturnType()->isIntegerTy()) {
7548 getOrCreateAAFor<AAValueConstantRange>(CSRetPos);
7549 }
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007550 }
7551
Johannes Doerfert28880192019-12-31 00:57:00 -06007552 for (int i = 0, e = CS.getNumArgOperands(); i < e; i++) {
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007553
7554 IRPosition CSArgPos = IRPosition::callsite_argument(CS, i);
7555
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007556 // Every call site argument might be dead.
7557 getOrCreateAAFor<AAIsDead>(CSArgPos);
7558
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007559 // Call site argument might be simplified.
7560 getOrCreateAAFor<AAValueSimplify>(CSArgPos);
7561
Hideto Ueno54869ec2019-07-15 06:49:04 +00007562 if (!CS.getArgument(i)->getType()->isPointerTy())
7563 continue;
7564
7565 // Call site argument attribute "non-null".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007566 getOrCreateAAFor<AANonNull>(CSArgPos);
Hideto Ueno19c07af2019-07-23 08:16:17 +00007567
Hideto Uenocbab3342019-08-29 05:52:00 +00007568 // Call site argument attribute "no-alias".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007569 getOrCreateAAFor<AANoAlias>(CSArgPos);
Hideto Uenocbab3342019-08-29 05:52:00 +00007570
Hideto Ueno19c07af2019-07-23 08:16:17 +00007571 // Call site argument attribute "dereferenceable".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007572 getOrCreateAAFor<AADereferenceable>(CSArgPos);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00007573
7574 // Call site argument attribute "align".
Johannes Doerfert97fd5822019-09-04 16:26:20 +00007575 getOrCreateAAFor<AAAlign>(CSArgPos);
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007576
Johannes Doerfert28880192019-12-31 00:57:00 -06007577 // Call site argument attribute
7578 // "readnone/readonly/writeonly/..."
7579 getOrCreateAAFor<AAMemoryBehavior>(CSArgPos);
7580
Hideto Ueno4ecf2552019-12-12 13:42:40 +00007581 // Call site argument attribute "nofree".
7582 getOrCreateAAFor<AANoFree>(CSArgPos);
Hideto Ueno54869ec2019-07-15 06:49:04 +00007583 }
7584 }
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007585 return true;
7586 };
7587
7588 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
7589 bool Success, AnyDead = false;
7590 Success = checkForAllInstructionsImpl(
7591 OpcodeInstMap, CallSitePred, nullptr, AnyDead,
7592 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
7593 (unsigned)Instruction::Call});
7594 (void)Success;
7595 assert(Success && !AnyDead && "Expected the check call to be successful!");
7596
7597 auto LoadStorePred = [&](Instruction &I) -> bool {
7598 if (isa<LoadInst>(I))
7599 getOrCreateAAFor<AAAlign>(
7600 IRPosition::value(*cast<LoadInst>(I).getPointerOperand()));
7601 else
7602 getOrCreateAAFor<AAAlign>(
7603 IRPosition::value(*cast<StoreInst>(I).getPointerOperand()));
7604 return true;
7605 };
7606 Success = checkForAllInstructionsImpl(
7607 OpcodeInstMap, LoadStorePred, nullptr, AnyDead,
7608 {(unsigned)Instruction::Load, (unsigned)Instruction::Store});
7609 (void)Success;
7610 assert(Success && !AnyDead && "Expected the check call to be successful!");
Johannes Doerfertaade7822019-06-05 03:02:24 +00007611}
7612
7613/// Helpers to ease debugging through output streams and print calls.
7614///
7615///{
7616raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
7617 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
7618}
7619
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007620raw_ostream &llvm::operator<<(raw_ostream &OS, IRPosition::Kind AP) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00007621 switch (AP) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007622 case IRPosition::IRP_INVALID:
7623 return OS << "inv";
7624 case IRPosition::IRP_FLOAT:
7625 return OS << "flt";
7626 case IRPosition::IRP_RETURNED:
7627 return OS << "fn_ret";
7628 case IRPosition::IRP_CALL_SITE_RETURNED:
7629 return OS << "cs_ret";
7630 case IRPosition::IRP_FUNCTION:
7631 return OS << "fn";
7632 case IRPosition::IRP_CALL_SITE:
7633 return OS << "cs";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007634 case IRPosition::IRP_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00007635 return OS << "arg";
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007636 case IRPosition::IRP_CALL_SITE_ARGUMENT:
Johannes Doerfertaade7822019-06-05 03:02:24 +00007637 return OS << "cs_arg";
Johannes Doerfertaade7822019-06-05 03:02:24 +00007638 }
7639 llvm_unreachable("Unknown attribute position!");
7640}
7641
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007642raw_ostream &llvm::operator<<(raw_ostream &OS, const IRPosition &Pos) {
Johannes Doerfert710ebb02019-08-14 21:18:01 +00007643 const Value &AV = Pos.getAssociatedValue();
7644 return OS << "{" << Pos.getPositionKind() << ":" << AV.getName() << " ["
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007645 << Pos.getAnchorValue().getName() << "@" << Pos.getArgNo() << "]}";
7646}
7647
Johannes Doerfert1a746452019-10-20 22:28:49 -05007648template <typename base_ty, base_ty BestState, base_ty WorstState>
Hideto Ueno188f9a32020-01-15 15:25:52 +09007649raw_ostream &
7650llvm::operator<<(raw_ostream &OS,
7651 const IntegerStateBase<base_ty, BestState, WorstState> &S) {
Johannes Doerfertacc80792019-08-12 22:07:34 +00007652 return OS << "(" << S.getKnown() << "-" << S.getAssumed() << ")"
7653 << static_cast<const AbstractState &>(S);
7654}
7655
Hideto Ueno188f9a32020-01-15 15:25:52 +09007656raw_ostream &llvm::operator<<(raw_ostream &OS, const IntegerRangeState &S) {
7657 OS << "range-state(" << S.getBitWidth() << ")<";
7658 S.getKnown().print(OS);
7659 OS << " / ";
7660 S.getAssumed().print(OS);
7661 OS << ">";
7662
7663 return OS << static_cast<const AbstractState &>(S);
7664}
7665
Johannes Doerfertaade7822019-06-05 03:02:24 +00007666raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
7667 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
7668}
7669
7670raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
7671 AA.print(OS);
7672 return OS;
7673}
7674
7675void AbstractAttribute::print(raw_ostream &OS) const {
Johannes Doerfertfb69f762019-08-05 23:32:31 +00007676 OS << "[P: " << getIRPosition() << "][" << getAsStr() << "][S: " << getState()
7677 << "]";
Johannes Doerfertaade7822019-06-05 03:02:24 +00007678}
7679///}
7680
7681/// ----------------------------------------------------------------------------
7682/// Pass (Manager) Boilerplate
7683/// ----------------------------------------------------------------------------
7684
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007685static bool runAttributorOnFunctions(InformationCache &InfoCache,
7686 SetVector<Function *> &Functions,
7687 AnalysisGetter &AG,
7688 CallGraphUpdater &CGUpdater) {
7689 if (DisableAttributor || Functions.empty())
Johannes Doerfertaade7822019-06-05 03:02:24 +00007690 return false;
7691
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007692 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << Functions.size()
Johannes Doerfertaade7822019-06-05 03:02:24 +00007693 << " functions.\n");
7694
7695 // Create an Attributor and initially empty information cache that is filled
7696 // while we identify default attribute opportunities.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007697 Attributor A(Functions, InfoCache, CGUpdater, DepRecInterval);
Johannes Doerfertaade7822019-06-05 03:02:24 +00007698
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007699 for (Function *F : Functions)
7700 A.initializeInformationCache(*F);
Johannes Doerfert3ab9e8b2019-09-17 10:52:41 +00007701
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007702 for (Function *F : Functions) {
7703 if (F->hasExactDefinition())
Johannes Doerfertb0412e42019-09-04 16:16:13 +00007704 NumFnWithExactDefinition++;
7705 else
Johannes Doerfertaade7822019-06-05 03:02:24 +00007706 NumFnWithoutExactDefinition++;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007707
Johannes Doerfert2f622062019-09-04 16:35:20 +00007708 // We look at internal functions only on-demand but if any use is not a
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007709 // direct call or outside the current set of analyzed functions, we have to
7710 // do it eagerly.
7711 if (F->hasLocalLinkage()) {
7712 if (llvm::all_of(F->uses(), [&Functions](const Use &U) {
7713 ImmutableCallSite ICS(U.getUser());
7714 return ICS && ICS.isCallee(&U) &&
7715 Functions.count(const_cast<Function *>(ICS.getCaller()));
Johannes Doerfert2f622062019-09-04 16:35:20 +00007716 }))
7717 continue;
7718 }
7719
Johannes Doerfertaade7822019-06-05 03:02:24 +00007720 // Populate the Attributor with abstract attribute opportunities in the
7721 // function and the information cache with IR information.
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007722 A.identifyDefaultAbstractAttributes(*F);
Johannes Doerfertaade7822019-06-05 03:02:24 +00007723 }
7724
Johannes Doerfert77a9e612020-01-11 23:36:17 -06007725 ChangeStatus Changed = A.run();
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007726 assert(!verifyModule(*Functions.front()->getParent(), &errs()) &&
7727 "Module verification failed!");
Johannes Doerfert77a9e612020-01-11 23:36:17 -06007728 LLVM_DEBUG(dbgs() << "[Attributor] Done with " << Functions.size()
7729 << " functions, result: " << Changed << ".\n");
7730 return Changed == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00007731}
7732
7733PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007734 FunctionAnalysisManager &FAM =
7735 AM.getResult<FunctionAnalysisManagerModuleProxy>(M).getManager();
7736 AnalysisGetter AG(FAM);
7737
7738 SetVector<Function *> Functions;
7739 for (Function &F : M)
7740 Functions.insert(&F);
7741
7742 CallGraphUpdater CGUpdater;
7743 InformationCache InfoCache(M, AG, /* CGSCC */ nullptr);
7744 if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
7745 // FIXME: Think about passes we will preserve and add them here.
7746 return PreservedAnalyses::none();
7747 }
7748 return PreservedAnalyses::all();
7749}
7750
7751PreservedAnalyses AttributorCGSCCPass::run(LazyCallGraph::SCC &C,
7752 CGSCCAnalysisManager &AM,
7753 LazyCallGraph &CG,
7754 CGSCCUpdateResult &UR) {
7755 FunctionAnalysisManager &FAM =
7756 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
7757 AnalysisGetter AG(FAM);
7758
7759 SetVector<Function *> Functions;
7760 for (LazyCallGraph::Node &N : C)
7761 Functions.insert(&N.getFunction());
7762
7763 if (Functions.empty())
7764 return PreservedAnalyses::all();
7765
7766 Module &M = *Functions.back()->getParent();
7767 CallGraphUpdater CGUpdater;
7768 CGUpdater.initialize(CG, C, AM, UR);
7769 InformationCache InfoCache(M, AG, /* CGSCC */ &Functions);
7770 if (runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater)) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00007771 // FIXME: Think about passes we will preserve and add them here.
7772 return PreservedAnalyses::none();
7773 }
7774 return PreservedAnalyses::all();
7775}
7776
7777namespace {
7778
7779struct AttributorLegacyPass : public ModulePass {
7780 static char ID;
7781
7782 AttributorLegacyPass() : ModulePass(ID) {
7783 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
7784 }
7785
7786 bool runOnModule(Module &M) override {
7787 if (skipModule(M))
7788 return false;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007789
Hideto Ueno3bb5cbc2019-09-17 05:45:18 +00007790 AnalysisGetter AG;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007791 SetVector<Function *> Functions;
7792 for (Function &F : M)
7793 Functions.insert(&F);
7794
7795 CallGraphUpdater CGUpdater;
7796 InformationCache InfoCache(M, AG, /* CGSCC */ nullptr);
7797 return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater);
Johannes Doerfertaade7822019-06-05 03:02:24 +00007798 }
7799
7800 void getAnalysisUsage(AnalysisUsage &AU) const override {
7801 // FIXME: Think about passes we will preserve and add them here.
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007802 AU.addRequired<TargetLibraryInfoWrapperPass>();
Johannes Doerfertaade7822019-06-05 03:02:24 +00007803 }
7804};
7805
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007806struct AttributorCGSCCLegacyPass : public CallGraphSCCPass {
7807 CallGraphUpdater CGUpdater;
7808 static char ID;
7809
7810 AttributorCGSCCLegacyPass() : CallGraphSCCPass(ID) {
7811 initializeAttributorCGSCCLegacyPassPass(*PassRegistry::getPassRegistry());
7812 }
7813
7814 bool runOnSCC(CallGraphSCC &SCC) override {
7815 if (skipSCC(SCC))
7816 return false;
7817
7818 SetVector<Function *> Functions;
7819 for (CallGraphNode *CGN : SCC)
7820 if (Function *Fn = CGN->getFunction())
7821 if (!Fn->isDeclaration())
7822 Functions.insert(Fn);
7823
7824 if (Functions.empty())
7825 return false;
7826
7827 AnalysisGetter AG;
7828 CallGraph &CG = const_cast<CallGraph &>(SCC.getCallGraph());
7829 CGUpdater.initialize(CG, SCC);
7830 Module &M = *Functions.back()->getParent();
7831 InformationCache InfoCache(M, AG, /* CGSCC */ &Functions);
7832 return runAttributorOnFunctions(InfoCache, Functions, AG, CGUpdater);
7833 }
7834
7835 bool doFinalization(CallGraph &CG) override { return CGUpdater.finalize(); }
7836
7837 void getAnalysisUsage(AnalysisUsage &AU) const override {
7838 // FIXME: Think about passes we will preserve and add them here.
7839 AU.addRequired<TargetLibraryInfoWrapperPass>();
7840 CallGraphSCCPass::getAnalysisUsage(AU);
7841 }
7842};
7843
Johannes Doerfertaade7822019-06-05 03:02:24 +00007844} // end anonymous namespace
7845
7846Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007847Pass *llvm::createAttributorCGSCCLegacyPass() {
7848 return new AttributorCGSCCLegacyPass();
7849}
Johannes Doerfertaade7822019-06-05 03:02:24 +00007850
7851char AttributorLegacyPass::ID = 0;
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06007852char AttributorCGSCCLegacyPass::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007853
7854const char AAReturnedValues::ID = 0;
7855const char AANoUnwind::ID = 0;
7856const char AANoSync::ID = 0;
Johannes Doerferteccdf082019-08-05 23:35:12 +00007857const char AANoFree::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007858const char AANonNull::ID = 0;
7859const char AANoRecurse::ID = 0;
7860const char AAWillReturn::ID = 0;
Johannes Doerfert58f324a2019-12-24 18:48:50 -06007861const char AAUndefinedBehavior::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007862const char AANoAlias::ID = 0;
Pankaj Gode04945c92019-11-22 18:40:47 +05307863const char AAReachability::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007864const char AANoReturn::ID = 0;
7865const char AAIsDead::ID = 0;
7866const char AADereferenceable::ID = 0;
7867const char AAAlign::ID = 0;
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00007868const char AANoCapture::ID = 0;
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007869const char AAValueSimplify::ID = 0;
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007870const char AAHeapToStack::ID = 0;
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007871const char AAPrivatizablePtr::ID = 0;
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007872const char AAMemoryBehavior::ID = 0;
Hideto Ueno188f9a32020-01-15 15:25:52 +09007873const char AAValueConstantRange::ID = 0;
Johannes Doerfert24020622019-08-05 23:30:01 +00007874
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007875// Macro magic to create the static generator function for attributes that
7876// follow the naming scheme.
7877
7878#define SWITCH_PK_INV(CLASS, PK, POS_NAME) \
7879 case IRPosition::PK: \
7880 llvm_unreachable("Cannot create " #CLASS " for a " POS_NAME " position!");
7881
7882#define SWITCH_PK_CREATE(CLASS, IRP, PK, SUFFIX) \
7883 case IRPosition::PK: \
7884 AA = new CLASS##SUFFIX(IRP); \
7885 break;
7886
7887#define CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7888 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7889 CLASS *AA = nullptr; \
7890 switch (IRP.getPositionKind()) { \
7891 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7892 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
7893 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
7894 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
7895 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
7896 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
7897 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
7898 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
7899 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007900 return *AA; \
7901 }
7902
7903#define CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7904 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7905 CLASS *AA = nullptr; \
7906 switch (IRP.getPositionKind()) { \
7907 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7908 SWITCH_PK_INV(CLASS, IRP_FUNCTION, "function") \
7909 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
7910 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
7911 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
7912 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
7913 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
7914 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
7915 } \
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007916 return *AA; \
7917 }
7918
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007919#define CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7920 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7921 CLASS *AA = nullptr; \
7922 switch (IRP.getPositionKind()) { \
7923 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7924 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
7925 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
7926 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
7927 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
7928 SWITCH_PK_CREATE(CLASS, IRP, IRP_RETURNED, Returned) \
7929 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
7930 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
7931 } \
7932 return *AA; \
7933 }
7934
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007935#define CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7936 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7937 CLASS *AA = nullptr; \
7938 switch (IRP.getPositionKind()) { \
7939 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7940 SWITCH_PK_INV(CLASS, IRP_ARGUMENT, "argument") \
7941 SWITCH_PK_INV(CLASS, IRP_FLOAT, "floating") \
7942 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
7943 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_RETURNED, "call site returned") \
7944 SWITCH_PK_INV(CLASS, IRP_CALL_SITE_ARGUMENT, "call site argument") \
7945 SWITCH_PK_INV(CLASS, IRP_CALL_SITE, "call site") \
7946 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
7947 } \
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007948 return *AA; \
7949 }
7950
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007951#define CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(CLASS) \
7952 CLASS &CLASS::createForPosition(const IRPosition &IRP, Attributor &A) { \
7953 CLASS *AA = nullptr; \
7954 switch (IRP.getPositionKind()) { \
7955 SWITCH_PK_INV(CLASS, IRP_INVALID, "invalid") \
7956 SWITCH_PK_INV(CLASS, IRP_RETURNED, "returned") \
7957 SWITCH_PK_CREATE(CLASS, IRP, IRP_FUNCTION, Function) \
7958 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE, CallSite) \
7959 SWITCH_PK_CREATE(CLASS, IRP, IRP_FLOAT, Floating) \
7960 SWITCH_PK_CREATE(CLASS, IRP, IRP_ARGUMENT, Argument) \
7961 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_RETURNED, CallSiteReturned) \
7962 SWITCH_PK_CREATE(CLASS, IRP, IRP_CALL_SITE_ARGUMENT, CallSiteArgument) \
7963 } \
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007964 return *AA; \
7965 }
7966
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007967CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoUnwind)
7968CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoSync)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007969CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoRecurse)
7970CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAWillReturn)
7971CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoReturn)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007972CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReturnedValues)
7973
7974CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANonNull)
7975CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoAlias)
Johannes Doerfert89c2e732019-10-30 17:20:20 -05007976CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAPrivatizablePtr)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007977CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AADereferenceable)
7978CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAAlign)
Johannes Doerfert7516a5e2019-09-03 20:37:24 +00007979CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoCapture)
Hideto Ueno188f9a32020-01-15 15:25:52 +09007980CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueConstantRange)
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007981
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007982CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAValueSimplify)
Johannes Doerfertcd4aab42019-10-13 03:08:18 -05007983CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAIsDead)
Stefan Stipanovicf35740d2019-11-02 16:35:38 +01007984CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION(AANoFree)
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007985
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007986CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAHeapToStack)
Pankaj Gode04945c92019-11-22 18:40:47 +05307987CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAReachability)
Johannes Doerfert58f324a2019-12-24 18:48:50 -06007988CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAUndefinedBehavior)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00007989
Johannes Doerfert1097fab2019-10-07 21:07:57 +00007990CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION(AAMemoryBehavior)
7991
Johannes Doerfertd4bea882019-10-07 23:28:54 +00007992#undef CREATE_FUNCTION_ONLY_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007993#undef CREATE_FUNCTION_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfertd4bea882019-10-07 23:28:54 +00007994#undef CREATE_NON_RET_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007995#undef CREATE_VALUE_ABSTRACT_ATTRIBUTE_FOR_POSITION
Hideto Uenof2b9dc42019-09-07 07:03:05 +00007996#undef CREATE_ALL_ABSTRACT_ATTRIBUTE_FOR_POSITION
Johannes Doerfert12cbbab2019-08-20 06:15:50 +00007997#undef SWITCH_PK_CREATE
7998#undef SWITCH_PK_INV
7999
Johannes Doerfertaade7822019-06-05 03:02:24 +00008000INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
8001 "Deduce and propagate attributes", false, false)
Stefan Stipanovic431141c2019-09-15 21:47:41 +00008002INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
Johannes Doerfertaade7822019-06-05 03:02:24 +00008003INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
8004 "Deduce and propagate attributes", false, false)
Johannes Doerfertb0c77c32019-11-27 00:30:12 -06008005INITIALIZE_PASS_BEGIN(AttributorCGSCCLegacyPass, "attributor-cgscc",
8006 "Deduce and propagate attributes (CGSCC pass)", false,
8007 false)
8008INITIALIZE_PASS_DEPENDENCY(TargetLibraryInfoWrapperPass)
8009INITIALIZE_PASS_DEPENDENCY(CallGraphWrapperPass)
8010INITIALIZE_PASS_END(AttributorCGSCCLegacyPass, "attributor-cgscc",
8011 "Deduce and propagate attributes (CGSCC pass)", false,
8012 false)