blob: e55751b5e5b5eef2b73ebf2bc3af54d1e9828408 [file] [log] [blame]
Johannes Doerfertaade7822019-06-05 03:02:24 +00001//===- Attributor.cpp - Module-wide attribute deduction -------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file implements an inter procedural pass that deduces and/or propagating
10// attributes. This is done in an abstract interpretation style fixpoint
11// iteration. See the Attributor.h file comment and the class descriptions in
12// that file for more information.
13//
14//===----------------------------------------------------------------------===//
15
16#include "llvm/Transforms/IPO/Attributor.h"
17
Hideto Ueno11d37102019-07-17 15:15:43 +000018#include "llvm/ADT/DepthFirstIterator.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000019#include "llvm/ADT/STLExtras.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000020#include "llvm/ADT/SetVector.h"
21#include "llvm/ADT/SmallPtrSet.h"
22#include "llvm/ADT/SmallVector.h"
23#include "llvm/ADT/Statistic.h"
Stefan Stipanovic69ebb022019-07-22 19:36:27 +000024#include "llvm/Analysis/CaptureTracking.h"
Johannes Doerfert924d2132019-08-05 21:34:45 +000025#include "llvm/Analysis/EHPersonalities.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000026#include "llvm/Analysis/GlobalsModRef.h"
Hideto Ueno19c07af2019-07-23 08:16:17 +000027#include "llvm/Analysis/Loads.h"
Hideto Ueno54869ec2019-07-15 06:49:04 +000028#include "llvm/Analysis/ValueTracking.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000029#include "llvm/IR/Argument.h"
30#include "llvm/IR/Attributes.h"
Hideto Ueno11d37102019-07-17 15:15:43 +000031#include "llvm/IR/CFG.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000032#include "llvm/IR/InstIterator.h"
Stefan Stipanovic06263672019-07-11 21:37:40 +000033#include "llvm/IR/IntrinsicInst.h"
Johannes Doerfertaade7822019-06-05 03:02:24 +000034#include "llvm/Support/CommandLine.h"
35#include "llvm/Support/Debug.h"
36#include "llvm/Support/raw_ostream.h"
Stefan Stipanovic6058b862019-07-22 23:58:23 +000037#include "llvm/Transforms/Utils/BasicBlockUtils.h"
38#include "llvm/Transforms/Utils/Local.h"
39
Johannes Doerfertaade7822019-06-05 03:02:24 +000040#include <cassert>
41
42using namespace llvm;
43
44#define DEBUG_TYPE "attributor"
45
46STATISTIC(NumFnWithExactDefinition,
47 "Number of function with exact definitions");
48STATISTIC(NumFnWithoutExactDefinition,
49 "Number of function without exact definitions");
50STATISTIC(NumAttributesTimedOut,
51 "Number of abstract attributes timed out before fixpoint");
52STATISTIC(NumAttributesValidFixpoint,
53 "Number of abstract attributes in a valid fixpoint state");
54STATISTIC(NumAttributesManifested,
55 "Number of abstract attributes manifested in IR");
Stefan Stipanovic53605892019-06-27 11:27:54 +000056STATISTIC(NumFnNoUnwind, "Number of functions marked nounwind");
Johannes Doerfertaade7822019-06-05 03:02:24 +000057
Johannes Doerfertaccd3e82019-07-08 23:27:20 +000058STATISTIC(NumFnUniqueReturned, "Number of function with unique return");
59STATISTIC(NumFnKnownReturns, "Number of function with known return values");
60STATISTIC(NumFnArgumentReturned,
61 "Number of function arguments marked returned");
Stefan Stipanovic06263672019-07-11 21:37:40 +000062STATISTIC(NumFnNoSync, "Number of functions marked nosync");
Hideto Ueno65bbaf92019-07-12 17:38:51 +000063STATISTIC(NumFnNoFree, "Number of functions marked nofree");
Hideto Ueno54869ec2019-07-15 06:49:04 +000064STATISTIC(NumFnReturnedNonNull,
65 "Number of function return values marked nonnull");
66STATISTIC(NumFnArgumentNonNull, "Number of function arguments marked nonnull");
67STATISTIC(NumCSArgumentNonNull, "Number of call site arguments marked nonnull");
Hideto Ueno11d37102019-07-17 15:15:43 +000068STATISTIC(NumFnWillReturn, "Number of functions marked willreturn");
Stefan Stipanovic69ebb022019-07-22 19:36:27 +000069STATISTIC(NumFnArgumentNoAlias, "Number of function arguments marked noalias");
Hideto Ueno19c07af2019-07-23 08:16:17 +000070STATISTIC(NumFnReturnedDereferenceable,
71 "Number of function return values marked dereferenceable");
72STATISTIC(NumFnArgumentDereferenceable,
73 "Number of function arguments marked dereferenceable");
74STATISTIC(NumCSArgumentDereferenceable,
75 "Number of call site arguments marked dereferenceable");
Hideto Uenoe7bea9b2019-07-28 07:04:01 +000076STATISTIC(NumFnReturnedAlign, "Number of function return values marked align");
77STATISTIC(NumFnArgumentAlign, "Number of function arguments marked align");
78STATISTIC(NumCSArgumentAlign, "Number of call site arguments marked align");
Johannes Doerferte83f3032019-08-05 23:22:05 +000079STATISTIC(NumFnNoReturn, "Number of functions marked noreturn");
Johannes Doerfertaccd3e82019-07-08 23:27:20 +000080
Johannes Doerfertaade7822019-06-05 03:02:24 +000081// TODO: Determine a good default value.
82//
83// In the LLVM-TS and SPEC2006, 32 seems to not induce compile time overheads
84// (when run with the first 5 abstract attributes). The results also indicate
85// that we never reach 32 iterations but always find a fixpoint sooner.
86//
87// This will become more evolved once we perform two interleaved fixpoint
88// iterations: bottom-up and top-down.
89static cl::opt<unsigned>
90 MaxFixpointIterations("attributor-max-iterations", cl::Hidden,
91 cl::desc("Maximal number of fixpoint iterations."),
92 cl::init(32));
93
94static cl::opt<bool> DisableAttributor(
95 "attributor-disable", cl::Hidden,
96 cl::desc("Disable the attributor inter-procedural deduction pass."),
Johannes Doerfert282d34e2019-06-14 14:53:41 +000097 cl::init(true));
Johannes Doerfertaade7822019-06-05 03:02:24 +000098
99static cl::opt<bool> VerifyAttributor(
100 "attributor-verify", cl::Hidden,
101 cl::desc("Verify the Attributor deduction and "
102 "manifestation of attributes -- may issue false-positive errors"),
103 cl::init(false));
104
105/// Logic operators for the change status enum class.
106///
107///{
108ChangeStatus llvm::operator|(ChangeStatus l, ChangeStatus r) {
109 return l == ChangeStatus::CHANGED ? l : r;
110}
111ChangeStatus llvm::operator&(ChangeStatus l, ChangeStatus r) {
112 return l == ChangeStatus::UNCHANGED ? l : r;
113}
114///}
115
116/// Helper to adjust the statistics.
117static void bookkeeping(AbstractAttribute::ManifestPosition MP,
118 const Attribute &Attr) {
119 if (!AreStatisticsEnabled())
120 return;
121
Stefan Stipanovic53605892019-06-27 11:27:54 +0000122 switch (Attr.getKindAsEnum()) {
Hideto Uenoe7bea9b2019-07-28 07:04:01 +0000123 case Attribute::Alignment:
124 switch (MP) {
125 case AbstractAttribute::MP_RETURNED:
126 NumFnReturnedAlign++;
127 break;
128 case AbstractAttribute::MP_ARGUMENT:
129 NumFnArgumentAlign++;
130 break;
131 case AbstractAttribute::MP_CALL_SITE_ARGUMENT:
132 NumCSArgumentAlign++;
133 break;
134 default:
135 break;
136 }
137 break;
Hideto Ueno19c07af2019-07-23 08:16:17 +0000138 case Attribute::Dereferenceable:
139 switch (MP) {
140 case AbstractAttribute::MP_RETURNED:
141 NumFnReturnedDereferenceable++;
142 break;
143 case AbstractAttribute::MP_ARGUMENT:
144 NumFnArgumentDereferenceable++;
145 break;
146 case AbstractAttribute::MP_CALL_SITE_ARGUMENT:
147 NumCSArgumentDereferenceable++;
148 break;
149 default:
150 break;
151 }
152 break;
Stefan Stipanovic53605892019-06-27 11:27:54 +0000153 case Attribute::NoUnwind:
154 NumFnNoUnwind++;
155 return;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000156 case Attribute::Returned:
157 NumFnArgumentReturned++;
158 return;
Stefan Stipanovic06263672019-07-11 21:37:40 +0000159 case Attribute::NoSync:
160 NumFnNoSync++;
161 break;
Hideto Ueno65bbaf92019-07-12 17:38:51 +0000162 case Attribute::NoFree:
163 NumFnNoFree++;
164 break;
Hideto Ueno54869ec2019-07-15 06:49:04 +0000165 case Attribute::NonNull:
166 switch (MP) {
167 case AbstractAttribute::MP_RETURNED:
168 NumFnReturnedNonNull++;
169 break;
170 case AbstractAttribute::MP_ARGUMENT:
171 NumFnArgumentNonNull++;
172 break;
173 case AbstractAttribute::MP_CALL_SITE_ARGUMENT:
174 NumCSArgumentNonNull++;
175 break;
176 default:
177 break;
178 }
179 break;
Hideto Ueno11d37102019-07-17 15:15:43 +0000180 case Attribute::WillReturn:
181 NumFnWillReturn++;
182 break;
Johannes Doerferte83f3032019-08-05 23:22:05 +0000183 case Attribute::NoReturn:
184 NumFnNoReturn++;
185 return;
Stefan Stipanovic69ebb022019-07-22 19:36:27 +0000186 case Attribute::NoAlias:
187 NumFnArgumentNoAlias++;
188 return;
Stefan Stipanovic53605892019-06-27 11:27:54 +0000189 default:
190 return;
191 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000192}
193
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000194template <typename StateTy>
195using followValueCB_t = std::function<bool(Value *, StateTy &State)>;
196template <typename StateTy>
197using visitValueCB_t = std::function<void(Value *, StateTy &State)>;
198
199/// Recursively visit all values that might become \p InitV at some point. This
200/// will be done by looking through cast instructions, selects, phis, and calls
201/// with the "returned" attribute. The callback \p FollowValueCB is asked before
202/// a potential origin value is looked at. If no \p FollowValueCB is passed, a
203/// default one is used that will make sure we visit every value only once. Once
204/// we cannot look through the value any further, the callback \p VisitValueCB
205/// is invoked and passed the current value and the \p State. To limit how much
206/// effort is invested, we will never visit more than \p MaxValues values.
207template <typename StateTy>
208static bool genericValueTraversal(
209 Value *InitV, StateTy &State, visitValueCB_t<StateTy> &VisitValueCB,
210 followValueCB_t<StateTy> *FollowValueCB = nullptr, int MaxValues = 8) {
211
212 SmallPtrSet<Value *, 16> Visited;
213 followValueCB_t<bool> DefaultFollowValueCB = [&](Value *Val, bool &) {
214 return Visited.insert(Val).second;
215 };
216
217 if (!FollowValueCB)
218 FollowValueCB = &DefaultFollowValueCB;
219
220 SmallVector<Value *, 16> Worklist;
221 Worklist.push_back(InitV);
222
223 int Iteration = 0;
224 do {
225 Value *V = Worklist.pop_back_val();
226
227 // Check if we should process the current value. To prevent endless
228 // recursion keep a record of the values we followed!
229 if (!(*FollowValueCB)(V, State))
230 continue;
231
232 // Make sure we limit the compile time for complex expressions.
233 if (Iteration++ >= MaxValues)
234 return false;
235
236 // Explicitly look through calls with a "returned" attribute if we do
237 // not have a pointer as stripPointerCasts only works on them.
238 if (V->getType()->isPointerTy()) {
239 V = V->stripPointerCasts();
240 } else {
241 CallSite CS(V);
242 if (CS && CS.getCalledFunction()) {
243 Value *NewV = nullptr;
244 for (Argument &Arg : CS.getCalledFunction()->args())
245 if (Arg.hasReturnedAttr()) {
246 NewV = CS.getArgOperand(Arg.getArgNo());
247 break;
248 }
249 if (NewV) {
250 Worklist.push_back(NewV);
251 continue;
252 }
253 }
254 }
255
256 // Look through select instructions, visit both potential values.
257 if (auto *SI = dyn_cast<SelectInst>(V)) {
258 Worklist.push_back(SI->getTrueValue());
259 Worklist.push_back(SI->getFalseValue());
260 continue;
261 }
262
263 // Look through phi nodes, visit all operands.
264 if (auto *PHI = dyn_cast<PHINode>(V)) {
265 Worklist.append(PHI->op_begin(), PHI->op_end());
266 continue;
267 }
268
269 // Once a leaf is reached we inform the user through the callback.
270 VisitValueCB(V, State);
271 } while (!Worklist.empty());
272
273 // All values have been visited.
274 return true;
275}
276
Johannes Doerfertaade7822019-06-05 03:02:24 +0000277/// Helper to identify the correct offset into an attribute list.
278static unsigned getAttrIndex(AbstractAttribute::ManifestPosition MP,
279 unsigned ArgNo = 0) {
280 switch (MP) {
281 case AbstractAttribute::MP_ARGUMENT:
282 case AbstractAttribute::MP_CALL_SITE_ARGUMENT:
283 return ArgNo + AttributeList::FirstArgIndex;
284 case AbstractAttribute::MP_FUNCTION:
285 return AttributeList::FunctionIndex;
286 case AbstractAttribute::MP_RETURNED:
287 return AttributeList::ReturnIndex;
288 }
Michael Liaofa449a92019-06-05 04:18:12 +0000289 llvm_unreachable("Unknown manifest position!");
Johannes Doerfertaade7822019-06-05 03:02:24 +0000290}
291
292/// Return true if \p New is equal or worse than \p Old.
293static bool isEqualOrWorse(const Attribute &New, const Attribute &Old) {
294 if (!Old.isIntAttribute())
295 return true;
296
297 return Old.getValueAsInt() >= New.getValueAsInt();
298}
299
300/// Return true if the information provided by \p Attr was added to the
301/// attribute list \p Attrs. This is only the case if it was not already present
302/// in \p Attrs at the position describe by \p MP and \p ArgNo.
303static bool addIfNotExistent(LLVMContext &Ctx, const Attribute &Attr,
304 AttributeList &Attrs,
305 AbstractAttribute::ManifestPosition MP,
306 unsigned ArgNo = 0) {
307 unsigned AttrIdx = getAttrIndex(MP, ArgNo);
308
309 if (Attr.isEnumAttribute()) {
310 Attribute::AttrKind Kind = Attr.getKindAsEnum();
311 if (Attrs.hasAttribute(AttrIdx, Kind))
312 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
313 return false;
314 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
315 return true;
316 }
317 if (Attr.isStringAttribute()) {
318 StringRef Kind = Attr.getKindAsString();
319 if (Attrs.hasAttribute(AttrIdx, Kind))
320 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
321 return false;
322 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
323 return true;
324 }
Hideto Ueno19c07af2019-07-23 08:16:17 +0000325 if (Attr.isIntAttribute()) {
326 Attribute::AttrKind Kind = Attr.getKindAsEnum();
327 if (Attrs.hasAttribute(AttrIdx, Kind))
328 if (isEqualOrWorse(Attr, Attrs.getAttribute(AttrIdx, Kind)))
329 return false;
330 Attrs = Attrs.removeAttribute(Ctx, AttrIdx, Kind);
331 Attrs = Attrs.addAttribute(Ctx, AttrIdx, Attr);
332 return true;
333 }
Johannes Doerfertaade7822019-06-05 03:02:24 +0000334
335 llvm_unreachable("Expected enum or string attribute!");
336}
337
Johannes Doerfert007153e2019-08-05 23:26:06 +0000338ChangeStatus AbstractAttribute::update(Attributor &A,
339 InformationCache &InfoCache) {
Johannes Doerfertaade7822019-06-05 03:02:24 +0000340 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
341 if (getState().isAtFixpoint())
342 return HasChanged;
343
344 LLVM_DEBUG(dbgs() << "[Attributor] Update: " << *this << "\n");
345
Johannes Doerfert007153e2019-08-05 23:26:06 +0000346 HasChanged = updateImpl(A, InfoCache);
Johannes Doerfertaade7822019-06-05 03:02:24 +0000347
348 LLVM_DEBUG(dbgs() << "[Attributor] Update " << HasChanged << " " << *this
349 << "\n");
350
351 return HasChanged;
352}
353
354ChangeStatus AbstractAttribute::manifest(Attributor &A) {
355 assert(getState().isValidState() &&
356 "Attempted to manifest an invalid state!");
357 assert(getAssociatedValue() &&
358 "Attempted to manifest an attribute without associated value!");
359
360 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
361 SmallVector<Attribute, 4> DeducedAttrs;
362 getDeducedAttributes(DeducedAttrs);
363
364 Function &ScopeFn = getAnchorScope();
365 LLVMContext &Ctx = ScopeFn.getContext();
366 ManifestPosition MP = getManifestPosition();
367
368 AttributeList Attrs;
369 SmallVector<unsigned, 4> ArgNos;
370
371 // In the following some generic code that will manifest attributes in
372 // DeducedAttrs if they improve the current IR. Due to the different
373 // annotation positions we use the underlying AttributeList interface.
374 // Note that MP_CALL_SITE_ARGUMENT can annotate multiple locations.
375
376 switch (MP) {
377 case MP_ARGUMENT:
378 ArgNos.push_back(cast<Argument>(getAssociatedValue())->getArgNo());
379 Attrs = ScopeFn.getAttributes();
380 break;
381 case MP_FUNCTION:
382 case MP_RETURNED:
383 ArgNos.push_back(0);
384 Attrs = ScopeFn.getAttributes();
385 break;
386 case MP_CALL_SITE_ARGUMENT: {
387 CallSite CS(&getAnchoredValue());
388 for (unsigned u = 0, e = CS.getNumArgOperands(); u != e; u++)
389 if (CS.getArgOperand(u) == getAssociatedValue())
390 ArgNos.push_back(u);
391 Attrs = CS.getAttributes();
392 }
393 }
394
395 for (const Attribute &Attr : DeducedAttrs) {
396 for (unsigned ArgNo : ArgNos) {
397 if (!addIfNotExistent(Ctx, Attr, Attrs, MP, ArgNo))
398 continue;
399
400 HasChanged = ChangeStatus::CHANGED;
401 bookkeeping(MP, Attr);
402 }
403 }
404
405 if (HasChanged == ChangeStatus::UNCHANGED)
406 return HasChanged;
407
408 switch (MP) {
409 case MP_ARGUMENT:
410 case MP_FUNCTION:
411 case MP_RETURNED:
412 ScopeFn.setAttributes(Attrs);
413 break;
414 case MP_CALL_SITE_ARGUMENT:
415 CallSite(&getAnchoredValue()).setAttributes(Attrs);
416 }
417
418 return HasChanged;
419}
420
421Function &AbstractAttribute::getAnchorScope() {
422 Value &V = getAnchoredValue();
423 if (isa<Function>(V))
424 return cast<Function>(V);
425 if (isa<Argument>(V))
426 return *cast<Argument>(V).getParent();
427 if (isa<Instruction>(V))
428 return *cast<Instruction>(V).getFunction();
429 llvm_unreachable("No scope for anchored value found!");
430}
431
432const Function &AbstractAttribute::getAnchorScope() const {
433 return const_cast<AbstractAttribute *>(this)->getAnchorScope();
434}
435
Hideto Ueno19c07af2019-07-23 08:16:17 +0000436// Helper function that returns argument index of value.
437// If the value is not an argument, this returns -1.
438static int getArgNo(Value &V) {
439 if (auto *Arg = dyn_cast<Argument>(&V))
440 return Arg->getArgNo();
441 return -1;
442}
443
Stefan Stipanovic53605892019-06-27 11:27:54 +0000444/// -----------------------NoUnwind Function Attribute--------------------------
445
446struct AANoUnwindFunction : AANoUnwind, BooleanState {
447
Johannes Doerfert007153e2019-08-05 23:26:06 +0000448 AANoUnwindFunction(Function &F) : AANoUnwind(F) {}
Stefan Stipanovic53605892019-06-27 11:27:54 +0000449
450 /// See AbstractAttribute::getState()
451 /// {
452 AbstractState &getState() override { return *this; }
453 const AbstractState &getState() const override { return *this; }
454 /// }
455
456 /// See AbstractAttribute::getManifestPosition().
Johannes Doerfertc7a1db32019-07-13 01:09:27 +0000457 ManifestPosition getManifestPosition() const override { return MP_FUNCTION; }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000458
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000459 const std::string getAsStr() const override {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000460 return getAssumed() ? "nounwind" : "may-unwind";
461 }
462
463 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +0000464 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Stefan Stipanovic53605892019-06-27 11:27:54 +0000465
466 /// See AANoUnwind::isAssumedNoUnwind().
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000467 bool isAssumedNoUnwind() const override { return getAssumed(); }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000468
469 /// See AANoUnwind::isKnownNoUnwind().
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000470 bool isKnownNoUnwind() const override { return getKnown(); }
Stefan Stipanovic53605892019-06-27 11:27:54 +0000471};
472
Johannes Doerfert007153e2019-08-05 23:26:06 +0000473ChangeStatus AANoUnwindFunction::updateImpl(Attributor &A,
474 InformationCache &InfoCache) {
Stefan Stipanovic53605892019-06-27 11:27:54 +0000475 Function &F = getAnchorScope();
476
477 // The map from instruction opcodes to those instructions in the function.
478 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
479 auto Opcodes = {
480 (unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
481 (unsigned)Instruction::Call, (unsigned)Instruction::CleanupRet,
482 (unsigned)Instruction::CatchSwitch, (unsigned)Instruction::Resume};
483
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000484 auto *LivenessAA = A.getAAFor<AAIsDead>(*this, F);
485
Stefan Stipanovic53605892019-06-27 11:27:54 +0000486 for (unsigned Opcode : Opcodes) {
487 for (Instruction *I : OpcodeInstMap[Opcode]) {
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000488 // Skip dead instructions.
489 if (LivenessAA && LivenessAA->isAssumedDead(I))
490 continue;
491
Stefan Stipanovic53605892019-06-27 11:27:54 +0000492 if (!I->mayThrow())
493 continue;
494
495 auto *NoUnwindAA = A.getAAFor<AANoUnwind>(*this, *I);
496
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000497 if (!NoUnwindAA || !NoUnwindAA->isAssumedNoUnwind())
498 return indicatePessimisticFixpoint();
Stefan Stipanovic53605892019-06-27 11:27:54 +0000499 }
500 }
501 return ChangeStatus::UNCHANGED;
502}
503
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000504/// --------------------- Function Return Values -------------------------------
505
506/// "Attribute" that collects all potential returned values and the return
507/// instructions that they arise from.
508///
509/// If there is a unique returned value R, the manifest method will:
510/// - mark R with the "returned" attribute, if R is an argument.
511class AAReturnedValuesImpl final : public AAReturnedValues, AbstractState {
512
513 /// Mapping of values potentially returned by the associated function to the
514 /// return instructions that might return them.
515 DenseMap<Value *, SmallPtrSet<ReturnInst *, 2>> ReturnedValues;
516
517 /// State flags
518 ///
519 ///{
520 bool IsFixed;
521 bool IsValidState;
522 bool HasOverdefinedReturnedCalls;
523 ///}
524
525 /// Collect values that could become \p V in the set \p Values, each mapped to
526 /// \p ReturnInsts.
527 void collectValuesRecursively(
528 Attributor &A, Value *V, SmallPtrSetImpl<ReturnInst *> &ReturnInsts,
529 DenseMap<Value *, SmallPtrSet<ReturnInst *, 2>> &Values) {
530
531 visitValueCB_t<bool> VisitValueCB = [&](Value *Val, bool &) {
532 assert(!isa<Instruction>(Val) ||
533 &getAnchorScope() == cast<Instruction>(Val)->getFunction());
534 Values[Val].insert(ReturnInsts.begin(), ReturnInsts.end());
535 };
536
537 bool UnusedBool;
538 bool Success = genericValueTraversal(V, UnusedBool, VisitValueCB);
539
540 // If we did abort the above traversal we haven't see all the values.
541 // Consequently, we cannot know if the information we would derive is
542 // accurate so we give up early.
543 if (!Success)
544 indicatePessimisticFixpoint();
545 }
546
547public:
548 /// See AbstractAttribute::AbstractAttribute(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +0000549 AAReturnedValuesImpl(Function &F) : AAReturnedValues(F) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000550 // We do not have an associated argument yet.
551 AssociatedVal = nullptr;
552 }
553
554 /// See AbstractAttribute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +0000555 void initialize(Attributor &A, InformationCache &InfoCache) override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000556 // Reset the state.
557 AssociatedVal = nullptr;
558 IsFixed = false;
559 IsValidState = true;
560 HasOverdefinedReturnedCalls = false;
561 ReturnedValues.clear();
562
563 Function &F = cast<Function>(getAnchoredValue());
564
565 // The map from instruction opcodes to those instructions in the function.
566 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
567
568 // Look through all arguments, if one is marked as returned we are done.
569 for (Argument &Arg : F.args()) {
570 if (Arg.hasReturnedAttr()) {
571
572 auto &ReturnInstSet = ReturnedValues[&Arg];
573 for (Instruction *RI : OpcodeInstMap[Instruction::Ret])
574 ReturnInstSet.insert(cast<ReturnInst>(RI));
575
576 indicateOptimisticFixpoint();
577 return;
578 }
579 }
580
581 // If no argument was marked as returned we look at all return instructions
582 // and collect potentially returned values.
583 for (Instruction *RI : OpcodeInstMap[Instruction::Ret]) {
584 SmallPtrSet<ReturnInst *, 1> RISet({cast<ReturnInst>(RI)});
585 collectValuesRecursively(A, cast<ReturnInst>(RI)->getReturnValue(), RISet,
586 ReturnedValues);
587 }
588 }
589
590 /// See AbstractAttribute::manifest(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000591 ChangeStatus manifest(Attributor &A) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000592
593 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000594 AbstractState &getState() override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000595
596 /// See AbstractAttribute::getState(...).
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000597 const AbstractState &getState() const override { return *this; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000598
599 /// See AbstractAttribute::getManifestPosition().
Johannes Doerfertc7a1db32019-07-13 01:09:27 +0000600 ManifestPosition getManifestPosition() const override { return MP_ARGUMENT; }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000601
602 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfert007153e2019-08-05 23:26:06 +0000603 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000604
605 /// Return the number of potential return values, -1 if unknown.
606 size_t getNumReturnValues() const {
607 return isValidState() ? ReturnedValues.size() : -1;
608 }
609
610 /// Return an assumed unique return value if a single candidate is found. If
611 /// there cannot be one, return a nullptr. If it is not clear yet, return the
612 /// Optional::NoneType.
Stefan Stipanovic7849e412019-08-03 15:27:41 +0000613 Optional<Value *>
614 getAssumedUniqueReturnValue(const AAIsDead *LivenessAA) const;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000615
616 /// See AbstractState::checkForallReturnedValues(...).
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000617 bool checkForallReturnedValues(
618 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> &Pred)
619 const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000620
621 /// Pretty print the attribute similar to the IR representation.
Stefan Stipanovic15e86f72019-07-12 17:42:14 +0000622 const std::string getAsStr() const override;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000623
624 /// See AbstractState::isAtFixpoint().
625 bool isAtFixpoint() const override { return IsFixed; }
626
627 /// See AbstractState::isValidState().
628 bool isValidState() const override { return IsValidState; }
629
630 /// See AbstractState::indicateOptimisticFixpoint(...).
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000631 ChangeStatus indicateOptimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000632 IsFixed = true;
633 IsValidState &= true;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000634 return ChangeStatus::UNCHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000635 }
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000636
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000637 ChangeStatus indicatePessimisticFixpoint() override {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000638 IsFixed = true;
639 IsValidState = false;
Johannes Doerfertd1c37932019-08-04 18:37:38 +0000640 return ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000641 }
642};
643
644ChangeStatus AAReturnedValuesImpl::manifest(Attributor &A) {
645 ChangeStatus Changed = ChangeStatus::UNCHANGED;
646
647 // Bookkeeping.
648 assert(isValidState());
649 NumFnKnownReturns++;
650
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000651 auto *LivenessAA = A.getAAFor<AAIsDead>(*this, getAnchorScope());
652
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000653 // Check if we have an assumed unique return value that we could manifest.
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000654 Optional<Value *> UniqueRV = getAssumedUniqueReturnValue(LivenessAA);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000655
656 if (!UniqueRV.hasValue() || !UniqueRV.getValue())
657 return Changed;
658
659 // Bookkeeping.
660 NumFnUniqueReturned++;
661
662 // If the assumed unique return value is an argument, annotate it.
663 if (auto *UniqueRVArg = dyn_cast<Argument>(UniqueRV.getValue())) {
664 AssociatedVal = UniqueRVArg;
665 Changed = AbstractAttribute::manifest(A) | Changed;
666 }
667
668 return Changed;
669}
670
671const std::string AAReturnedValuesImpl::getAsStr() const {
672 return (isAtFixpoint() ? "returns(#" : "may-return(#") +
Johannes Doerfert6471bb62019-08-04 18:39:28 +0000673 (isValidState() ? std::to_string(getNumReturnValues()) : "?") +
674 ")[OD: " + std::to_string(HasOverdefinedReturnedCalls) + "]";
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000675}
676
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000677Optional<Value *> AAReturnedValuesImpl::getAssumedUniqueReturnValue(
678 const AAIsDead *LivenessAA) const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000679 // If checkForallReturnedValues provides a unique value, ignoring potential
680 // undef values that can also be present, it is assumed to be the actual
681 // return value and forwarded to the caller of this method. If there are
682 // multiple, a nullptr is returned indicating there cannot be a unique
683 // returned value.
684 Optional<Value *> UniqueRV;
685
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000686 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
687 [&](Value &RV, const SmallPtrSetImpl<ReturnInst *> &RetInsts) -> bool {
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000688 // If all ReturnInsts are dead, then ReturnValue is dead as well
689 // and can be ignored.
690 if (LivenessAA &&
691 !LivenessAA->isLiveInstSet(RetInsts.begin(), RetInsts.end()))
692 return true;
693
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000694 // If we found a second returned value and neither the current nor the saved
695 // one is an undef, there is no unique returned value. Undefs are special
696 // since we can pretend they have any value.
697 if (UniqueRV.hasValue() && UniqueRV != &RV &&
698 !(isa<UndefValue>(RV) || isa<UndefValue>(UniqueRV.getValue()))) {
699 UniqueRV = nullptr;
700 return false;
701 }
702
703 // Do not overwrite a value with an undef.
704 if (!UniqueRV.hasValue() || !isa<UndefValue>(RV))
705 UniqueRV = &RV;
706
707 return true;
708 };
709
710 if (!checkForallReturnedValues(Pred))
711 UniqueRV = nullptr;
712
713 return UniqueRV;
714}
715
716bool AAReturnedValuesImpl::checkForallReturnedValues(
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000717 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> &Pred)
718 const {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000719 if (!isValidState())
720 return false;
721
722 // Check all returned values but ignore call sites as long as we have not
723 // encountered an overdefined one during an update.
724 for (auto &It : ReturnedValues) {
725 Value *RV = It.first;
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000726 const SmallPtrSetImpl<ReturnInst *> &RetInsts = It.second;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000727
728 ImmutableCallSite ICS(RV);
729 if (ICS && !HasOverdefinedReturnedCalls)
730 continue;
731
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000732 if (!Pred(*RV, RetInsts))
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000733 return false;
734 }
735
736 return true;
737}
738
Johannes Doerfert007153e2019-08-05 23:26:06 +0000739ChangeStatus AAReturnedValuesImpl::updateImpl(Attributor &A,
740 InformationCache &InfoCache) {
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000741
742 // Check if we know of any values returned by the associated function,
743 // if not, we are done.
744 if (getNumReturnValues() == 0) {
745 indicateOptimisticFixpoint();
746 return ChangeStatus::UNCHANGED;
747 }
748
749 // Check if any of the returned values is a call site we can refine.
750 decltype(ReturnedValues) AddRVs;
751 bool HasCallSite = false;
752
Johannes Doerfertda4d8112019-08-01 16:21:54 +0000753 // Keep track of any change to trigger updates on dependent attributes.
754 ChangeStatus Changed = ChangeStatus::UNCHANGED;
755
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000756 auto *LivenessAA = A.getAAFor<AAIsDead>(*this, getAnchorScope());
757
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000758 // Look at all returned call sites.
759 for (auto &It : ReturnedValues) {
760 SmallPtrSet<ReturnInst *, 2> &ReturnInsts = It.second;
761 Value *RV = It.first;
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000762
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000763 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Potentially returned value " << *RV
764 << "\n");
765
766 // Only call sites can change during an update, ignore the rest.
767 CallSite RetCS(RV);
768 if (!RetCS)
769 continue;
770
771 // For now, any call site we see will prevent us from directly fixing the
772 // state. However, if the information on the callees is fixed, the call
773 // sites will be removed and we will fix the information for this state.
774 HasCallSite = true;
775
Johannes Doerfert4361da22019-08-04 18:38:53 +0000776 // Ignore dead ReturnValues.
777 if (LivenessAA &&
778 !LivenessAA->isLiveInstSet(ReturnInsts.begin(), ReturnInsts.end())) {
779 LLVM_DEBUG(dbgs() << "[AAReturnedValues] all returns are assumed dead, "
780 "skip it for now\n");
781 continue;
782 }
783
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000784 // Try to find a assumed unique return value for the called function.
785 auto *RetCSAA = A.getAAFor<AAReturnedValuesImpl>(*this, *RV);
Johannes Doerfert0a7f4cd2019-07-13 01:09:21 +0000786 if (!RetCSAA) {
Johannes Doerfertda4d8112019-08-01 16:21:54 +0000787 if (!HasOverdefinedReturnedCalls)
788 Changed = ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000789 HasOverdefinedReturnedCalls = true;
790 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned call site (" << *RV
791 << ") with " << (RetCSAA ? "invalid" : "no")
792 << " associated state\n");
793 continue;
794 }
795
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000796 auto *LivenessCSAA = A.getAAFor<AAIsDead>(*this, RetCSAA->getAnchorScope());
797
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000798 // Try to find a assumed unique return value for the called function.
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000799 Optional<Value *> AssumedUniqueRV =
800 RetCSAA->getAssumedUniqueReturnValue(LivenessCSAA);
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000801
802 // If no assumed unique return value was found due to the lack of
803 // candidates, we may need to resolve more calls (through more update
804 // iterations) or the called function will not return. Either way, we simply
805 // stick with the call sites as return values. Because there were not
806 // multiple possibilities, we do not treat it as overdefined.
807 if (!AssumedUniqueRV.hasValue())
808 continue;
809
810 // If multiple, non-refinable values were found, there cannot be a unique
811 // return value for the called function. The returned call is overdefined!
812 if (!AssumedUniqueRV.getValue()) {
Johannes Doerfertda4d8112019-08-01 16:21:54 +0000813 if (!HasOverdefinedReturnedCalls)
814 Changed = ChangeStatus::CHANGED;
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000815 HasOverdefinedReturnedCalls = true;
816 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Returned call site has multiple "
817 "potentially returned values\n");
818 continue;
819 }
820
821 LLVM_DEBUG({
822 bool UniqueRVIsKnown = RetCSAA->isAtFixpoint();
823 dbgs() << "[AAReturnedValues] Returned call site "
824 << (UniqueRVIsKnown ? "known" : "assumed")
825 << " unique return value: " << *AssumedUniqueRV << "\n";
826 });
827
828 // The assumed unique return value.
829 Value *AssumedRetVal = AssumedUniqueRV.getValue();
830
831 // If the assumed unique return value is an argument, lookup the matching
832 // call site operand and recursively collect new returned values.
833 // If it is not an argument, it is just put into the set of returned values
834 // as we would have already looked through casts, phis, and similar values.
835 if (Argument *AssumedRetArg = dyn_cast<Argument>(AssumedRetVal))
836 collectValuesRecursively(A,
837 RetCS.getArgOperand(AssumedRetArg->getArgNo()),
838 ReturnInsts, AddRVs);
839 else
840 AddRVs[AssumedRetVal].insert(ReturnInsts.begin(), ReturnInsts.end());
841 }
842
Johannes Doerfertaccd3e82019-07-08 23:27:20 +0000843 for (auto &It : AddRVs) {
844 assert(!It.second.empty() && "Entry does not add anything.");
845 auto &ReturnInsts = ReturnedValues[It.first];
846 for (ReturnInst *RI : It.second)
847 if (ReturnInsts.insert(RI).second) {
848 LLVM_DEBUG(dbgs() << "[AAReturnedValues] Add new returned value "
849 << *It.first << " => " << *RI << "\n");
850 Changed = ChangeStatus::CHANGED;
851 }
852 }
853
854 // If there is no call site in the returned values we are done.
855 if (!HasCallSite) {
856 indicateOptimisticFixpoint();
857 return ChangeStatus::CHANGED;
858 }
859
860 return Changed;
861}
862
Stefan Stipanovic06263672019-07-11 21:37:40 +0000863/// ------------------------ NoSync Function Attribute -------------------------
864
865struct AANoSyncFunction : AANoSync, BooleanState {
866
Johannes Doerfert007153e2019-08-05 23:26:06 +0000867 AANoSyncFunction(Function &F) : AANoSync(F) {}
Stefan Stipanovic06263672019-07-11 21:37:40 +0000868
869 /// See AbstractAttribute::getState()
870 /// {
871 AbstractState &getState() override { return *this; }
872 const AbstractState &getState() const override { return *this; }
873 /// }
874
875 /// See AbstractAttribute::getManifestPosition().
Johannes Doerfertc7a1db32019-07-13 01:09:27 +0000876 ManifestPosition getManifestPosition() const override { return MP_FUNCTION; }
Stefan Stipanovic06263672019-07-11 21:37:40 +0000877
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +0000878 const std::string getAsStr() const override {
Stefan Stipanovic06263672019-07-11 21:37:40 +0000879 return getAssumed() ? "nosync" : "may-sync";
880 }
881
882 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +0000883 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Stefan Stipanovic06263672019-07-11 21:37:40 +0000884
885 /// See AANoSync::isAssumedNoSync()
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +0000886 bool isAssumedNoSync() const override { return getAssumed(); }
Stefan Stipanovic06263672019-07-11 21:37:40 +0000887
888 /// See AANoSync::isKnownNoSync()
Stefan Stipanoviccb5ecae2019-07-12 18:34:06 +0000889 bool isKnownNoSync() const override { return getKnown(); }
Stefan Stipanovic06263672019-07-11 21:37:40 +0000890
891 /// Helper function used to determine whether an instruction is non-relaxed
892 /// atomic. In other words, if an atomic instruction does not have unordered
893 /// or monotonic ordering
894 static bool isNonRelaxedAtomic(Instruction *I);
895
896 /// Helper function used to determine whether an instruction is volatile.
897 static bool isVolatile(Instruction *I);
898
Johannes Doerfertc7a1db32019-07-13 01:09:27 +0000899 /// Helper function uset to check if intrinsic is volatile (memcpy, memmove,
900 /// memset).
Stefan Stipanovic06263672019-07-11 21:37:40 +0000901 static bool isNoSyncIntrinsic(Instruction *I);
902};
903
904bool AANoSyncFunction::isNonRelaxedAtomic(Instruction *I) {
905 if (!I->isAtomic())
906 return false;
907
908 AtomicOrdering Ordering;
909 switch (I->getOpcode()) {
910 case Instruction::AtomicRMW:
911 Ordering = cast<AtomicRMWInst>(I)->getOrdering();
912 break;
913 case Instruction::Store:
914 Ordering = cast<StoreInst>(I)->getOrdering();
915 break;
916 case Instruction::Load:
917 Ordering = cast<LoadInst>(I)->getOrdering();
918 break;
919 case Instruction::Fence: {
920 auto *FI = cast<FenceInst>(I);
921 if (FI->getSyncScopeID() == SyncScope::SingleThread)
922 return false;
923 Ordering = FI->getOrdering();
924 break;
925 }
926 case Instruction::AtomicCmpXchg: {
927 AtomicOrdering Success = cast<AtomicCmpXchgInst>(I)->getSuccessOrdering();
928 AtomicOrdering Failure = cast<AtomicCmpXchgInst>(I)->getFailureOrdering();
929 // Only if both are relaxed, than it can be treated as relaxed.
930 // Otherwise it is non-relaxed.
931 if (Success != AtomicOrdering::Unordered &&
932 Success != AtomicOrdering::Monotonic)
933 return true;
934 if (Failure != AtomicOrdering::Unordered &&
935 Failure != AtomicOrdering::Monotonic)
936 return true;
937 return false;
938 }
939 default:
940 llvm_unreachable(
941 "New atomic operations need to be known in the attributor.");
942 }
943
944 // Relaxed.
945 if (Ordering == AtomicOrdering::Unordered ||
946 Ordering == AtomicOrdering::Monotonic)
947 return false;
948 return true;
949}
950
951/// Checks if an intrinsic is nosync. Currently only checks mem* intrinsics.
952/// FIXME: We should ipmrove the handling of intrinsics.
953bool AANoSyncFunction::isNoSyncIntrinsic(Instruction *I) {
954 if (auto *II = dyn_cast<IntrinsicInst>(I)) {
955 switch (II->getIntrinsicID()) {
956 /// Element wise atomic memory intrinsics are can only be unordered,
957 /// therefore nosync.
958 case Intrinsic::memset_element_unordered_atomic:
959 case Intrinsic::memmove_element_unordered_atomic:
960 case Intrinsic::memcpy_element_unordered_atomic:
961 return true;
962 case Intrinsic::memset:
963 case Intrinsic::memmove:
964 case Intrinsic::memcpy:
965 if (!cast<MemIntrinsic>(II)->isVolatile())
966 return true;
967 return false;
968 default:
969 return false;
970 }
971 }
972 return false;
973}
974
975bool AANoSyncFunction::isVolatile(Instruction *I) {
976 assert(!ImmutableCallSite(I) && !isa<CallBase>(I) &&
977 "Calls should not be checked here");
978
979 switch (I->getOpcode()) {
980 case Instruction::AtomicRMW:
981 return cast<AtomicRMWInst>(I)->isVolatile();
982 case Instruction::Store:
983 return cast<StoreInst>(I)->isVolatile();
984 case Instruction::Load:
985 return cast<LoadInst>(I)->isVolatile();
986 case Instruction::AtomicCmpXchg:
987 return cast<AtomicCmpXchgInst>(I)->isVolatile();
988 default:
989 return false;
990 }
991}
992
Johannes Doerfert007153e2019-08-05 23:26:06 +0000993ChangeStatus AANoSyncFunction::updateImpl(Attributor &A,
994 InformationCache &InfoCache) {
Stefan Stipanovic06263672019-07-11 21:37:40 +0000995 Function &F = getAnchorScope();
996
Stefan Stipanovicd0216172019-08-02 21:31:22 +0000997 auto *LivenessAA = A.getAAFor<AAIsDead>(*this, F);
998
Stefan Stipanovic06263672019-07-11 21:37:40 +0000999 /// We are looking for volatile instructions or Non-Relaxed atomics.
1000 /// FIXME: We should ipmrove the handling of intrinsics.
1001 for (Instruction *I : InfoCache.getReadOrWriteInstsForFunction(F)) {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001002 // Skip assumed dead instructions.
1003 if (LivenessAA && LivenessAA->isAssumedDead(I))
1004 continue;
1005
Stefan Stipanovic06263672019-07-11 21:37:40 +00001006 ImmutableCallSite ICS(I);
1007 auto *NoSyncAA = A.getAAFor<AANoSyncFunction>(*this, *I);
1008
1009 if (isa<IntrinsicInst>(I) && isNoSyncIntrinsic(I))
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001010 continue;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001011
1012 if (ICS && (!NoSyncAA || !NoSyncAA->isAssumedNoSync()) &&
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001013 !ICS.hasFnAttr(Attribute::NoSync))
1014 return indicatePessimisticFixpoint();
Stefan Stipanovic06263672019-07-11 21:37:40 +00001015
Johannes Doerfertc7a1db32019-07-13 01:09:27 +00001016 if (ICS)
Stefan Stipanovic06263672019-07-11 21:37:40 +00001017 continue;
1018
1019 if (!isVolatile(I) && !isNonRelaxedAtomic(I))
1020 continue;
1021
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001022 return indicatePessimisticFixpoint();
Stefan Stipanovic06263672019-07-11 21:37:40 +00001023 }
1024
1025 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
1026 auto Opcodes = {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
1027 (unsigned)Instruction::Call};
1028
1029 for (unsigned Opcode : Opcodes) {
1030 for (Instruction *I : OpcodeInstMap[Opcode]) {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001031 // Skip assumed dead instructions.
1032 if (LivenessAA && LivenessAA->isAssumedDead(I))
1033 continue;
Stefan Stipanovic06263672019-07-11 21:37:40 +00001034 // At this point we handled all read/write effects and they are all
1035 // nosync, so they can be skipped.
1036 if (I->mayReadOrWriteMemory())
1037 continue;
1038
1039 ImmutableCallSite ICS(I);
1040
1041 // non-convergent and readnone imply nosync.
1042 if (!ICS.isConvergent())
1043 continue;
1044
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001045 return indicatePessimisticFixpoint();
Stefan Stipanovic06263672019-07-11 21:37:40 +00001046 }
1047 }
1048
1049 return ChangeStatus::UNCHANGED;
1050}
1051
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001052/// ------------------------ No-Free Attributes ----------------------------
1053
1054struct AANoFreeFunction : AbstractAttribute, BooleanState {
1055
1056 /// See AbstractAttribute::AbstractAttribute(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001057 AANoFreeFunction(Function &F) : AbstractAttribute(F) {}
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001058
1059 /// See AbstractAttribute::getState()
1060 ///{
1061 AbstractState &getState() override { return *this; }
1062 const AbstractState &getState() const override { return *this; }
1063 ///}
1064
1065 /// See AbstractAttribute::getManifestPosition().
1066 ManifestPosition getManifestPosition() const override { return MP_FUNCTION; }
1067
1068 /// See AbstractAttribute::getAsStr().
1069 const std::string getAsStr() const override {
1070 return getAssumed() ? "nofree" : "may-free";
1071 }
1072
1073 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001074 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001075
1076 /// See AbstractAttribute::getAttrKind().
1077 Attribute::AttrKind getAttrKind() const override { return ID; }
1078
1079 /// Return true if "nofree" is assumed.
1080 bool isAssumedNoFree() const { return getAssumed(); }
1081
1082 /// Return true if "nofree" is known.
1083 bool isKnownNoFree() const { return getKnown(); }
1084
1085 /// The identifier used by the Attributor for this class of attributes.
1086 static constexpr Attribute::AttrKind ID = Attribute::NoFree;
1087};
1088
Johannes Doerfert007153e2019-08-05 23:26:06 +00001089ChangeStatus AANoFreeFunction::updateImpl(Attributor &A,
1090 InformationCache &InfoCache) {
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001091 Function &F = getAnchorScope();
1092
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001093 auto *LivenessAA = A.getAAFor<AAIsDead>(*this, F);
1094
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001095 // The map from instruction opcodes to those instructions in the function.
1096 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
1097
1098 for (unsigned Opcode :
1099 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
1100 (unsigned)Instruction::Call}) {
1101 for (Instruction *I : OpcodeInstMap[Opcode]) {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001102 // Skip assumed dead instructions.
1103 if (LivenessAA && LivenessAA->isAssumedDead(I))
1104 continue;
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001105 auto ICS = ImmutableCallSite(I);
1106 auto *NoFreeAA = A.getAAFor<AANoFreeFunction>(*this, *I);
1107
Johannes Doerfert0a7f4cd2019-07-13 01:09:21 +00001108 if ((!NoFreeAA || !NoFreeAA->isAssumedNoFree()) &&
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001109 !ICS.hasFnAttr(Attribute::NoFree))
1110 return indicatePessimisticFixpoint();
Hideto Ueno65bbaf92019-07-12 17:38:51 +00001111 }
1112 }
1113 return ChangeStatus::UNCHANGED;
1114}
1115
Hideto Ueno54869ec2019-07-15 06:49:04 +00001116/// ------------------------ NonNull Argument Attribute ------------------------
1117struct AANonNullImpl : AANonNull, BooleanState {
1118
Johannes Doerfert007153e2019-08-05 23:26:06 +00001119 AANonNullImpl(Value &V) : AANonNull(V) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001120
Johannes Doerfert007153e2019-08-05 23:26:06 +00001121 AANonNullImpl(Value *AssociatedVal, Value &AnchoredValue)
1122 : AANonNull(AssociatedVal, AnchoredValue) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001123
1124 /// See AbstractAttribute::getState()
1125 /// {
1126 AbstractState &getState() override { return *this; }
1127 const AbstractState &getState() const override { return *this; }
1128 /// }
1129
1130 /// See AbstractAttribute::getAsStr().
1131 const std::string getAsStr() const override {
1132 return getAssumed() ? "nonnull" : "may-null";
1133 }
1134
1135 /// See AANonNull::isAssumedNonNull().
1136 bool isAssumedNonNull() const override { return getAssumed(); }
1137
1138 /// See AANonNull::isKnownNonNull().
1139 bool isKnownNonNull() const override { return getKnown(); }
1140
1141 /// Generate a predicate that checks if a given value is assumed nonnull.
1142 /// The generated function returns true if a value satisfies any of
1143 /// following conditions.
1144 /// (i) A value is known nonZero(=nonnull).
1145 /// (ii) A value is associated with AANonNull and its isAssumedNonNull() is
1146 /// true.
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001147 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)>
1148 generatePredicate(Attributor &);
Hideto Ueno54869ec2019-07-15 06:49:04 +00001149};
1150
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001151std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)>
1152AANonNullImpl::generatePredicate(Attributor &A) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00001153 // FIXME: The `AAReturnedValues` should provide the predicate with the
1154 // `ReturnInst` vector as well such that we can use the control flow sensitive
1155 // version of `isKnownNonZero`. This should fix `test11` in
1156 // `test/Transforms/FunctionAttrs/nonnull.ll`
1157
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001158 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
1159 [&](Value &RV, const SmallPtrSetImpl<ReturnInst *> &RetInsts) -> bool {
1160 Function &F = getAnchorScope();
1161
1162 if (isKnownNonZero(&RV, F.getParent()->getDataLayout()))
Hideto Ueno54869ec2019-07-15 06:49:04 +00001163 return true;
1164
1165 auto *NonNullAA = A.getAAFor<AANonNull>(*this, RV);
1166
1167 ImmutableCallSite ICS(&RV);
1168
1169 if ((!NonNullAA || !NonNullAA->isAssumedNonNull()) &&
1170 (!ICS || !ICS.hasRetAttr(Attribute::NonNull)))
1171 return false;
1172
1173 return true;
1174 };
1175
1176 return Pred;
1177}
1178
1179/// NonNull attribute for function return value.
1180struct AANonNullReturned : AANonNullImpl {
1181
Johannes Doerfert007153e2019-08-05 23:26:06 +00001182 AANonNullReturned(Function &F) : AANonNullImpl(F) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001183
1184 /// See AbstractAttribute::getManifestPosition().
1185 ManifestPosition getManifestPosition() const override { return MP_RETURNED; }
1186
1187 /// See AbstractAttriubute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001188 void initialize(Attributor &A, InformationCache &InfoCache) override {
Hideto Ueno54869ec2019-07-15 06:49:04 +00001189 Function &F = getAnchorScope();
1190
1191 // Already nonnull.
1192 if (F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
Hideto Ueno19c07af2019-07-23 08:16:17 +00001193 Attribute::NonNull) ||
1194 F.getAttributes().hasAttribute(AttributeList::ReturnIndex,
1195 Attribute::Dereferenceable))
Hideto Ueno54869ec2019-07-15 06:49:04 +00001196 indicateOptimisticFixpoint();
1197 }
1198
1199 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001200 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001201};
1202
Johannes Doerfert007153e2019-08-05 23:26:06 +00001203ChangeStatus AANonNullReturned::updateImpl(Attributor &A,
1204 InformationCache &InfoCache) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00001205 Function &F = getAnchorScope();
1206
1207 auto *AARetVal = A.getAAFor<AAReturnedValues>(*this, F);
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001208 if (!AARetVal)
1209 return indicatePessimisticFixpoint();
Hideto Ueno54869ec2019-07-15 06:49:04 +00001210
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001211 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
1212 this->generatePredicate(A);
1213
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001214 if (!AARetVal->checkForallReturnedValues(Pred))
1215 return indicatePessimisticFixpoint();
Hideto Ueno54869ec2019-07-15 06:49:04 +00001216 return ChangeStatus::UNCHANGED;
1217}
1218
1219/// NonNull attribute for function argument.
1220struct AANonNullArgument : AANonNullImpl {
1221
Johannes Doerfert007153e2019-08-05 23:26:06 +00001222 AANonNullArgument(Argument &A) : AANonNullImpl(A) {}
Hideto Ueno54869ec2019-07-15 06:49:04 +00001223
1224 /// See AbstractAttribute::getManifestPosition().
1225 ManifestPosition getManifestPosition() const override { return MP_ARGUMENT; }
1226
1227 /// See AbstractAttriubute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001228 void initialize(Attributor &A, InformationCache &InfoCache) override {
Hideto Ueno54869ec2019-07-15 06:49:04 +00001229 Argument *Arg = cast<Argument>(getAssociatedValue());
1230 if (Arg->hasNonNullAttr())
1231 indicateOptimisticFixpoint();
1232 }
1233
1234 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001235 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001236};
1237
1238/// NonNull attribute for a call site argument.
1239struct AANonNullCallSiteArgument : AANonNullImpl {
1240
1241 /// See AANonNullImpl::AANonNullImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001242 AANonNullCallSiteArgument(CallSite CS, unsigned ArgNo)
1243 : AANonNullImpl(CS.getArgOperand(ArgNo), *CS.getInstruction()),
Hideto Ueno54869ec2019-07-15 06:49:04 +00001244 ArgNo(ArgNo) {}
1245
1246 /// See AbstractAttribute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001247 void initialize(Attributor &A, InformationCache &InfoCache) override {
Hideto Ueno54869ec2019-07-15 06:49:04 +00001248 CallSite CS(&getAnchoredValue());
Hideto Ueno19c07af2019-07-23 08:16:17 +00001249 if (CS.paramHasAttr(ArgNo, getAttrKind()) ||
1250 CS.paramHasAttr(ArgNo, Attribute::Dereferenceable) ||
1251 isKnownNonZero(getAssociatedValue(),
1252 getAnchorScope().getParent()->getDataLayout()))
Hideto Ueno54869ec2019-07-15 06:49:04 +00001253 indicateOptimisticFixpoint();
1254 }
1255
1256 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001257 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno54869ec2019-07-15 06:49:04 +00001258
1259 /// See AbstractAttribute::getManifestPosition().
1260 ManifestPosition getManifestPosition() const override {
1261 return MP_CALL_SITE_ARGUMENT;
1262 };
1263
1264 // Return argument index of associated value.
1265 int getArgNo() const { return ArgNo; }
1266
1267private:
1268 unsigned ArgNo;
1269};
Johannes Doerfert007153e2019-08-05 23:26:06 +00001270
1271ChangeStatus AANonNullArgument::updateImpl(Attributor &A,
1272 InformationCache &InfoCache) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00001273 Function &F = getAnchorScope();
1274 Argument &Arg = cast<Argument>(getAnchoredValue());
1275
1276 unsigned ArgNo = Arg.getArgNo();
1277
1278 // Callback function
1279 std::function<bool(CallSite)> CallSiteCheck = [&](CallSite CS) {
1280 assert(CS && "Sanity check: Call site was not initialized properly!");
1281
1282 auto *NonNullAA = A.getAAFor<AANonNull>(*this, *CS.getInstruction(), ArgNo);
1283
1284 // Check that NonNullAA is AANonNullCallSiteArgument.
1285 if (NonNullAA) {
1286 ImmutableCallSite ICS(&NonNullAA->getAnchoredValue());
1287 if (ICS && CS.getInstruction() == ICS.getInstruction())
1288 return NonNullAA->isAssumedNonNull();
1289 return false;
1290 }
1291
1292 if (CS.paramHasAttr(ArgNo, Attribute::NonNull))
1293 return true;
1294
1295 Value *V = CS.getArgOperand(ArgNo);
1296 if (isKnownNonZero(V, getAnchorScope().getParent()->getDataLayout()))
1297 return true;
1298
1299 return false;
1300 };
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001301 if (!A.checkForAllCallSites(F, CallSiteCheck, true, *this))
1302 return indicatePessimisticFixpoint();
Hideto Ueno54869ec2019-07-15 06:49:04 +00001303 return ChangeStatus::UNCHANGED;
1304}
1305
Johannes Doerfert007153e2019-08-05 23:26:06 +00001306ChangeStatus
1307AANonNullCallSiteArgument::updateImpl(Attributor &A,
1308 InformationCache &InfoCache) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00001309 // NOTE: Never look at the argument of the callee in this method.
1310 // If we do this, "nonnull" is always deduced because of the assumption.
1311
1312 Value &V = *getAssociatedValue();
1313
1314 auto *NonNullAA = A.getAAFor<AANonNull>(*this, V);
1315
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001316 if (!NonNullAA || !NonNullAA->isAssumedNonNull())
1317 return indicatePessimisticFixpoint();
Hideto Ueno54869ec2019-07-15 06:49:04 +00001318
1319 return ChangeStatus::UNCHANGED;
1320}
1321
Hideto Ueno11d37102019-07-17 15:15:43 +00001322/// ------------------------ Will-Return Attributes ----------------------------
1323
1324struct AAWillReturnImpl : public AAWillReturn, BooleanState {
1325
1326 /// See AbstractAttribute::AbstractAttribute(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001327 AAWillReturnImpl(Function &F) : AAWillReturn(F) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00001328
1329 /// See AAWillReturn::isKnownWillReturn().
1330 bool isKnownWillReturn() const override { return getKnown(); }
1331
1332 /// See AAWillReturn::isAssumedWillReturn().
1333 bool isAssumedWillReturn() const override { return getAssumed(); }
1334
1335 /// See AbstractAttribute::getState(...).
1336 AbstractState &getState() override { return *this; }
1337
1338 /// See AbstractAttribute::getState(...).
1339 const AbstractState &getState() const override { return *this; }
1340
1341 /// See AbstractAttribute::getAsStr()
1342 const std::string getAsStr() const override {
1343 return getAssumed() ? "willreturn" : "may-noreturn";
1344 }
1345};
1346
1347struct AAWillReturnFunction final : AAWillReturnImpl {
1348
1349 /// See AbstractAttribute::AbstractAttribute(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001350 AAWillReturnFunction(Function &F) : AAWillReturnImpl(F) {}
Hideto Ueno11d37102019-07-17 15:15:43 +00001351
1352 /// See AbstractAttribute::getManifestPosition().
Hideto Ueno9f5d80d2019-07-23 08:29:22 +00001353 ManifestPosition getManifestPosition() const override { return MP_FUNCTION; }
Hideto Ueno11d37102019-07-17 15:15:43 +00001354
1355 /// See AbstractAttribute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001356 void initialize(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno11d37102019-07-17 15:15:43 +00001357
1358 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001359 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno11d37102019-07-17 15:15:43 +00001360};
1361
1362// Helper function that checks whether a function has any cycle.
1363// TODO: Replace with more efficent code
1364bool containsCycle(Function &F) {
1365 SmallPtrSet<BasicBlock *, 32> Visited;
1366
1367 // Traverse BB by dfs and check whether successor is already visited.
1368 for (BasicBlock *BB : depth_first(&F)) {
1369 Visited.insert(BB);
1370 for (auto *SuccBB : successors(BB)) {
1371 if (Visited.count(SuccBB))
1372 return true;
1373 }
1374 }
1375 return false;
1376}
1377
1378// Helper function that checks the function have a loop which might become an
1379// endless loop
1380// FIXME: Any cycle is regarded as endless loop for now.
1381// We have to allow some patterns.
1382bool containsPossiblyEndlessLoop(Function &F) { return containsCycle(F); }
1383
Johannes Doerfert007153e2019-08-05 23:26:06 +00001384void AAWillReturnFunction::initialize(Attributor &A,
1385 InformationCache &InfoCache) {
Hideto Ueno11d37102019-07-17 15:15:43 +00001386 Function &F = getAnchorScope();
1387
1388 if (containsPossiblyEndlessLoop(F))
1389 indicatePessimisticFixpoint();
1390}
1391
Johannes Doerfert007153e2019-08-05 23:26:06 +00001392ChangeStatus AAWillReturnFunction::updateImpl(Attributor &A,
1393 InformationCache &InfoCache) {
Hideto Ueno11d37102019-07-17 15:15:43 +00001394 Function &F = getAnchorScope();
1395
1396 // The map from instruction opcodes to those instructions in the function.
1397 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
1398
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001399 auto *LivenessAA = A.getAAFor<AAIsDead>(*this, F);
1400
Hideto Ueno11d37102019-07-17 15:15:43 +00001401 for (unsigned Opcode :
1402 {(unsigned)Instruction::Invoke, (unsigned)Instruction::CallBr,
1403 (unsigned)Instruction::Call}) {
1404 for (Instruction *I : OpcodeInstMap[Opcode]) {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001405 // Skip assumed dead instructions.
1406 if (LivenessAA && LivenessAA->isAssumedDead(I))
1407 continue;
1408
Hideto Ueno11d37102019-07-17 15:15:43 +00001409 auto ICS = ImmutableCallSite(I);
1410
1411 if (ICS.hasFnAttr(Attribute::WillReturn))
1412 continue;
1413
1414 auto *WillReturnAA = A.getAAFor<AAWillReturn>(*this, *I);
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001415 if (!WillReturnAA || !WillReturnAA->isAssumedWillReturn())
1416 return indicatePessimisticFixpoint();
Hideto Ueno11d37102019-07-17 15:15:43 +00001417
1418 auto *NoRecurseAA = A.getAAFor<AANoRecurse>(*this, *I);
1419
1420 // FIXME: (i) Prohibit any recursion for now.
1421 // (ii) AANoRecurse isn't implemented yet so currently any call is
1422 // regarded as having recursion.
1423 // Code below should be
1424 // if ((!NoRecurseAA || !NoRecurseAA->isAssumedNoRecurse()) &&
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001425 if (!NoRecurseAA && !ICS.hasFnAttr(Attribute::NoRecurse))
1426 return indicatePessimisticFixpoint();
Hideto Ueno11d37102019-07-17 15:15:43 +00001427 }
1428 }
1429
1430 return ChangeStatus::UNCHANGED;
1431}
1432
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001433/// ------------------------ NoAlias Argument Attribute ------------------------
1434
1435struct AANoAliasImpl : AANoAlias, BooleanState {
1436
Johannes Doerfert007153e2019-08-05 23:26:06 +00001437 AANoAliasImpl(Value &V) : AANoAlias(V) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001438
1439 /// See AbstractAttribute::getState()
1440 /// {
1441 AbstractState &getState() override { return *this; }
1442 const AbstractState &getState() const override { return *this; }
1443 /// }
1444
1445 const std::string getAsStr() const override {
1446 return getAssumed() ? "noalias" : "may-alias";
1447 }
1448
1449 /// See AANoAlias::isAssumedNoAlias().
1450 bool isAssumedNoAlias() const override { return getAssumed(); }
1451
1452 /// See AANoAlias::isKnowndNoAlias().
1453 bool isKnownNoAlias() const override { return getKnown(); }
1454};
1455
1456/// NoAlias attribute for function return value.
1457struct AANoAliasReturned : AANoAliasImpl {
1458
Johannes Doerfert007153e2019-08-05 23:26:06 +00001459 AANoAliasReturned(Function &F) : AANoAliasImpl(F) {}
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001460
1461 /// See AbstractAttribute::getManifestPosition().
1462 virtual ManifestPosition getManifestPosition() const override {
1463 return MP_RETURNED;
1464 }
1465
1466 /// See AbstractAttriubute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001467 void initialize(Attributor &A, InformationCache &InfoCache) override {
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001468 Function &F = getAnchorScope();
1469
1470 // Already noalias.
1471 if (F.returnDoesNotAlias()) {
1472 indicateOptimisticFixpoint();
1473 return;
1474 }
1475 }
1476
1477 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001478 virtual ChangeStatus updateImpl(Attributor &A,
1479 InformationCache &InfoCache) override;
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001480};
1481
Johannes Doerfert007153e2019-08-05 23:26:06 +00001482ChangeStatus AANoAliasReturned::updateImpl(Attributor &A,
1483 InformationCache &InfoCache) {
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001484 Function &F = getAnchorScope();
1485
1486 auto *AARetValImpl = A.getAAFor<AAReturnedValuesImpl>(*this, F);
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001487 if (!AARetValImpl)
1488 return indicatePessimisticFixpoint();
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001489
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001490 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
1491 [&](Value &RV, const SmallPtrSetImpl<ReturnInst *> &RetInsts) -> bool {
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001492 if (Constant *C = dyn_cast<Constant>(&RV))
1493 if (C->isNullValue() || isa<UndefValue>(C))
1494 return true;
1495
1496 /// For now, we can only deduce noalias if we have call sites.
1497 /// FIXME: add more support.
1498 ImmutableCallSite ICS(&RV);
1499 if (!ICS)
1500 return false;
1501
1502 auto *NoAliasAA = A.getAAFor<AANoAlias>(*this, RV);
1503
Hideto Ueno9f5d80d2019-07-23 08:29:22 +00001504 if (!ICS.returnDoesNotAlias() &&
1505 (!NoAliasAA || !NoAliasAA->isAssumedNoAlias()))
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001506 return false;
1507
1508 /// FIXME: We can improve capture check in two ways:
1509 /// 1. Use the AANoCapture facilities.
1510 /// 2. Use the location of return insts for escape queries.
1511 if (PointerMayBeCaptured(&RV, /* ReturnCaptures */ false,
1512 /* StoreCaptures */ true))
1513 return false;
1514
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001515 return true;
1516 };
1517
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001518 if (!AARetValImpl->checkForallReturnedValues(Pred))
1519 return indicatePessimisticFixpoint();
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00001520
1521 return ChangeStatus::UNCHANGED;
1522}
1523
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001524/// -------------------AAIsDead Function Attribute-----------------------
1525
1526struct AAIsDeadFunction : AAIsDead, BooleanState {
1527
Johannes Doerfert007153e2019-08-05 23:26:06 +00001528 AAIsDeadFunction(Function &F) : AAIsDead(F) {}
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001529
1530 /// See AbstractAttribute::getState()
1531 /// {
1532 AbstractState &getState() override { return *this; }
1533 const AbstractState &getState() const override { return *this; }
1534 /// }
1535
1536 /// See AbstractAttribute::getManifestPosition().
1537 ManifestPosition getManifestPosition() const override { return MP_FUNCTION; }
1538
Johannes Doerfert007153e2019-08-05 23:26:06 +00001539 void initialize(Attributor &A, InformationCache &InfoCache) override {
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001540 Function &F = getAnchorScope();
1541
1542 ToBeExploredPaths.insert(&(F.getEntryBlock().front()));
1543 AssumedLiveBlocks.insert(&(F.getEntryBlock()));
1544 for (size_t i = 0; i < ToBeExploredPaths.size(); ++i)
Johannes Doerfert4361da22019-08-04 18:38:53 +00001545 if (const Instruction *NextNoReturnI =
1546 findNextNoReturn(A, ToBeExploredPaths[i]))
1547 NoReturnCalls.insert(NextNoReturnI);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001548 }
1549
Johannes Doerfert4361da22019-08-04 18:38:53 +00001550 /// Find the next assumed noreturn instruction in the block of \p I starting
1551 /// from, thus including, \p I.
1552 ///
1553 /// The caller is responsible to monitor the ToBeExploredPaths set as new
1554 /// instructions discovered in other basic block will be placed in there.
1555 ///
1556 /// \returns The next assumed noreturn instructions in the block of \p I
1557 /// starting from, thus including, \p I.
1558 const Instruction *findNextNoReturn(Attributor &A, const Instruction *I);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001559
1560 const std::string getAsStr() const override {
1561 return "LiveBBs(" + std::to_string(AssumedLiveBlocks.size()) + "/" +
1562 std::to_string(getAnchorScope().size()) + ")";
1563 }
1564
1565 /// See AbstractAttribute::manifest(...).
1566 ChangeStatus manifest(Attributor &A) override {
1567 assert(getState().isValidState() &&
1568 "Attempted to manifest an invalid state!");
1569
1570 ChangeStatus HasChanged = ChangeStatus::UNCHANGED;
Johannes Doerfert924d2132019-08-05 21:34:45 +00001571 const Function &F = getAnchorScope();
1572
1573 // Flag to determine if we can change an invoke to a call assuming the callee
1574 // is nounwind. This is not possible if the personality of the function allows
1575 // to catch asynchronous exceptions.
1576 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001577
Johannes Doerfert4361da22019-08-04 18:38:53 +00001578 for (const Instruction *NRC : NoReturnCalls) {
1579 Instruction *I = const_cast<Instruction *>(NRC);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001580 BasicBlock *BB = I->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00001581 Instruction *SplitPos = I->getNextNode();
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001582
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001583 if (auto *II = dyn_cast<InvokeInst>(I)) {
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00001584 // If we keep the invoke the split position is at the beginning of the
1585 // normal desitination block (it invokes a noreturn function after all).
1586 BasicBlock *NormalDestBB = II->getNormalDest();
1587 SplitPos = &NormalDestBB->front();
1588
Johannes Doerfert4361da22019-08-04 18:38:53 +00001589 /// Invoke is replaced with a call and unreachable is placed after it if
1590 /// the callee is nounwind and noreturn. Otherwise, we keep the invoke
1591 /// and only place an unreachable in the normal successor.
Johannes Doerfert924d2132019-08-05 21:34:45 +00001592 if (Invoke2CallAllowed) {
1593 if (Function *Callee = II->getCalledFunction()) {
1594 auto *AANoUnw = A.getAAFor<AANoUnwind>(*this, *Callee);
1595 if (Callee->hasFnAttribute(Attribute::NoUnwind) ||
1596 (AANoUnw && AANoUnw->isAssumedNoUnwind())) {
1597 LLVM_DEBUG(dbgs()
1598 << "[AAIsDead] Replace invoke with call inst\n");
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00001599 // We do not need an invoke (II) but instead want a call followed
1600 // by an unreachable. However, we do not remove II as other
1601 // abstract attributes might have it cached as part of their
1602 // results. Given that we modify the CFG anyway, we simply keep II
1603 // around but in a new dead block. To avoid II being live through
1604 // a different edge we have to ensure the block we place it in is
1605 // only reached from the current block of II and then not reached
1606 // at all when we insert the unreachable.
1607 SplitBlockPredecessors(NormalDestBB, {BB}, ".i2c");
1608 CallInst *CI = createCallMatchingInvoke(II);
1609 CI->insertBefore(II);
1610 CI->takeName(II);
1611 II->replaceAllUsesWith(CI);
1612 SplitPos = CI->getNextNode();
Johannes Doerfert924d2132019-08-05 21:34:45 +00001613 }
Johannes Doerfert4361da22019-08-04 18:38:53 +00001614 }
1615 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001616 }
1617
Johannes Doerfert3d7bbc62019-08-05 21:35:02 +00001618 BB = SplitPos->getParent();
Johannes Doerfert4361da22019-08-04 18:38:53 +00001619 SplitBlock(BB, SplitPos);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001620 changeToUnreachable(BB->getTerminator(), /* UseLLVMTrap */ false);
1621 HasChanged = ChangeStatus::CHANGED;
1622 }
1623
1624 return HasChanged;
1625 }
1626
1627 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001628 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001629
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001630 /// See AAIsDead::isAssumedDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00001631 bool isAssumedDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001632 assert(BB->getParent() == &getAnchorScope() &&
1633 "BB must be in the same anchor scope function.");
1634
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001635 if (!getAssumed())
1636 return false;
1637 return !AssumedLiveBlocks.count(BB);
1638 }
1639
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001640 /// See AAIsDead::isKnownDead(BasicBlock *).
Johannes Doerfert4361da22019-08-04 18:38:53 +00001641 bool isKnownDead(const BasicBlock *BB) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001642 return getKnown() && isAssumedDead(BB);
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001643 }
1644
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001645 /// See AAIsDead::isAssumed(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00001646 bool isAssumedDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001647 assert(I->getParent()->getParent() == &getAnchorScope() &&
1648 "Instruction must be in the same anchor scope function.");
1649
Stefan Stipanovic7849e412019-08-03 15:27:41 +00001650 if (!getAssumed())
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001651 return false;
1652
1653 // If it is not in AssumedLiveBlocks then it for sure dead.
1654 // Otherwise, it can still be after noreturn call in a live block.
1655 if (!AssumedLiveBlocks.count(I->getParent()))
1656 return true;
1657
1658 // If it is not after a noreturn call, than it is live.
Johannes Doerfert4361da22019-08-04 18:38:53 +00001659 return isAfterNoReturn(I);
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001660 }
1661
1662 /// See AAIsDead::isKnownDead(Instruction *I).
Johannes Doerfert4361da22019-08-04 18:38:53 +00001663 bool isKnownDead(const Instruction *I) const override {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001664 return getKnown() && isAssumedDead(I);
1665 }
1666
1667 /// Check if instruction is after noreturn call, in other words, assumed dead.
Johannes Doerfert4361da22019-08-04 18:38:53 +00001668 bool isAfterNoReturn(const Instruction *I) const;
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001669
Johannes Doerfert924d2132019-08-05 21:34:45 +00001670 /// Determine if \p F might catch asynchronous exceptions.
1671 static bool mayCatchAsynchronousExceptions(const Function &F) {
1672 return F.hasPersonalityFn() && !canSimplifyInvokeNoUnwind(&F);
1673 }
1674
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001675 /// Collection of to be explored paths.
Johannes Doerfert4361da22019-08-04 18:38:53 +00001676 SmallSetVector<const Instruction *, 8> ToBeExploredPaths;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001677
1678 /// Collection of all assumed live BasicBlocks.
Johannes Doerfert4361da22019-08-04 18:38:53 +00001679 DenseSet<const BasicBlock *> AssumedLiveBlocks;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001680
1681 /// Collection of calls with noreturn attribute, assumed or knwon.
Johannes Doerfert4361da22019-08-04 18:38:53 +00001682 SmallSetVector<const Instruction *, 4> NoReturnCalls;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001683};
1684
Johannes Doerfert4361da22019-08-04 18:38:53 +00001685bool AAIsDeadFunction::isAfterNoReturn(const Instruction *I) const {
1686 const Instruction *PrevI = I->getPrevNode();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001687 while (PrevI) {
1688 if (NoReturnCalls.count(PrevI))
1689 return true;
1690 PrevI = PrevI->getPrevNode();
1691 }
1692 return false;
1693}
1694
Johannes Doerfert4361da22019-08-04 18:38:53 +00001695const Instruction *AAIsDeadFunction::findNextNoReturn(Attributor &A,
1696 const Instruction *I) {
1697 const BasicBlock *BB = I->getParent();
Johannes Doerfert924d2132019-08-05 21:34:45 +00001698 const Function &F = *BB->getParent();
1699
1700 // Flag to determine if we can change an invoke to a call assuming the callee
1701 // is nounwind. This is not possible if the personality of the function allows
1702 // to catch asynchronous exceptions.
1703 bool Invoke2CallAllowed = !mayCatchAsynchronousExceptions(F);
Johannes Doerfert4361da22019-08-04 18:38:53 +00001704
1705 // TODO: We should have a function that determines if an "edge" is dead.
1706 // Edges could be from an instruction to the next or from a terminator
1707 // to the successor. For now, we need to special case the unwind block
1708 // of InvokeInst below.
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001709
1710 while (I) {
1711 ImmutableCallSite ICS(I);
1712
1713 if (ICS) {
Johannes Doerfert4361da22019-08-04 18:38:53 +00001714 // Regarless of the no-return property of an invoke instruction we only
1715 // learn that the regular successor is not reachable through this
1716 // instruction but the unwind block might still be.
1717 if (auto *Invoke = dyn_cast<InvokeInst>(I)) {
1718 // Use nounwind to justify the unwind block is dead as well.
1719 auto *AANoUnw = A.getAAFor<AANoUnwind>(*this, *Invoke);
Johannes Doerfert924d2132019-08-05 21:34:45 +00001720 if (!Invoke2CallAllowed ||
1721 (!AANoUnw || !AANoUnw->isAssumedNoUnwind())) {
Johannes Doerfert4361da22019-08-04 18:38:53 +00001722 AssumedLiveBlocks.insert(Invoke->getUnwindDest());
1723 ToBeExploredPaths.insert(&Invoke->getUnwindDest()->front());
1724 }
1725 }
1726
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001727 auto *NoReturnAA = A.getAAFor<AANoReturn>(*this, *I);
Johannes Doerfert4361da22019-08-04 18:38:53 +00001728 if (ICS.hasFnAttr(Attribute::NoReturn) ||
1729 (NoReturnAA && NoReturnAA->isAssumedNoReturn()))
1730 return I;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001731 }
1732
1733 I = I->getNextNode();
1734 }
1735
1736 // get new paths (reachable blocks).
Johannes Doerfert4361da22019-08-04 18:38:53 +00001737 for (const BasicBlock *SuccBB : successors(BB)) {
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001738 AssumedLiveBlocks.insert(SuccBB);
Johannes Doerfert4361da22019-08-04 18:38:53 +00001739 ToBeExploredPaths.insert(&SuccBB->front());
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001740 }
1741
Johannes Doerfert4361da22019-08-04 18:38:53 +00001742 // No noreturn instruction found.
1743 return nullptr;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001744}
1745
Johannes Doerfert007153e2019-08-05 23:26:06 +00001746ChangeStatus AAIsDeadFunction::updateImpl(Attributor &A,
1747 InformationCache &InfoCache) {
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001748 // Temporary collection to iterate over existing noreturn instructions. This
1749 // will alow easier modification of NoReturnCalls collection
Johannes Doerfert4361da22019-08-04 18:38:53 +00001750 SmallVector<const Instruction *, 8> NoReturnChanged;
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001751 ChangeStatus Status = ChangeStatus::UNCHANGED;
1752
Johannes Doerfert4361da22019-08-04 18:38:53 +00001753 for (const Instruction *I : NoReturnCalls)
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001754 NoReturnChanged.push_back(I);
1755
Johannes Doerfert4361da22019-08-04 18:38:53 +00001756 for (const Instruction *I : NoReturnChanged) {
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001757 size_t Size = ToBeExploredPaths.size();
1758
Johannes Doerfert4361da22019-08-04 18:38:53 +00001759 const Instruction *NextNoReturnI = findNextNoReturn(A, I);
1760 if (NextNoReturnI != I) {
1761 Status = ChangeStatus::CHANGED;
1762 NoReturnCalls.remove(I);
1763 if (NextNoReturnI)
1764 NoReturnCalls.insert(NextNoReturnI);
1765 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001766
Johannes Doerfert4361da22019-08-04 18:38:53 +00001767 // Explore new paths.
1768 while (Size != ToBeExploredPaths.size()) {
1769 Status = ChangeStatus::CHANGED;
1770 if (const Instruction *NextNoReturnI =
1771 findNextNoReturn(A, ToBeExploredPaths[Size++]))
1772 NoReturnCalls.insert(NextNoReturnI);
1773 }
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001774 }
1775
Hideto Ueno19c07af2019-07-23 08:16:17 +00001776 LLVM_DEBUG(
1777 dbgs() << "[AAIsDead] AssumedLiveBlocks: " << AssumedLiveBlocks.size()
Stefan Stipanovicd0216172019-08-02 21:31:22 +00001778 << " Total number of blocks: " << getAnchorScope().size() << "\n");
Stefan Stipanovic6058b862019-07-22 23:58:23 +00001779
1780 return Status;
1781}
1782
Hideto Ueno19c07af2019-07-23 08:16:17 +00001783/// -------------------- Dereferenceable Argument Attribute --------------------
1784
1785struct DerefState : AbstractState {
1786
1787 /// State representing for dereferenceable bytes.
1788 IntegerState DerefBytesState;
1789
1790 /// State representing that whether the value is nonnull or global.
1791 IntegerState NonNullGlobalState;
1792
1793 /// Bits encoding for NonNullGlobalState.
1794 enum {
1795 DEREF_NONNULL = 1 << 0,
1796 DEREF_GLOBAL = 1 << 1,
1797 };
1798
1799 /// See AbstractState::isValidState()
1800 bool isValidState() const override { return DerefBytesState.isValidState(); }
1801
Johannes Doerfertb6acee52019-08-04 17:55:15 +00001802 /// See AbstractState::isAtFixpoint()
Hideto Ueno19c07af2019-07-23 08:16:17 +00001803 bool isAtFixpoint() const override {
Johannes Doerfertb6acee52019-08-04 17:55:15 +00001804 return !isValidState() || (DerefBytesState.isAtFixpoint() &&
1805 NonNullGlobalState.isAtFixpoint());
Hideto Ueno19c07af2019-07-23 08:16:17 +00001806 }
1807
1808 /// See AbstractState::indicateOptimisticFixpoint(...)
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001809 ChangeStatus indicateOptimisticFixpoint() override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00001810 DerefBytesState.indicateOptimisticFixpoint();
1811 NonNullGlobalState.indicateOptimisticFixpoint();
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001812 return ChangeStatus::UNCHANGED;
Hideto Ueno19c07af2019-07-23 08:16:17 +00001813 }
1814
1815 /// See AbstractState::indicatePessimisticFixpoint(...)
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001816 ChangeStatus indicatePessimisticFixpoint() override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00001817 DerefBytesState.indicatePessimisticFixpoint();
1818 NonNullGlobalState.indicatePessimisticFixpoint();
Johannes Doerfertd1c37932019-08-04 18:37:38 +00001819 return ChangeStatus::CHANGED;
Hideto Ueno19c07af2019-07-23 08:16:17 +00001820 }
1821
1822 /// Update known dereferenceable bytes.
1823 void takeKnownDerefBytesMaximum(uint64_t Bytes) {
1824 DerefBytesState.takeKnownMaximum(Bytes);
1825 }
1826
1827 /// Update assumed dereferenceable bytes.
1828 void takeAssumedDerefBytesMinimum(uint64_t Bytes) {
1829 DerefBytesState.takeAssumedMinimum(Bytes);
1830 }
1831
1832 /// Update assumed NonNullGlobalState
1833 void updateAssumedNonNullGlobalState(bool IsNonNull, bool IsGlobal) {
1834 if (!IsNonNull)
1835 NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
1836 if (!IsGlobal)
1837 NonNullGlobalState.removeAssumedBits(DEREF_GLOBAL);
1838 }
1839
1840 /// Equality for DerefState.
1841 bool operator==(const DerefState &R) {
1842 return this->DerefBytesState == R.DerefBytesState &&
1843 this->NonNullGlobalState == R.NonNullGlobalState;
1844 }
1845};
1846struct AADereferenceableImpl : AADereferenceable, DerefState {
1847
Johannes Doerfert007153e2019-08-05 23:26:06 +00001848 AADereferenceableImpl(Value &V) : AADereferenceable(V) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00001849
Johannes Doerfert007153e2019-08-05 23:26:06 +00001850 AADereferenceableImpl(Value *AssociatedVal, Value &AnchoredValue)
1851 : AADereferenceable(AssociatedVal, AnchoredValue) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00001852
1853 /// See AbstractAttribute::getState()
1854 /// {
1855 AbstractState &getState() override { return *this; }
1856 const AbstractState &getState() const override { return *this; }
1857 /// }
1858
1859 /// See AADereferenceable::getAssumedDereferenceableBytes().
1860 uint32_t getAssumedDereferenceableBytes() const override {
1861 return DerefBytesState.getAssumed();
1862 }
1863
1864 /// See AADereferenceable::getKnownDereferenceableBytes().
1865 uint32_t getKnownDereferenceableBytes() const override {
1866 return DerefBytesState.getKnown();
1867 }
1868
1869 // Helper function for syncing nonnull state.
1870 void syncNonNull(const AANonNull *NonNullAA) {
1871 if (!NonNullAA) {
1872 NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
1873 return;
1874 }
1875
1876 if (NonNullAA->isKnownNonNull())
1877 NonNullGlobalState.addKnownBits(DEREF_NONNULL);
1878
1879 if (!NonNullAA->isAssumedNonNull())
1880 NonNullGlobalState.removeAssumedBits(DEREF_NONNULL);
1881 }
1882
1883 /// See AADereferenceable::isAssumedGlobal().
1884 bool isAssumedGlobal() const override {
1885 return NonNullGlobalState.isAssumed(DEREF_GLOBAL);
1886 }
1887
1888 /// See AADereferenceable::isKnownGlobal().
1889 bool isKnownGlobal() const override {
1890 return NonNullGlobalState.isKnown(DEREF_GLOBAL);
1891 }
1892
1893 /// See AADereferenceable::isAssumedNonNull().
1894 bool isAssumedNonNull() const override {
1895 return NonNullGlobalState.isAssumed(DEREF_NONNULL);
1896 }
1897
1898 /// See AADereferenceable::isKnownNonNull().
1899 bool isKnownNonNull() const override {
1900 return NonNullGlobalState.isKnown(DEREF_NONNULL);
1901 }
1902
1903 void getDeducedAttributes(SmallVectorImpl<Attribute> &Attrs) const override {
1904 LLVMContext &Ctx = AnchoredVal.getContext();
1905
1906 // TODO: Add *_globally support
1907 if (isAssumedNonNull())
1908 Attrs.emplace_back(Attribute::getWithDereferenceableBytes(
1909 Ctx, getAssumedDereferenceableBytes()));
1910 else
1911 Attrs.emplace_back(Attribute::getWithDereferenceableOrNullBytes(
1912 Ctx, getAssumedDereferenceableBytes()));
1913 }
1914 uint64_t computeAssumedDerefenceableBytes(Attributor &A, Value &V,
1915 bool &IsNonNull, bool &IsGlobal);
1916
Johannes Doerfert007153e2019-08-05 23:26:06 +00001917 void initialize(Attributor &A, InformationCache &InfoCache) override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00001918 Function &F = getAnchorScope();
1919 unsigned AttrIdx =
1920 getAttrIndex(getManifestPosition(), getArgNo(getAnchoredValue()));
1921
1922 for (Attribute::AttrKind AK :
1923 {Attribute::Dereferenceable, Attribute::DereferenceableOrNull})
1924 if (F.getAttributes().hasAttribute(AttrIdx, AK))
1925 takeKnownDerefBytesMaximum(F.getAttribute(AttrIdx, AK).getValueAsInt());
1926 }
1927
1928 /// See AbstractAttribute::getAsStr().
1929 const std::string getAsStr() const override {
1930 if (!getAssumedDereferenceableBytes())
1931 return "unknown-dereferenceable";
1932 return std::string("dereferenceable") +
1933 (isAssumedNonNull() ? "" : "_or_null") +
1934 (isAssumedGlobal() ? "_globally" : "") + "<" +
1935 std::to_string(getKnownDereferenceableBytes()) + "-" +
1936 std::to_string(getAssumedDereferenceableBytes()) + ">";
1937 }
1938};
1939
1940struct AADereferenceableReturned : AADereferenceableImpl {
Johannes Doerfert007153e2019-08-05 23:26:06 +00001941 AADereferenceableReturned(Function &F) : AADereferenceableImpl(F) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00001942
1943 /// See AbstractAttribute::getManifestPosition().
1944 ManifestPosition getManifestPosition() const override { return MP_RETURNED; }
1945
1946 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00001947 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno19c07af2019-07-23 08:16:17 +00001948};
1949
1950// Helper function that returns dereferenceable bytes.
1951static uint64_t calcDifferenceIfBaseIsNonNull(int64_t DerefBytes,
1952 int64_t Offset, bool IsNonNull) {
1953 if (!IsNonNull)
1954 return 0;
1955 return std::max((int64_t)0, DerefBytes - Offset);
1956}
1957
1958uint64_t AADereferenceableImpl::computeAssumedDerefenceableBytes(
1959 Attributor &A, Value &V, bool &IsNonNull, bool &IsGlobal) {
1960 // TODO: Tracking the globally flag.
1961 IsGlobal = false;
1962
1963 // First, we try to get information about V from Attributor.
1964 if (auto *DerefAA = A.getAAFor<AADereferenceable>(*this, V)) {
1965 IsNonNull &= DerefAA->isAssumedNonNull();
1966 return DerefAA->getAssumedDereferenceableBytes();
1967 }
1968
1969 // Otherwise, we try to compute assumed bytes from base pointer.
1970 const DataLayout &DL = getAnchorScope().getParent()->getDataLayout();
1971 unsigned IdxWidth =
1972 DL.getIndexSizeInBits(V.getType()->getPointerAddressSpace());
1973 APInt Offset(IdxWidth, 0);
1974 Value *Base = V.stripAndAccumulateInBoundsConstantOffsets(DL, Offset);
1975
1976 if (auto *BaseDerefAA = A.getAAFor<AADereferenceable>(*this, *Base)) {
1977 IsNonNull &= Offset != 0;
1978 return calcDifferenceIfBaseIsNonNull(
1979 BaseDerefAA->getAssumedDereferenceableBytes(), Offset.getSExtValue(),
1980 Offset != 0 || BaseDerefAA->isAssumedNonNull());
1981 }
1982
1983 // Then, use IR information.
1984
1985 if (isDereferenceablePointer(Base, Base->getType(), DL))
1986 return calcDifferenceIfBaseIsNonNull(
1987 DL.getTypeStoreSize(Base->getType()->getPointerElementType()),
1988 Offset.getSExtValue(),
1989 !NullPointerIsDefined(&getAnchorScope(),
1990 V.getType()->getPointerAddressSpace()));
1991
1992 IsNonNull = false;
1993 return 0;
1994}
Johannes Doerfert007153e2019-08-05 23:26:06 +00001995
1996ChangeStatus
1997AADereferenceableReturned::updateImpl(Attributor &A,
1998 InformationCache &InfoCache) {
Hideto Ueno19c07af2019-07-23 08:16:17 +00001999 Function &F = getAnchorScope();
2000 auto BeforeState = static_cast<DerefState>(*this);
2001
2002 syncNonNull(A.getAAFor<AANonNull>(*this, F));
2003
2004 auto *AARetVal = A.getAAFor<AAReturnedValues>(*this, F);
Johannes Doerfertd1c37932019-08-04 18:37:38 +00002005 if (!AARetVal)
2006 return indicatePessimisticFixpoint();
Hideto Ueno19c07af2019-07-23 08:16:17 +00002007
2008 bool IsNonNull = isAssumedNonNull();
2009 bool IsGlobal = isAssumedGlobal();
2010
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002011 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
2012 [&](Value &RV, const SmallPtrSetImpl<ReturnInst *> &RetInsts) -> bool {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002013 takeAssumedDerefBytesMinimum(
2014 computeAssumedDerefenceableBytes(A, RV, IsNonNull, IsGlobal));
2015 return isValidState();
2016 };
2017
2018 if (AARetVal->checkForallReturnedValues(Pred)) {
2019 updateAssumedNonNullGlobalState(IsNonNull, IsGlobal);
2020 return BeforeState == static_cast<DerefState>(*this)
2021 ? ChangeStatus::UNCHANGED
2022 : ChangeStatus::CHANGED;
2023 }
Johannes Doerfertd1c37932019-08-04 18:37:38 +00002024 return indicatePessimisticFixpoint();
Hideto Ueno19c07af2019-07-23 08:16:17 +00002025}
2026
2027struct AADereferenceableArgument : AADereferenceableImpl {
Johannes Doerfert007153e2019-08-05 23:26:06 +00002028 AADereferenceableArgument(Argument &A) : AADereferenceableImpl(A) {}
Hideto Ueno19c07af2019-07-23 08:16:17 +00002029
2030 /// See AbstractAttribute::getManifestPosition().
2031 ManifestPosition getManifestPosition() const override { return MP_ARGUMENT; }
2032
2033 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002034 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002035};
2036
Johannes Doerfert007153e2019-08-05 23:26:06 +00002037ChangeStatus
2038AADereferenceableArgument::updateImpl(Attributor &A,
2039 InformationCache &InfoCache) {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002040 Function &F = getAnchorScope();
2041 Argument &Arg = cast<Argument>(getAnchoredValue());
2042
2043 auto BeforeState = static_cast<DerefState>(*this);
2044
2045 unsigned ArgNo = Arg.getArgNo();
2046
2047 syncNonNull(A.getAAFor<AANonNull>(*this, F, ArgNo));
2048
2049 bool IsNonNull = isAssumedNonNull();
2050 bool IsGlobal = isAssumedGlobal();
2051
2052 // Callback function
2053 std::function<bool(CallSite)> CallSiteCheck = [&](CallSite CS) -> bool {
2054 assert(CS && "Sanity check: Call site was not initialized properly!");
2055
2056 // Check that DereferenceableAA is AADereferenceableCallSiteArgument.
2057 if (auto *DereferenceableAA =
2058 A.getAAFor<AADereferenceable>(*this, *CS.getInstruction(), ArgNo)) {
2059 ImmutableCallSite ICS(&DereferenceableAA->getAnchoredValue());
2060 if (ICS && CS.getInstruction() == ICS.getInstruction()) {
2061 takeAssumedDerefBytesMinimum(
2062 DereferenceableAA->getAssumedDereferenceableBytes());
2063 IsNonNull &= DereferenceableAA->isAssumedNonNull();
2064 IsGlobal &= DereferenceableAA->isAssumedGlobal();
2065 return isValidState();
2066 }
2067 }
2068
2069 takeAssumedDerefBytesMinimum(computeAssumedDerefenceableBytes(
2070 A, *CS.getArgOperand(ArgNo), IsNonNull, IsGlobal));
2071
2072 return isValidState();
2073 };
2074
Johannes Doerfertd1c37932019-08-04 18:37:38 +00002075 if (!A.checkForAllCallSites(F, CallSiteCheck, true, *this))
2076 return indicatePessimisticFixpoint();
Hideto Ueno19c07af2019-07-23 08:16:17 +00002077
2078 updateAssumedNonNullGlobalState(IsNonNull, IsGlobal);
2079
2080 return BeforeState == static_cast<DerefState>(*this) ? ChangeStatus::UNCHANGED
2081 : ChangeStatus::CHANGED;
2082}
2083
2084/// Dereferenceable attribute for a call site argument.
2085struct AADereferenceableCallSiteArgument : AADereferenceableImpl {
2086
2087 /// See AADereferenceableImpl::AADereferenceableImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002088 AADereferenceableCallSiteArgument(CallSite CS, unsigned ArgNo)
2089 : AADereferenceableImpl(CS.getArgOperand(ArgNo), *CS.getInstruction()),
Hideto Ueno19c07af2019-07-23 08:16:17 +00002090 ArgNo(ArgNo) {}
2091
2092 /// See AbstractAttribute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002093 void initialize(Attributor &A, InformationCache &InfoCache) override {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002094 CallSite CS(&getAnchoredValue());
2095 if (CS.paramHasAttr(ArgNo, Attribute::Dereferenceable))
Hideto Ueno96bb3472019-08-03 04:10:50 +00002096 takeKnownDerefBytesMaximum(
2097 CS.getDereferenceableBytes(ArgNo + AttributeList::FirstArgIndex));
Hideto Ueno19c07af2019-07-23 08:16:17 +00002098
2099 if (CS.paramHasAttr(ArgNo, Attribute::DereferenceableOrNull))
Hideto Ueno96bb3472019-08-03 04:10:50 +00002100 takeKnownDerefBytesMaximum(CS.getDereferenceableOrNullBytes(
2101 ArgNo + AttributeList::FirstArgIndex));
Hideto Ueno19c07af2019-07-23 08:16:17 +00002102 }
2103
2104 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002105 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Ueno19c07af2019-07-23 08:16:17 +00002106
2107 /// See AbstractAttribute::getManifestPosition().
2108 ManifestPosition getManifestPosition() const override {
2109 return MP_CALL_SITE_ARGUMENT;
2110 };
2111
2112 // Return argument index of associated value.
2113 int getArgNo() const { return ArgNo; }
2114
2115private:
2116 unsigned ArgNo;
2117};
2118
Johannes Doerfert007153e2019-08-05 23:26:06 +00002119ChangeStatus
2120AADereferenceableCallSiteArgument::updateImpl(Attributor &A,
2121 InformationCache &InfoCache) {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002122 // NOTE: Never look at the argument of the callee in this method.
2123 // If we do this, "dereferenceable" is always deduced because of the
2124 // assumption.
2125
2126 Value &V = *getAssociatedValue();
2127
2128 auto BeforeState = static_cast<DerefState>(*this);
2129
2130 syncNonNull(A.getAAFor<AANonNull>(*this, getAnchoredValue(), ArgNo));
2131 bool IsNonNull = isAssumedNonNull();
2132 bool IsGlobal = isKnownGlobal();
2133
2134 takeAssumedDerefBytesMinimum(
2135 computeAssumedDerefenceableBytes(A, V, IsNonNull, IsGlobal));
2136 updateAssumedNonNullGlobalState(IsNonNull, IsGlobal);
2137
2138 return BeforeState == static_cast<DerefState>(*this) ? ChangeStatus::UNCHANGED
2139 : ChangeStatus::CHANGED;
2140}
2141
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002142// ------------------------ Align Argument Attribute ------------------------
2143
2144struct AAAlignImpl : AAAlign, IntegerState {
2145
2146 // Max alignemnt value allowed in IR
2147 static const unsigned MAX_ALIGN = 1U << 29;
2148
Johannes Doerfert007153e2019-08-05 23:26:06 +00002149 AAAlignImpl(Value *AssociatedVal, Value &AnchoredValue)
2150 : AAAlign(AssociatedVal, AnchoredValue), IntegerState(MAX_ALIGN) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002151
Johannes Doerfert007153e2019-08-05 23:26:06 +00002152 AAAlignImpl(Value &V) : AAAlignImpl(&V, V) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002153
2154 /// See AbstractAttribute::getState()
2155 /// {
2156 AbstractState &getState() override { return *this; }
2157 const AbstractState &getState() const override { return *this; }
2158 /// }
2159
2160 virtual const std::string getAsStr() const override {
2161 return getAssumedAlign() ? ("align<" + std::to_string(getKnownAlign()) +
2162 "-" + std::to_string(getAssumedAlign()) + ">")
2163 : "unknown-align";
2164 }
2165
2166 /// See AAAlign::getAssumedAlign().
2167 unsigned getAssumedAlign() const override { return getAssumed(); }
2168
2169 /// See AAAlign::getKnownAlign().
2170 unsigned getKnownAlign() const override { return getKnown(); }
2171
2172 /// See AbstractAttriubute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002173 void initialize(Attributor &A, InformationCache &InfoCache) override {
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002174 Function &F = getAnchorScope();
2175
2176 unsigned AttrIdx =
2177 getAttrIndex(getManifestPosition(), getArgNo(getAnchoredValue()));
2178
2179 // Already the function has align attribute on return value or argument.
2180 if (F.getAttributes().hasAttribute(AttrIdx, ID))
2181 addKnownBits(F.getAttribute(AttrIdx, ID).getAlignment());
2182 }
2183
2184 /// See AbstractAttribute::getDeducedAttributes
2185 virtual void
2186 getDeducedAttributes(SmallVectorImpl<Attribute> &Attrs) const override {
2187 LLVMContext &Ctx = AnchoredVal.getContext();
2188
2189 Attrs.emplace_back(Attribute::getWithAlignment(Ctx, getAssumedAlign()));
2190 }
2191};
2192
2193/// Align attribute for function return value.
2194struct AAAlignReturned : AAAlignImpl {
2195
Johannes Doerfert007153e2019-08-05 23:26:06 +00002196 AAAlignReturned(Function &F) : AAAlignImpl(F) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002197
2198 /// See AbstractAttribute::getManifestPosition().
2199 virtual ManifestPosition getManifestPosition() const override {
2200 return MP_RETURNED;
2201 }
2202
2203 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002204 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002205};
2206
Johannes Doerfert007153e2019-08-05 23:26:06 +00002207ChangeStatus AAAlignReturned::updateImpl(Attributor &A,
2208 InformationCache &InfoCache) {
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002209 Function &F = getAnchorScope();
2210 auto *AARetValImpl = A.getAAFor<AAReturnedValuesImpl>(*this, F);
Johannes Doerfertd1c37932019-08-04 18:37:38 +00002211 if (!AARetValImpl)
2212 return indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002213
2214 // Currently, align<n> is deduced if alignments in return values are assumed
2215 // as greater than n. We reach pessimistic fixpoint if any of the return value
2216 // wouldn't have align. If no assumed state was used for reasoning, an
2217 // optimistic fixpoint is reached earlier.
2218
2219 base_t BeforeState = getAssumed();
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002220 std::function<bool(Value &, const SmallPtrSetImpl<ReturnInst *> &)> Pred =
2221 [&](Value &RV, const SmallPtrSetImpl<ReturnInst *> &RetInsts) -> bool {
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002222 auto *AlignAA = A.getAAFor<AAAlign>(*this, RV);
2223
2224 if (AlignAA)
2225 takeAssumedMinimum(AlignAA->getAssumedAlign());
2226 else
2227 // Use IR information.
2228 takeAssumedMinimum(RV.getPointerAlignment(
2229 getAnchorScope().getParent()->getDataLayout()));
2230
2231 return isValidState();
2232 };
2233
Johannes Doerfertd1c37932019-08-04 18:37:38 +00002234 if (!AARetValImpl->checkForallReturnedValues(Pred))
2235 return indicatePessimisticFixpoint();
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002236
2237 return (getAssumed() != BeforeState) ? ChangeStatus::CHANGED
2238 : ChangeStatus::UNCHANGED;
2239}
2240
2241/// Align attribute for function argument.
2242struct AAAlignArgument : AAAlignImpl {
2243
Johannes Doerfert007153e2019-08-05 23:26:06 +00002244 AAAlignArgument(Argument &A) : AAAlignImpl(A) {}
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002245
2246 /// See AbstractAttribute::getManifestPosition().
2247 virtual ManifestPosition getManifestPosition() const override {
2248 return MP_ARGUMENT;
2249 }
2250
2251 /// See AbstractAttribute::updateImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002252 virtual ChangeStatus updateImpl(Attributor &A,
2253 InformationCache &InfoCache) override;
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002254};
2255
Johannes Doerfert007153e2019-08-05 23:26:06 +00002256ChangeStatus AAAlignArgument::updateImpl(Attributor &A,
2257 InformationCache &InfoCache) {
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002258
2259 Function &F = getAnchorScope();
2260 Argument &Arg = cast<Argument>(getAnchoredValue());
2261
2262 unsigned ArgNo = Arg.getArgNo();
2263 const DataLayout &DL = F.getParent()->getDataLayout();
2264
2265 auto BeforeState = getAssumed();
2266
2267 // Callback function
2268 std::function<bool(CallSite)> CallSiteCheck = [&](CallSite CS) {
2269 assert(CS && "Sanity check: Call site was not initialized properly!");
2270
2271 auto *AlignAA = A.getAAFor<AAAlign>(*this, *CS.getInstruction(), ArgNo);
2272
2273 // Check that AlignAA is AAAlignCallSiteArgument.
2274 if (AlignAA) {
2275 ImmutableCallSite ICS(&AlignAA->getAnchoredValue());
2276 if (ICS && CS.getInstruction() == ICS.getInstruction()) {
2277 takeAssumedMinimum(AlignAA->getAssumedAlign());
2278 return isValidState();
2279 }
2280 }
2281
2282 Value *V = CS.getArgOperand(ArgNo);
2283 takeAssumedMinimum(V->getPointerAlignment(DL));
2284 return isValidState();
2285 };
2286
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002287 if (!A.checkForAllCallSites(F, CallSiteCheck, true, *this))
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002288 indicatePessimisticFixpoint();
2289
2290 return BeforeState == getAssumed() ? ChangeStatus::UNCHANGED
2291 : ChangeStatus ::CHANGED;
2292}
2293
2294struct AAAlignCallSiteArgument : AAAlignImpl {
2295
2296 /// See AANonNullImpl::AANonNullImpl(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002297 AAAlignCallSiteArgument(CallSite CS, unsigned ArgNo)
2298 : AAAlignImpl(CS.getArgOperand(ArgNo), *CS.getInstruction()),
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002299 ArgNo(ArgNo) {}
2300
2301 /// See AbstractAttribute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002302 void initialize(Attributor &A, InformationCache &InfoCache) override {
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002303 CallSite CS(&getAnchoredValue());
2304 takeKnownMaximum(getAssociatedValue()->getPointerAlignment(
2305 getAnchorScope().getParent()->getDataLayout()));
2306 }
2307
2308 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002309 ChangeStatus updateImpl(Attributor &A, InformationCache &InfoCache) override;
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002310
2311 /// See AbstractAttribute::getManifestPosition().
2312 ManifestPosition getManifestPosition() const override {
2313 return MP_CALL_SITE_ARGUMENT;
2314 };
2315
2316 // Return argument index of associated value.
2317 int getArgNo() const { return ArgNo; }
2318
2319private:
2320 unsigned ArgNo;
2321};
2322
Johannes Doerfert007153e2019-08-05 23:26:06 +00002323ChangeStatus AAAlignCallSiteArgument::updateImpl(Attributor &A,
2324 InformationCache &InfoCache) {
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002325 // NOTE: Never look at the argument of the callee in this method.
2326 // If we do this, "align" is always deduced because of the assumption.
2327
2328 auto BeforeState = getAssumed();
2329
2330 Value &V = *getAssociatedValue();
2331
2332 auto *AlignAA = A.getAAFor<AAAlign>(*this, V);
2333
2334 if (AlignAA)
2335 takeAssumedMinimum(AlignAA->getAssumedAlign());
2336 else
2337 indicatePessimisticFixpoint();
2338
2339 return BeforeState == getAssumed() ? ChangeStatus::UNCHANGED
2340 : ChangeStatus::CHANGED;
2341}
2342
Johannes Doerferte83f3032019-08-05 23:22:05 +00002343/// ------------------ Function No-Return Attribute ----------------------------
2344struct AANoReturnFunction final : public AANoReturn, BooleanState {
2345
Johannes Doerfert007153e2019-08-05 23:26:06 +00002346 AANoReturnFunction(Function &F) : AANoReturn(F) {}
Johannes Doerferte83f3032019-08-05 23:22:05 +00002347
2348 /// See AbstractAttribute::getState()
2349 /// {
2350 AbstractState &getState() override { return *this; }
2351 const AbstractState &getState() const override { return *this; }
2352 /// }
2353
2354 /// Return true if the underlying object is known to never return.
2355 bool isKnownNoReturn() const override { return getKnown(); }
2356
2357 /// Return true if the underlying object is assumed to never return.
2358 bool isAssumedNoReturn() const override { return getAssumed(); }
2359
2360 /// See AbstractAttribute::getManifestPosition().
2361 ManifestPosition getManifestPosition() const override { return MP_FUNCTION; }
2362
2363 /// See AbstractAttribute::getAsStr().
2364 const std::string getAsStr() const override {
2365 return getAssumed() ? "noreturn" : "may-return";
2366 }
2367
2368 /// See AbstractAttribute::initialize(...).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002369 void initialize(Attributor &A, InformationCache &InfoCache) override {
Johannes Doerferte83f3032019-08-05 23:22:05 +00002370 Function &F = getAnchorScope();
2371 if (F.hasFnAttribute(getAttrKind()))
2372 indicateOptimisticFixpoint();
2373 }
2374
2375 /// See AbstractAttribute::updateImpl(Attributor &A).
Johannes Doerfert007153e2019-08-05 23:26:06 +00002376 virtual ChangeStatus updateImpl(Attributor &A,
2377 InformationCache &InfoCache) override {
Johannes Doerferte83f3032019-08-05 23:22:05 +00002378 Function &F = getAnchorScope();
2379
2380 // The map from instruction opcodes to those instructions in the function.
2381 auto &OpcodeInstMap = InfoCache.getOpcodeInstMapForFunction(F);
2382
2383 // Look at all return instructions.
2384 auto &ReturnInsts = OpcodeInstMap[Instruction::Ret];
2385 if (ReturnInsts.empty())
2386 return indicateOptimisticFixpoint();
2387
2388 auto *LivenessAA = A.getAAFor<AAIsDead>(*this, F);
2389 if (!LivenessAA ||
2390 LivenessAA->isLiveInstSet(ReturnInsts.begin(), ReturnInsts.end()))
2391 return indicatePessimisticFixpoint();
2392
2393 return ChangeStatus::UNCHANGED;
2394 }
2395};
2396
Johannes Doerfertaade7822019-06-05 03:02:24 +00002397/// ----------------------------------------------------------------------------
2398/// Attributor
2399/// ----------------------------------------------------------------------------
2400
Hideto Ueno54869ec2019-07-15 06:49:04 +00002401bool Attributor::checkForAllCallSites(Function &F,
2402 std::function<bool(CallSite)> &Pred,
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002403 bool RequireAllCallSites,
2404 AbstractAttribute &AA) {
Hideto Ueno54869ec2019-07-15 06:49:04 +00002405 // We can try to determine information from
2406 // the call sites. However, this is only possible all call sites are known,
2407 // hence the function has internal linkage.
2408 if (RequireAllCallSites && !F.hasInternalLinkage()) {
2409 LLVM_DEBUG(
2410 dbgs()
2411 << "Attributor: Function " << F.getName()
2412 << " has no internal linkage, hence not all call sites are known\n");
2413 return false;
2414 }
2415
2416 for (const Use &U : F.uses()) {
Stefan Stipanovicd0216172019-08-02 21:31:22 +00002417 Instruction *I = cast<Instruction>(U.getUser());
2418 Function *AnchorValue = I->getParent()->getParent();
2419
2420 auto *LivenessAA = getAAFor<AAIsDead>(AA, *AnchorValue);
2421
2422 // Skip dead calls.
2423 if (LivenessAA && LivenessAA->isAssumedDead(I))
2424 continue;
Hideto Ueno54869ec2019-07-15 06:49:04 +00002425
2426 CallSite CS(U.getUser());
Hideto Ueno54869ec2019-07-15 06:49:04 +00002427 if (!CS || !CS.isCallee(&U) || !CS.getCaller()->hasExactDefinition()) {
2428 if (!RequireAllCallSites)
2429 continue;
2430
2431 LLVM_DEBUG(dbgs() << "Attributor: User " << *U.getUser()
2432 << " is an invalid use of " << F.getName() << "\n");
2433 return false;
2434 }
2435
2436 if (Pred(CS))
2437 continue;
2438
2439 LLVM_DEBUG(dbgs() << "Attributor: Call site callback failed for "
2440 << *CS.getInstruction() << "\n");
2441 return false;
2442 }
2443
2444 return true;
2445}
2446
Johannes Doerfert007153e2019-08-05 23:26:06 +00002447ChangeStatus Attributor::run(InformationCache &InfoCache) {
Johannes Doerfertaade7822019-06-05 03:02:24 +00002448 // Initialize all abstract attributes.
2449 for (AbstractAttribute *AA : AllAbstractAttributes)
Johannes Doerfert007153e2019-08-05 23:26:06 +00002450 AA->initialize(*this, InfoCache);
Johannes Doerfertaade7822019-06-05 03:02:24 +00002451
2452 LLVM_DEBUG(dbgs() << "[Attributor] Identified and initialized "
2453 << AllAbstractAttributes.size()
2454 << " abstract attributes.\n");
2455
Stefan Stipanovic53605892019-06-27 11:27:54 +00002456 // Now that all abstract attributes are collected and initialized we start
2457 // the abstract analysis.
Johannes Doerfertaade7822019-06-05 03:02:24 +00002458
2459 unsigned IterationCounter = 1;
2460
2461 SmallVector<AbstractAttribute *, 64> ChangedAAs;
2462 SetVector<AbstractAttribute *> Worklist;
2463 Worklist.insert(AllAbstractAttributes.begin(), AllAbstractAttributes.end());
2464
2465 do {
2466 LLVM_DEBUG(dbgs() << "\n\n[Attributor] #Iteration: " << IterationCounter
2467 << ", Worklist size: " << Worklist.size() << "\n");
2468
2469 // Add all abstract attributes that are potentially dependent on one that
2470 // changed to the work list.
2471 for (AbstractAttribute *ChangedAA : ChangedAAs) {
2472 auto &QuerriedAAs = QueryMap[ChangedAA];
2473 Worklist.insert(QuerriedAAs.begin(), QuerriedAAs.end());
2474 }
2475
2476 // Reset the changed set.
2477 ChangedAAs.clear();
2478
2479 // Update all abstract attribute in the work list and record the ones that
2480 // changed.
2481 for (AbstractAttribute *AA : Worklist)
Johannes Doerfert007153e2019-08-05 23:26:06 +00002482 if (AA->update(*this, InfoCache) == ChangeStatus::CHANGED)
Johannes Doerfertaade7822019-06-05 03:02:24 +00002483 ChangedAAs.push_back(AA);
2484
2485 // Reset the work list and repopulate with the changed abstract attributes.
2486 // Note that dependent ones are added above.
2487 Worklist.clear();
2488 Worklist.insert(ChangedAAs.begin(), ChangedAAs.end());
2489
2490 } while (!Worklist.empty() && ++IterationCounter < MaxFixpointIterations);
2491
2492 LLVM_DEBUG(dbgs() << "\n[Attributor] Fixpoint iteration done after: "
2493 << IterationCounter << "/" << MaxFixpointIterations
2494 << " iterations\n");
2495
2496 bool FinishedAtFixpoint = Worklist.empty();
2497
2498 // Reset abstract arguments not settled in a sound fixpoint by now. This
2499 // happens when we stopped the fixpoint iteration early. Note that only the
2500 // ones marked as "changed" *and* the ones transitively depending on them
2501 // need to be reverted to a pessimistic state. Others might not be in a
2502 // fixpoint state but we can use the optimistic results for them anyway.
2503 SmallPtrSet<AbstractAttribute *, 32> Visited;
2504 for (unsigned u = 0; u < ChangedAAs.size(); u++) {
2505 AbstractAttribute *ChangedAA = ChangedAAs[u];
2506 if (!Visited.insert(ChangedAA).second)
2507 continue;
2508
2509 AbstractState &State = ChangedAA->getState();
2510 if (!State.isAtFixpoint()) {
2511 State.indicatePessimisticFixpoint();
2512
2513 NumAttributesTimedOut++;
2514 }
2515
2516 auto &QuerriedAAs = QueryMap[ChangedAA];
2517 ChangedAAs.append(QuerriedAAs.begin(), QuerriedAAs.end());
2518 }
2519
2520 LLVM_DEBUG({
2521 if (!Visited.empty())
2522 dbgs() << "\n[Attributor] Finalized " << Visited.size()
2523 << " abstract attributes.\n";
2524 });
2525
2526 unsigned NumManifested = 0;
2527 unsigned NumAtFixpoint = 0;
2528 ChangeStatus ManifestChange = ChangeStatus::UNCHANGED;
2529 for (AbstractAttribute *AA : AllAbstractAttributes) {
2530 AbstractState &State = AA->getState();
2531
2532 // If there is not already a fixpoint reached, we can now take the
2533 // optimistic state. This is correct because we enforced a pessimistic one
2534 // on abstract attributes that were transitively dependent on a changed one
2535 // already above.
2536 if (!State.isAtFixpoint())
2537 State.indicateOptimisticFixpoint();
2538
2539 // If the state is invalid, we do not try to manifest it.
2540 if (!State.isValidState())
2541 continue;
2542
2543 // Manifest the state and record if we changed the IR.
2544 ChangeStatus LocalChange = AA->manifest(*this);
2545 ManifestChange = ManifestChange | LocalChange;
2546
2547 NumAtFixpoint++;
2548 NumManifested += (LocalChange == ChangeStatus::CHANGED);
2549 }
2550
2551 (void)NumManifested;
2552 (void)NumAtFixpoint;
2553 LLVM_DEBUG(dbgs() << "\n[Attributor] Manifested " << NumManifested
2554 << " arguments while " << NumAtFixpoint
2555 << " were in a valid fixpoint state\n");
2556
2557 // If verification is requested, we finished this run at a fixpoint, and the
2558 // IR was changed, we re-run the whole fixpoint analysis, starting at
2559 // re-initialization of the arguments. This re-run should not result in an IR
2560 // change. Though, the (virtual) state of attributes at the end of the re-run
2561 // might be more optimistic than the known state or the IR state if the better
2562 // state cannot be manifested.
2563 if (VerifyAttributor && FinishedAtFixpoint &&
2564 ManifestChange == ChangeStatus::CHANGED) {
2565 VerifyAttributor = false;
Johannes Doerfert007153e2019-08-05 23:26:06 +00002566 ChangeStatus VerifyStatus = run(InfoCache);
Johannes Doerfertaade7822019-06-05 03:02:24 +00002567 if (VerifyStatus != ChangeStatus::UNCHANGED)
2568 llvm_unreachable(
2569 "Attributor verification failed, re-run did result in an IR change "
2570 "even after a fixpoint was reached in the original run. (False "
2571 "positives possible!)");
2572 VerifyAttributor = true;
2573 }
2574
2575 NumAttributesManifested += NumManifested;
2576 NumAttributesValidFixpoint += NumAtFixpoint;
2577
2578 return ManifestChange;
2579}
2580
2581void Attributor::identifyDefaultAbstractAttributes(
2582 Function &F, InformationCache &InfoCache,
2583 DenseSet</* Attribute::AttrKind */ unsigned> *Whitelist) {
2584
Johannes Doerfert305b9612019-08-04 18:40:01 +00002585 // Check for dead BasicBlocks in every function.
Johannes Doerfert007153e2019-08-05 23:26:06 +00002586 registerAA(*new AAIsDeadFunction(F));
Johannes Doerfert305b9612019-08-04 18:40:01 +00002587
2588 // Every function might be "will-return".
Johannes Doerfert007153e2019-08-05 23:26:06 +00002589 registerAA(*new AAWillReturnFunction(F));
Johannes Doerfert305b9612019-08-04 18:40:01 +00002590
Stefan Stipanovic53605892019-06-27 11:27:54 +00002591 // Every function can be nounwind.
Johannes Doerfert007153e2019-08-05 23:26:06 +00002592 registerAA(*new AANoUnwindFunction(F));
Stefan Stipanovic53605892019-06-27 11:27:54 +00002593
Stefan Stipanovic06263672019-07-11 21:37:40 +00002594 // Every function might be marked "nosync"
Johannes Doerfert007153e2019-08-05 23:26:06 +00002595 registerAA(*new AANoSyncFunction(F));
Stefan Stipanovic06263672019-07-11 21:37:40 +00002596
Hideto Ueno65bbaf92019-07-12 17:38:51 +00002597 // Every function might be "no-free".
Johannes Doerfert007153e2019-08-05 23:26:06 +00002598 registerAA(*new AANoFreeFunction(F));
Hideto Ueno65bbaf92019-07-12 17:38:51 +00002599
Johannes Doerferte83f3032019-08-05 23:22:05 +00002600 // Every function might be "no-return".
Johannes Doerfert007153e2019-08-05 23:26:06 +00002601 registerAA(*new AANoReturnFunction(F));
Johannes Doerferte83f3032019-08-05 23:22:05 +00002602
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00002603 // Return attributes are only appropriate if the return type is non void.
2604 Type *ReturnType = F.getReturnType();
2605 if (!ReturnType->isVoidTy()) {
2606 // Argument attribute "returned" --- Create only one per function even
2607 // though it is an argument attribute.
2608 if (!Whitelist || Whitelist->count(AAReturnedValues::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002609 registerAA(*new AAReturnedValuesImpl(F));
Hideto Ueno54869ec2019-07-15 06:49:04 +00002610
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002611 if (ReturnType->isPointerTy()) {
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002612 // Every function with pointer return type might be marked align.
2613 if (!Whitelist || Whitelist->count(AAAlignReturned::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002614 registerAA(*new AAAlignReturned(F));
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002615
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002616 // Every function with pointer return type might be marked nonnull.
2617 if (!Whitelist || Whitelist->count(AANonNullReturned::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002618 registerAA(*new AANonNullReturned(F));
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002619
2620 // Every function with pointer return type might be marked noalias.
2621 if (!Whitelist || Whitelist->count(AANoAliasReturned::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002622 registerAA(*new AANoAliasReturned(F));
Hideto Ueno19c07af2019-07-23 08:16:17 +00002623
2624 // Every function with pointer return type might be marked
2625 // dereferenceable.
2626 if (ReturnType->isPointerTy() &&
2627 (!Whitelist || Whitelist->count(AADereferenceableReturned::ID)))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002628 registerAA(*new AADereferenceableReturned(F));
Stefan Stipanovic69ebb022019-07-22 19:36:27 +00002629 }
Hideto Ueno54869ec2019-07-15 06:49:04 +00002630 }
2631
Hideto Ueno54869ec2019-07-15 06:49:04 +00002632 for (Argument &Arg : F.args()) {
Hideto Ueno19c07af2019-07-23 08:16:17 +00002633 if (Arg.getType()->isPointerTy()) {
2634 // Every argument with pointer type might be marked nonnull.
2635 if (!Whitelist || Whitelist->count(AANonNullArgument::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002636 registerAA(*new AANonNullArgument(Arg));
Hideto Ueno19c07af2019-07-23 08:16:17 +00002637
2638 // Every argument with pointer type might be marked dereferenceable.
2639 if (!Whitelist || Whitelist->count(AADereferenceableArgument::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002640 registerAA(*new AADereferenceableArgument(Arg));
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002641
2642 // Every argument with pointer type might be marked align.
2643 if (!Whitelist || Whitelist->count(AAAlignArgument::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002644 registerAA(*new AAAlignArgument(Arg));
Hideto Ueno19c07af2019-07-23 08:16:17 +00002645 }
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00002646 }
2647
Johannes Doerfertaade7822019-06-05 03:02:24 +00002648 // Walk all instructions to find more attribute opportunities and also
2649 // interesting instructions that might be queried by abstract attributes
2650 // during their initialization or update.
2651 auto &ReadOrWriteInsts = InfoCache.FuncRWInstsMap[&F];
2652 auto &InstOpcodeMap = InfoCache.FuncInstOpcodeMap[&F];
2653
2654 for (Instruction &I : instructions(&F)) {
2655 bool IsInterestingOpcode = false;
2656
2657 // To allow easy access to all instructions in a function with a given
2658 // opcode we store them in the InfoCache. As not all opcodes are interesting
2659 // to concrete attributes we only cache the ones that are as identified in
2660 // the following switch.
2661 // Note: There are no concrete attributes now so this is initially empty.
Stefan Stipanovic53605892019-06-27 11:27:54 +00002662 switch (I.getOpcode()) {
2663 default:
2664 assert((!ImmutableCallSite(&I)) && (!isa<CallBase>(&I)) &&
2665 "New call site/base instruction type needs to be known int the "
2666 "attributor.");
2667 break;
2668 case Instruction::Call:
2669 case Instruction::CallBr:
2670 case Instruction::Invoke:
2671 case Instruction::CleanupRet:
2672 case Instruction::CatchSwitch:
2673 case Instruction::Resume:
Johannes Doerfertaccd3e82019-07-08 23:27:20 +00002674 case Instruction::Ret:
Stefan Stipanovic53605892019-06-27 11:27:54 +00002675 IsInterestingOpcode = true;
2676 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00002677 if (IsInterestingOpcode)
2678 InstOpcodeMap[I.getOpcode()].push_back(&I);
2679 if (I.mayReadOrWriteMemory())
2680 ReadOrWriteInsts.push_back(&I);
Hideto Ueno54869ec2019-07-15 06:49:04 +00002681
2682 CallSite CS(&I);
2683 if (CS && CS.getCalledFunction()) {
2684 for (int i = 0, e = CS.getCalledFunction()->arg_size(); i < e; i++) {
2685 if (!CS.getArgument(i)->getType()->isPointerTy())
2686 continue;
2687
2688 // Call site argument attribute "non-null".
Hideto Ueno19c07af2019-07-23 08:16:17 +00002689 if (!Whitelist || Whitelist->count(AANonNullCallSiteArgument::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002690 registerAA(*new AANonNullCallSiteArgument(CS, i), i);
Hideto Ueno19c07af2019-07-23 08:16:17 +00002691
2692 // Call site argument attribute "dereferenceable".
2693 if (!Whitelist ||
2694 Whitelist->count(AADereferenceableCallSiteArgument::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002695 registerAA(*new AADereferenceableCallSiteArgument(CS, i), i);
Hideto Uenoe7bea9b2019-07-28 07:04:01 +00002696
2697 // Call site argument attribute "align".
2698 if (!Whitelist || Whitelist->count(AAAlignCallSiteArgument::ID))
Johannes Doerfert007153e2019-08-05 23:26:06 +00002699 registerAA(*new AAAlignCallSiteArgument(CS, i), i);
Hideto Ueno54869ec2019-07-15 06:49:04 +00002700 }
2701 }
Johannes Doerfertaade7822019-06-05 03:02:24 +00002702 }
2703}
2704
2705/// Helpers to ease debugging through output streams and print calls.
2706///
2707///{
2708raw_ostream &llvm::operator<<(raw_ostream &OS, ChangeStatus S) {
2709 return OS << (S == ChangeStatus::CHANGED ? "changed" : "unchanged");
2710}
2711
2712raw_ostream &llvm::operator<<(raw_ostream &OS,
2713 AbstractAttribute::ManifestPosition AP) {
2714 switch (AP) {
2715 case AbstractAttribute::MP_ARGUMENT:
2716 return OS << "arg";
2717 case AbstractAttribute::MP_CALL_SITE_ARGUMENT:
2718 return OS << "cs_arg";
2719 case AbstractAttribute::MP_FUNCTION:
2720 return OS << "fn";
2721 case AbstractAttribute::MP_RETURNED:
2722 return OS << "fn_ret";
2723 }
2724 llvm_unreachable("Unknown attribute position!");
2725}
2726
2727raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractState &S) {
2728 return OS << (!S.isValidState() ? "top" : (S.isAtFixpoint() ? "fix" : ""));
2729}
2730
2731raw_ostream &llvm::operator<<(raw_ostream &OS, const AbstractAttribute &AA) {
2732 AA.print(OS);
2733 return OS;
2734}
2735
2736void AbstractAttribute::print(raw_ostream &OS) const {
2737 OS << "[" << getManifestPosition() << "][" << getAsStr() << "]["
2738 << AnchoredVal.getName() << "]";
2739}
2740///}
2741
2742/// ----------------------------------------------------------------------------
2743/// Pass (Manager) Boilerplate
2744/// ----------------------------------------------------------------------------
2745
2746static bool runAttributorOnModule(Module &M) {
2747 if (DisableAttributor)
2748 return false;
2749
2750 LLVM_DEBUG(dbgs() << "[Attributor] Run on module with " << M.size()
2751 << " functions.\n");
2752
2753 // Create an Attributor and initially empty information cache that is filled
2754 // while we identify default attribute opportunities.
2755 Attributor A;
2756 InformationCache InfoCache;
2757
2758 for (Function &F : M) {
2759 // TODO: Not all attributes require an exact definition. Find a way to
2760 // enable deduction for some but not all attributes in case the
2761 // definition might be changed at runtime, see also
2762 // http://lists.llvm.org/pipermail/llvm-dev/2018-February/121275.html.
2763 // TODO: We could always determine abstract attributes and if sufficient
2764 // information was found we could duplicate the functions that do not
2765 // have an exact definition.
2766 if (!F.hasExactDefinition()) {
2767 NumFnWithoutExactDefinition++;
2768 continue;
2769 }
2770
2771 // For now we ignore naked and optnone functions.
2772 if (F.hasFnAttribute(Attribute::Naked) ||
2773 F.hasFnAttribute(Attribute::OptimizeNone))
2774 continue;
2775
2776 NumFnWithExactDefinition++;
2777
2778 // Populate the Attributor with abstract attribute opportunities in the
2779 // function and the information cache with IR information.
2780 A.identifyDefaultAbstractAttributes(F, InfoCache);
2781 }
2782
Johannes Doerfert007153e2019-08-05 23:26:06 +00002783 return A.run(InfoCache) == ChangeStatus::CHANGED;
Johannes Doerfertaade7822019-06-05 03:02:24 +00002784}
2785
2786PreservedAnalyses AttributorPass::run(Module &M, ModuleAnalysisManager &AM) {
2787 if (runAttributorOnModule(M)) {
2788 // FIXME: Think about passes we will preserve and add them here.
2789 return PreservedAnalyses::none();
2790 }
2791 return PreservedAnalyses::all();
2792}
2793
2794namespace {
2795
2796struct AttributorLegacyPass : public ModulePass {
2797 static char ID;
2798
2799 AttributorLegacyPass() : ModulePass(ID) {
2800 initializeAttributorLegacyPassPass(*PassRegistry::getPassRegistry());
2801 }
2802
2803 bool runOnModule(Module &M) override {
2804 if (skipModule(M))
2805 return false;
2806 return runAttributorOnModule(M);
2807 }
2808
2809 void getAnalysisUsage(AnalysisUsage &AU) const override {
2810 // FIXME: Think about passes we will preserve and add them here.
2811 AU.setPreservesCFG();
2812 }
2813};
2814
2815} // end anonymous namespace
2816
2817Pass *llvm::createAttributorLegacyPass() { return new AttributorLegacyPass(); }
2818
2819char AttributorLegacyPass::ID = 0;
2820INITIALIZE_PASS_BEGIN(AttributorLegacyPass, "attributor",
2821 "Deduce and propagate attributes", false, false)
2822INITIALIZE_PASS_END(AttributorLegacyPass, "attributor",
2823 "Deduce and propagate attributes", false, false)