LLVM 24.0.0git
FunctionAttrs.cpp
Go to the documentation of this file.
1//===- FunctionAttrs.cpp - Pass which marks functions attributes ----------===//
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/// \file
10/// This file implements interprocedural passes which walk the
11/// call-graph deducing and/or propagating function attributes.
12//
13//===----------------------------------------------------------------------===//
14
16#include "llvm/ADT/ArrayRef.h"
17#include "llvm/ADT/DenseMap.h"
20#include "llvm/ADT/STLExtras.h"
21#include "llvm/ADT/SetVector.h"
24#include "llvm/ADT/Statistic.h"
27#include "llvm/Analysis/CFG.h"
35#include "llvm/IR/Argument.h"
36#include "llvm/IR/Attributes.h"
37#include "llvm/IR/BasicBlock.h"
38#include "llvm/IR/Constant.h"
40#include "llvm/IR/Constants.h"
41#include "llvm/IR/Function.h"
43#include "llvm/IR/InstrTypes.h"
44#include "llvm/IR/Instruction.h"
47#include "llvm/IR/Metadata.h"
49#include "llvm/IR/PassManager.h"
51#include "llvm/IR/Type.h"
52#include "llvm/IR/Use.h"
53#include "llvm/IR/User.h"
54#include "llvm/IR/Value.h"
58#include "llvm/Support/Debug.h"
62#include "llvm/Transforms/IPO.h"
64#include <cassert>
65#include <iterator>
66#include <map>
67#include <optional>
68#include <vector>
69
70using namespace llvm;
71using namespace llvm::PatternMatch;
72
73#define DEBUG_TYPE "function-attrs"
74
75STATISTIC(NumMemoryAttr, "Number of functions with improved memory attribute");
76STATISTIC(NumCapturesNone, "Number of arguments marked captures(none)");
77STATISTIC(NumCapturesPartial, "Number of arguments marked with captures "
78 "attribute other than captures(none)");
79STATISTIC(NumReturned, "Number of arguments marked returned");
80STATISTIC(NumReadNoneArg, "Number of arguments marked readnone");
81STATISTIC(NumReadOnlyArg, "Number of arguments marked readonly");
82STATISTIC(NumWriteOnlyArg, "Number of arguments marked writeonly");
83STATISTIC(NumNoAlias, "Number of function returns marked noalias");
84STATISTIC(NumNonNullReturn, "Number of function returns marked nonnull");
85STATISTIC(NumNoUndefReturn, "Number of function returns marked noundef");
86STATISTIC(NumNoRecurse, "Number of functions marked as norecurse");
87STATISTIC(NumNoUnwind, "Number of functions marked as nounwind");
88STATISTIC(NumNoFree, "Number of functions marked as nofree");
89STATISTIC(NumNoFreeArg, "Number of arguments marked as nofree");
90STATISTIC(NumWillReturn, "Number of functions marked as willreturn");
91STATISTIC(NumNoSync, "Number of functions marked as nosync");
92STATISTIC(NumCold, "Number of functions marked as cold");
93
94STATISTIC(NumThinLinkNoRecurse,
95 "Number of functions marked as norecurse during thinlink");
96STATISTIC(NumThinLinkNoUnwind,
97 "Number of functions marked as nounwind during thinlink");
98
100 "enable-poison-arg-attr-prop", cl::init(true), cl::Hidden,
101 cl::desc("Try to propagate nonnull and nofpclass argument attributes from "
102 "callsites to caller functions."));
103
105 "disable-nounwind-inference", cl::Hidden,
106 cl::desc("Stop inferring nounwind attribute during function-attrs pass"));
107
109 "disable-nofree-inference", cl::Hidden,
110 cl::desc("Stop inferring nofree attribute during function-attrs pass"));
111
113 "disable-thinlto-funcattrs", cl::init(true), cl::Hidden,
114 cl::desc("Don't propagate function-attrs in thinLTO"));
115
117 if (capturesNothing(CI))
118 ++NumCapturesNone;
119 else
120 ++NumCapturesPartial;
121}
122
123namespace {
124
125using SCCNodeSet = SmallSetVector<Function *, 8>;
126
127} // end anonymous namespace
128
130 ModRefInfo MR, AAResults &AAR) {
131 // Ignore accesses to known-invariant or local memory.
132 MR &= AAR.getModRefInfoMask(Loc, /*IgnoreLocal=*/true);
133 if (isNoModRef(MR))
134 return;
135
136 const Value *UO = getUnderlyingObjectAggressive(Loc.Ptr);
137 if (isa<AllocaInst>(UO))
138 return;
139 if (isa<Argument>(UO)) {
141 return;
142 }
143
144 // If it's not an identified object, it might be an argument.
145 if (!isIdentifiedObject(UO))
149}
150
151static void addArgLocs(MemoryEffects &ME, const CallBase *Call,
152 ModRefInfo ArgMR, AAResults &AAR) {
153 for (const Value *Arg : Call->args()) {
154 if (!Arg->getType()->isPtrOrPtrVectorTy())
155 continue;
156
157 addLocAccess(ME,
158 MemoryLocation::getBeforeOrAfter(Arg, Call->getAAMetadata()),
159 ArgMR, AAR);
160 }
161}
162
163/// Returns the memory access attribute for function F using AAR for AA results,
164/// where SCCNodes is the current SCC.
165///
166/// If ThisBody is true, this function may examine the function body and will
167/// return a result pertaining to this copy of the function. If it is false, the
168/// result will be based only on AA results for the function declaration; it
169/// will be assumed that some other (perhaps less optimized) version of the
170/// function may be selected at link time.
171///
172/// The return value is split into two parts: Memory effects that always apply,
173/// and additional memory effects that apply if any of the functions in the SCC
174/// can access argmem.
175static std::pair<MemoryEffects, MemoryEffects>
177 const SCCNodeSet &SCCNodes) {
178 MemoryEffects OrigME = AAR.getMemoryEffects(&F);
179 if (OrigME.doesNotAccessMemory())
180 // Already perfect!
181 return {OrigME, MemoryEffects::none()};
182
183 if (!ThisBody)
184 return {OrigME, MemoryEffects::none()};
185
187 // Additional locations accessed if the SCC accesses argmem.
188 MemoryEffects RecursiveArgME = MemoryEffects::none();
189
190 auto AddNonArgMemoryEffects = [&ME](MemoryEffects InstME) {
191 // Merge instruction memory effects, including inaccessible and errno
192 // memory, but excluding argument memory, which is handled separately.
194
195 // If the instruction accesses captured memory (currently part of "other")
196 // and an argument is captured (currently not tracked), then it may also
197 // access argument memory.
198 ModRefInfo OtherMR = InstME.getModRef(IRMemLocation::Other);
199 ME |= MemoryEffects::argMemOnly(OtherMR);
200 };
201
202 // Inalloca and preallocated arguments are always clobbered by the call.
203 if (F.getAttributes().hasAttrSomewhere(Attribute::InAlloca) ||
204 F.getAttributes().hasAttrSomewhere(Attribute::Preallocated))
206
207 // Scan the function body for instructions that may read or write memory.
208 for (Instruction &I : instructions(F)) {
209 // Some instructions can be ignored even if they read or write memory.
210 // Detect these now, skipping to the next instruction if one is found.
211 if (auto *Call = dyn_cast<CallBase>(&I)) {
212 // We can optimistically ignore calls to functions in the same SCC, with
213 // two caveats:
214 // * Calls with operand bundles may have additional effects.
215 // * Argument memory accesses may imply additional effects depending on
216 // what the argument location is.
217 if (!Call->hasOperandBundles() && Call->getCalledFunction() &&
218 SCCNodes.count(Call->getCalledFunction())) {
219 // Keep track of which additional locations are accessed if the SCC
220 // turns out to access argmem.
221 addArgLocs(RecursiveArgME, Call, ModRefInfo::ModRef, AAR);
222 continue;
223 }
224
225 MemoryEffects CallME = AAR.getMemoryEffects(Call);
226
227 // If the call doesn't access memory, we're done.
228 if (CallME.doesNotAccessMemory())
229 continue;
230
231 // A pseudo probe call shouldn't change any function attribute since it
232 // doesn't translate to a real instruction. It comes with a memory access
233 // tag to prevent itself being removed by optimizations and not block
234 // other instructions being optimized.
236 continue;
237
238 AddNonArgMemoryEffects(CallME);
239
240 // Check whether all pointer arguments point to local memory, and
241 // ignore calls that only access local memory.
243 if (ArgMR != ModRefInfo::NoModRef)
244 addArgLocs(ME, Call, ArgMR, AAR);
245 continue;
246 }
247
248 MemoryEffects InstME = I.getMemoryEffects();
249 if (InstME.doesNotAccessMemory())
250 continue;
251
252 std::optional<MemoryLocation> Loc = MemoryLocation::getOrNone(&I);
253 if (!Loc) {
254 // If no location is known, conservatively assume anything can be
255 // accessed.
256 ME |= MemoryEffects(InstME.getModRef());
257 continue;
258 }
259
260 AddNonArgMemoryEffects(InstME);
262 }
263
264 return {OrigME & ME, RecursiveArgME};
265}
266
268 AAResults &AAR) {
269 return checkFunctionMemoryAccess(F, /*ThisBody=*/true, AAR, {}).first;
270}
271
272/// Deduce readonly/readnone/writeonly attributes for the SCC.
273template <typename AARGetterT>
274static void addMemoryAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter,
277 MemoryEffects RecursiveArgME = MemoryEffects::none();
278 for (Function *F : SCCNodes) {
279 // Call the callable parameter to look up AA results for this function.
280 AAResults &AAR = AARGetter(*F);
281 // Non-exact function definitions may not be selected at link time, and an
282 // alternative version that writes to memory may be selected. See the
283 // comment on GlobalValue::isDefinitionExact for more details.
284 auto [FnME, FnRecursiveArgME] =
285 checkFunctionMemoryAccess(*F, F->hasExactDefinition(), AAR, SCCNodes);
286 ME |= FnME;
287 RecursiveArgME |= FnRecursiveArgME;
288 // Reached bottom of the lattice, we will not be able to improve the result.
289 if (ME == MemoryEffects::unknown())
290 return;
291 }
292
293 // If the SCC accesses argmem, add recursive accesses resulting from that.
295 if (ArgMR != ModRefInfo::NoModRef)
296 ME |= RecursiveArgME & MemoryEffects(ArgMR);
297
298 for (Function *F : SCCNodes) {
299 MemoryEffects OldME = F->getMemoryEffects();
300 MemoryEffects NewME = ME & OldME;
301 if (NewME != OldME) {
302 ++NumMemoryAttr;
303 F->setMemoryEffects(NewME);
304 // Remove conflicting writable attributes.
306 for (Argument &A : F->args())
307 A.removeAttr(Attribute::Writable);
308 Changed.insert(F);
309 }
310 }
311}
312
313// Compute definitive function attributes for a function taking into account
314// prevailing definitions and linkage types
316 ValueInfo VI,
317 DenseMap<ValueInfo, FunctionSummary *> &CachedPrevailingSummary,
319 IsPrevailing) {
320
321 auto [It, Inserted] = CachedPrevailingSummary.try_emplace(VI);
322 if (!Inserted)
323 return It->second;
324
325 /// At this point, prevailing symbols have been resolved. The following leads
326 /// to returning a conservative result:
327 /// - Multiple instances with local linkage. Normally local linkage would be
328 /// unique per module
329 /// as the GUID includes the module path. We could have a guid alias if
330 /// there wasn't any distinguishing path when each file was compiled, but
331 /// that should be rare so we'll punt on those.
332
333 /// These next 2 cases should not happen and will assert:
334 /// - Multiple instances with external linkage. This should be caught in
335 /// symbol resolution
336 /// - Non-existent FunctionSummary for Aliasee. This presents a hole in our
337 /// knowledge meaning we have to go conservative.
338
339 /// Otherwise, we calculate attributes for a function as:
340 /// 1. If we have a local linkage, take its attributes. If there's somehow
341 /// multiple, bail and go conservative.
342 /// 2. If we have an external/WeakODR/LinkOnceODR linkage check that it is
343 /// prevailing, take its attributes.
344 /// 3. If we have a Weak/LinkOnce linkage the copies can have semantic
345 /// differences. However, if the prevailing copy is known it will be used
346 /// so take its attributes. If the prevailing copy is in a native file
347 /// all IR copies will be dead and propagation will go conservative.
348 /// 4. AvailableExternally summaries without a prevailing copy are known to
349 /// occur in a couple of circumstances:
350 /// a. An internal function gets imported due to its caller getting
351 /// imported, it becomes AvailableExternally but no prevailing
352 /// definition exists. Because it has to get imported along with its
353 /// caller the attributes will be captured by propagating on its
354 /// caller.
355 /// b. C++11 [temp.explicit]p10 can generate AvailableExternally
356 /// definitions of explicitly instanced template declarations
357 /// for inlining which are ultimately dropped from the TU. Since this
358 /// is localized to the TU the attributes will have already made it to
359 /// the callers.
360 /// These are edge cases and already captured by their callers so we
361 /// ignore these for now. If they become relevant to optimize in the
362 /// future this can be revisited.
363 /// 5. Otherwise, go conservative.
364
365 FunctionSummary *Local = nullptr;
366 FunctionSummary *Prevailing = nullptr;
367
368 for (const auto &GVS : VI.getSummaryList()) {
369 if (!GVS->isLive())
370 continue;
371
372 FunctionSummary *FS = dyn_cast<FunctionSummary>(GVS->getBaseObject());
373 // Virtual and Unknown (e.g. indirect) calls require going conservative
374 if (!FS || FS->fflags().HasUnknownCall)
375 return nullptr;
376
377 const auto &Linkage = GVS->linkage();
379 if (Local) {
381 dbgs()
382 << "ThinLTO FunctionAttrs: Multiple Local Linkage, bailing on "
383 "function "
384 << VI.name() << " from " << FS->modulePath() << ". Previous module "
385 << Local->modulePath() << "\n");
386 return nullptr;
387 }
388 Local = FS;
390 assert(IsPrevailing(VI.getGUID(), GVS.get()) || GVS->wasPromoted());
391 Prevailing = FS;
392 break;
397 if (IsPrevailing(VI.getGUID(), GVS.get())) {
398 Prevailing = FS;
399 break;
400 }
402 // TODO: Handle these cases if they become meaningful
403 continue;
404 }
405 }
406
407 auto &CPS = CachedPrevailingSummary[VI];
408 if (Local) {
409 assert(!Prevailing);
410 CPS = Local;
411 } else if (Prevailing) {
412 assert(!Local);
413 CPS = Prevailing;
414 }
415
416 return CPS;
417}
418
420 ModuleSummaryIndex &Index,
422 IsPrevailing) {
423 // TODO: implement addNoAliasAttrs once
424 // there's more information about the return type in the summary
426 return false;
427
428 DenseMap<ValueInfo, FunctionSummary *> CachedPrevailingSummary;
429 bool Changed = false;
430
431 auto PropagateAttributes = [&](std::vector<ValueInfo> &SCCNodes) {
432 // Assume we can propagate unless we discover otherwise
433 FunctionSummary::FFlags InferredFlags;
434 InferredFlags.NoRecurse = (SCCNodes.size() == 1);
435 InferredFlags.NoUnwind = true;
436
437 for (auto &V : SCCNodes) {
438 FunctionSummary *CallerSummary =
439 calculatePrevailingSummary(V, CachedPrevailingSummary, IsPrevailing);
440
441 // Function summaries can fail to contain information such as declarations
442 if (!CallerSummary)
443 return;
444
445 if (CallerSummary->fflags().MayThrow)
446 InferredFlags.NoUnwind = false;
447
448 for (const auto &Callee : CallerSummary->calls()) {
450 Callee.first, CachedPrevailingSummary, IsPrevailing);
451
452 if (!CalleeSummary)
453 return;
454
455 if (!CalleeSummary->fflags().NoRecurse)
456 InferredFlags.NoRecurse = false;
457
458 if (!CalleeSummary->fflags().NoUnwind)
459 InferredFlags.NoUnwind = false;
460
461 if (!InferredFlags.NoUnwind && !InferredFlags.NoRecurse)
462 break;
463 }
464 }
465
466 if (InferredFlags.NoUnwind || InferredFlags.NoRecurse) {
467 Changed = true;
468 for (auto &V : SCCNodes) {
469 if (InferredFlags.NoRecurse) {
470 LLVM_DEBUG(dbgs() << "ThinLTO FunctionAttrs: Propagated NoRecurse to "
471 << V.name() << "\n");
472 ++NumThinLinkNoRecurse;
473 }
474
475 if (InferredFlags.NoUnwind) {
476 LLVM_DEBUG(dbgs() << "ThinLTO FunctionAttrs: Propagated NoUnwind to "
477 << V.name() << "\n");
478 ++NumThinLinkNoUnwind;
479 }
480
481 for (const auto &S : V.getSummaryList()) {
482 if (auto *FS = dyn_cast<FunctionSummary>(S.get())) {
483 if (InferredFlags.NoRecurse)
484 FS->setNoRecurse();
485
486 if (InferredFlags.NoUnwind)
487 FS->setNoUnwind();
488 }
489 }
490 }
491 }
492 };
493
494 // Call propagation functions on each SCC in the Index
495 for (scc_iterator<ModuleSummaryIndex *> I = scc_begin(&Index); !I.isAtEnd();
496 ++I) {
497 std::vector<ValueInfo> Nodes(*I);
498 PropagateAttributes(Nodes);
499 }
500 return Changed;
501}
502
503namespace {
504
505/// For a given pointer Argument, this retains a list of Arguments of functions
506/// in the same SCC that the pointer data flows into. We use this to build an
507/// SCC of the arguments.
508struct ArgumentGraphNode {
509 Argument *Definition;
510 /// CaptureComponents for this argument, excluding captures via Uses.
511 /// We don't distinguish between other/return captures here.
514};
515
516class ArgumentGraph {
517 // We store pointers to ArgumentGraphNode objects, so it's important that
518 // that they not move around upon insert.
519 using ArgumentMapTy = std::map<Argument *, ArgumentGraphNode>;
520
521 ArgumentMapTy ArgumentMap;
522
523 // There is no root node for the argument graph, in fact:
524 // void f(int *x, int *y) { if (...) f(x, y); }
525 // is an example where the graph is disconnected. The SCCIterator requires a
526 // single entry point, so we maintain a fake ("synthetic") root node that
527 // uses every node. Because the graph is directed and nothing points into
528 // the root, it will not participate in any SCCs (except for its own).
529 ArgumentGraphNode SyntheticRoot;
530
531public:
532 ArgumentGraph() { SyntheticRoot.Definition = nullptr; }
533
535
536 iterator begin() { return SyntheticRoot.Uses.begin(); }
537 iterator end() { return SyntheticRoot.Uses.end(); }
538 ArgumentGraphNode *getEntryNode() { return &SyntheticRoot; }
539
540 ArgumentGraphNode *operator[](Argument *A) {
541 ArgumentGraphNode &Node = ArgumentMap[A];
542 Node.Definition = A;
543 SyntheticRoot.Uses.push_back(&Node);
544 return &Node;
545 }
546};
547
548/// This tracker checks whether callees are in the SCC, and if so it does not
549/// consider that a capture, instead adding it to the "Uses" list and
550/// continuing with the analysis.
551struct ArgumentUsesTracker : public CaptureTracker {
552 ArgumentUsesTracker(const SCCNodeSet &SCCNodes) : SCCNodes(SCCNodes) {}
553
554 void tooManyUses() override { CI = CaptureInfo::all(); }
555
556 Action captured(const Use *U, UseCaptureInfo UseCI) override {
557 if (updateCaptureInfo(U, UseCI.UseCC)) {
558 // Don't bother continuing if we already capture everything.
559 if (capturesAll(CI.getOtherComponents()))
560 return Stop;
561 return Continue;
562 }
563
564 // For SCC argument tracking, we're not going to analyze other/ret
565 // components separately, so don't follow the return value.
566 return ContinueIgnoringReturn;
567 }
568
569 bool updateCaptureInfo(const Use *U, CaptureComponents CC) {
570 CallBase *CB = dyn_cast<CallBase>(U->getUser());
571 if (!CB) {
572 if (isa<ReturnInst>(U->getUser()))
573 CI |= CaptureInfo::retOnly(CC);
574 else
575 // Conservatively assume that the captured value might make its way
576 // into the return value as well. This could be made more precise.
577 CI |= CaptureInfo(CC);
578 return true;
579 }
580
582 if (!F || !F->hasExactDefinition() || !SCCNodes.count(F)) {
583 CI |= CaptureInfo(CC);
584 return true;
585 }
586
587 assert(!CB->isCallee(U) && "callee operand reported captured?");
588 const unsigned UseIndex = CB->getDataOperandNo(U);
589 if (UseIndex >= CB->arg_size()) {
590 // Data operand, but not a argument operand -- must be a bundle operand
591 assert(CB->hasOperandBundles() && "Must be!");
592
593 // CaptureTracking told us that we're being captured by an operand bundle
594 // use. In this case it does not matter if the callee is within our SCC
595 // or not -- we've been captured in some unknown way, and we have to be
596 // conservative.
597 CI |= CaptureInfo(CC);
598 return true;
599 }
600
601 if (UseIndex >= F->arg_size()) {
602 assert(F->isVarArg() && "More params than args in non-varargs call");
603 CI |= CaptureInfo(CC);
604 return true;
605 }
606
607 // TODO(captures): Could improve precision by remembering maximum
608 // capture components for the argument.
609 Uses.push_back(&*std::next(F->arg_begin(), UseIndex));
610 return false;
611 }
612
613 // Does not include potential captures via Uses in the SCC.
614 CaptureInfo CI = CaptureInfo::none();
615
616 // Uses within our SCC.
618
619 const SCCNodeSet &SCCNodes;
620};
621
622/// A struct of argument use: a Use and the offset it accesses. This struct
623/// is to track uses inside function via GEP. If GEP has a non-constant index,
624/// the Offset field is nullopt.
625struct ArgumentUse {
626 Use *U;
627 std::optional<int64_t> Offset;
628};
629
630/// A struct of argument access info. "Unknown" accesses are the cases like
631/// unrecognized instructions, instructions that have more than one use of
632/// the argument, or volatile memory accesses. "WriteWithSideEffect" are call
633/// instructions that not only write an argument but also capture it.
634struct ArgumentAccessInfo {
635 enum class AccessType : uint8_t { Write, WriteWithSideEffect, Read, Unknown };
636 AccessType ArgAccessType;
637 ConstantRangeList AccessRanges;
638};
639
640/// A struct to wrap the argument use info per block.
641struct UsesPerBlockInfo {
642 SmallDenseMap<Instruction *, ArgumentAccessInfo, 4> Insts;
643 bool HasWrites = false;
644 bool HasUnknownAccess = false;
645};
646
647/// A struct to summarize the argument use info in a function.
648struct ArgumentUsesSummary {
649 bool HasAnyWrite = false;
650 bool HasWriteOutsideEntryBB = false;
651 SmallDenseMap<const BasicBlock *, UsesPerBlockInfo, 16> UsesPerBlock;
652};
653
654ArgumentAccessInfo getArgumentAccessInfo(const Instruction *I,
655 const ArgumentUse &ArgUse,
656 const DataLayout &DL) {
657 auto GetTypeAccessRange =
658 [&DL](Type *Ty,
659 std::optional<int64_t> Offset) -> std::optional<ConstantRange> {
660 auto TypeSize = DL.getTypeStoreSize(Ty);
661 if (!TypeSize.isScalable() && Offset) {
662 int64_t Size = TypeSize.getFixedValue();
663 APInt Low(64, *Offset, true);
664 bool Overflow;
665 APInt High = Low.sadd_ov(APInt(64, Size, true), Overflow);
666 // Bail if the range overflows signed 64-bit int.
667 if (Overflow)
668 return std::nullopt;
669 return ConstantRange(Low, High);
670 }
671 return std::nullopt;
672 };
673 auto GetConstantIntRange =
674 [](Value *Length,
675 std::optional<int64_t> Offset) -> std::optional<ConstantRange> {
676 auto *ConstantLength = dyn_cast<ConstantInt>(Length);
677 if (ConstantLength && Offset) {
678 int64_t Len = ConstantLength->getSExtValue();
679
680 // Reject zero or negative lengths
681 if (Len <= 0)
682 return std::nullopt;
683
684 APInt Low(64, *Offset, true);
685 bool Overflow;
686 APInt High = Low.sadd_ov(APInt(64, Len, true), Overflow);
687 if (Overflow)
688 return std::nullopt;
689
690 return ConstantRange(Low, High);
691 }
692 return std::nullopt;
693 };
694
695 if (auto *SI = dyn_cast<StoreInst>(I)) {
696 if (SI->isSimple() && &SI->getOperandUse(1) == ArgUse.U) {
697 // Get the fixed type size of "SI". Since the access range of a write
698 // will be unioned, if "SI" doesn't have a fixed type size, we just set
699 // the access range to empty.
700 ConstantRangeList AccessRanges;
701 if (auto TypeAccessRange =
702 GetTypeAccessRange(SI->getAccessType(), ArgUse.Offset))
703 AccessRanges.insert(*TypeAccessRange);
704 return {ArgumentAccessInfo::AccessType::Write, std::move(AccessRanges)};
705 }
706 } else if (auto *LI = dyn_cast<LoadInst>(I)) {
707 if (LI->isSimple()) {
708 assert(&LI->getOperandUse(0) == ArgUse.U);
709 // Get the fixed type size of "LI". Different from Write, if "LI"
710 // doesn't have a fixed type size, we conservatively set as a clobber
711 // with an empty access range.
712 if (auto TypeAccessRange =
713 GetTypeAccessRange(LI->getAccessType(), ArgUse.Offset))
714 return {ArgumentAccessInfo::AccessType::Read, {*TypeAccessRange}};
715 }
716 } else if (auto *MemSet = dyn_cast<MemSetInst>(I)) {
717 if (!MemSet->isVolatile()) {
718 ConstantRangeList AccessRanges;
719 if (auto AccessRange =
720 GetConstantIntRange(MemSet->getLength(), ArgUse.Offset))
721 AccessRanges.insert(*AccessRange);
722 return {ArgumentAccessInfo::AccessType::Write, AccessRanges};
723 }
724 } else if (auto *MTI = dyn_cast<MemTransferInst>(I)) {
725 if (!MTI->isVolatile()) {
726 if (&MTI->getOperandUse(0) == ArgUse.U) {
727 ConstantRangeList AccessRanges;
728 if (auto AccessRange =
729 GetConstantIntRange(MTI->getLength(), ArgUse.Offset))
730 AccessRanges.insert(*AccessRange);
731 return {ArgumentAccessInfo::AccessType::Write, AccessRanges};
732 } else if (&MTI->getOperandUse(1) == ArgUse.U) {
733 if (auto AccessRange =
734 GetConstantIntRange(MTI->getLength(), ArgUse.Offset))
735 return {ArgumentAccessInfo::AccessType::Read, {*AccessRange}};
736 }
737 }
738 } else if (auto *CB = dyn_cast<CallBase>(I)) {
739 if (CB->isArgOperand(ArgUse.U) &&
740 !CB->isByValArgument(CB->getArgOperandNo(ArgUse.U))) {
741 unsigned ArgNo = CB->getArgOperandNo(ArgUse.U);
742 bool IsInitialize = CB->paramHasAttr(ArgNo, Attribute::Initializes);
743 if (IsInitialize && ArgUse.Offset) {
744 // Argument is a Write when parameter is writeonly/readnone
745 // and nocapture. Otherwise, it's a WriteWithSideEffect.
746 auto Access = CB->onlyWritesMemory(ArgNo) && CB->doesNotCapture(ArgNo)
747 ? ArgumentAccessInfo::AccessType::Write
748 : ArgumentAccessInfo::AccessType::WriteWithSideEffect;
749 ConstantRangeList AccessRanges;
750 Attribute Attr = CB->getParamAttr(ArgNo, Attribute::Initializes);
752 for (ConstantRange &CR : CBCRL)
753 AccessRanges.insert(ConstantRange(CR.getLower() + *ArgUse.Offset,
754 CR.getUpper() + *ArgUse.Offset));
755 return {Access, AccessRanges};
756 }
757 }
758 }
759 // Other unrecognized instructions are considered as unknown.
760 return {ArgumentAccessInfo::AccessType::Unknown, {}};
761}
762
763// Collect the uses of argument "A" in "F".
764ArgumentUsesSummary collectArgumentUsesPerBlock(Argument &A, Function &F) {
765 auto &DL = F.getParent()->getDataLayout();
766 unsigned PointerSize =
767 DL.getIndexSizeInBits(A.getType()->getPointerAddressSpace());
768 ArgumentUsesSummary Result;
769
770 BasicBlock &EntryBB = F.getEntryBlock();
772 for (Use &U : A.uses())
773 Worklist.push_back({&U, 0});
774
775 // Update "UsesPerBlock" with the block of "I" as key and "Info" as value.
776 // Return true if the block of "I" has write accesses after updating.
777 auto UpdateUseInfo = [&Result](Instruction *I, ArgumentAccessInfo Info) {
778 auto *BB = I->getParent();
779 auto &BBInfo = Result.UsesPerBlock[BB];
780 auto [It, Inserted] = BBInfo.Insts.try_emplace(I);
781 auto &IInfo = It->second;
782
783 // Instructions that have more than one use of the argument are considered
784 // as clobbers.
785 if (!Inserted) {
786 IInfo = {ArgumentAccessInfo::AccessType::Unknown, {}};
787 BBInfo.HasUnknownAccess = true;
788 return false;
789 }
790
791 IInfo = std::move(Info);
792 BBInfo.HasUnknownAccess |=
793 IInfo.ArgAccessType == ArgumentAccessInfo::AccessType::Unknown;
794 bool InfoHasWrites =
795 (IInfo.ArgAccessType == ArgumentAccessInfo::AccessType::Write ||
796 IInfo.ArgAccessType ==
797 ArgumentAccessInfo::AccessType::WriteWithSideEffect) &&
798 !IInfo.AccessRanges.empty();
799 BBInfo.HasWrites |= InfoHasWrites;
800 return InfoHasWrites;
801 };
802
803 // No need for a visited set because we don't look through phis, so there are
804 // no cycles.
805 while (!Worklist.empty()) {
806 ArgumentUse ArgUse = Worklist.pop_back_val();
807 User *U = ArgUse.U->getUser();
808 // Add GEP uses to worklist.
809 // If the GEP is not a constant GEP, set the ArgumentUse::Offset to nullopt.
810 if (auto *GEP = dyn_cast<GEPOperator>(U)) {
811 std::optional<int64_t> NewOffset = std::nullopt;
812 if (ArgUse.Offset) {
813 APInt Offset(PointerSize, 0);
814 if (GEP->accumulateConstantOffset(DL, Offset))
815 NewOffset = *ArgUse.Offset + Offset.getSExtValue();
816 }
817 for (Use &U : GEP->uses())
818 Worklist.push_back({&U, NewOffset});
819 continue;
820 }
821
822 auto *I = cast<Instruction>(U);
823 bool HasWrite = UpdateUseInfo(I, getArgumentAccessInfo(I, ArgUse, DL));
824
825 Result.HasAnyWrite |= HasWrite;
826
827 if (HasWrite && I->getParent() != &EntryBB)
828 Result.HasWriteOutsideEntryBB = true;
829 }
830 return Result;
831}
832
833} // end anonymous namespace
834
835namespace llvm {
836
837template <> struct GraphTraits<ArgumentGraphNode *> {
838 using NodeRef = ArgumentGraphNode *;
840
841 static NodeRef getEntryNode(NodeRef A) { return A; }
842 static ChildIteratorType child_begin(NodeRef N) { return N->Uses.begin(); }
843 static ChildIteratorType child_end(NodeRef N) { return N->Uses.end(); }
844};
845
846template <>
847struct GraphTraits<ArgumentGraph *> : public GraphTraits<ArgumentGraphNode *> {
848 static NodeRef getEntryNode(ArgumentGraph *AG) { return AG->getEntryNode(); }
849
850 static ChildIteratorType nodes_begin(ArgumentGraph *AG) {
851 return AG->begin();
852 }
853
854 static ChildIteratorType nodes_end(ArgumentGraph *AG) { return AG->end(); }
855};
856
858 bool IsRead = false;
859 bool IsWrite = false;
860 bool IsFree = false;
861
862 static ArgAccessProperties all() { return {true, true, true}; }
863
864 bool hasAll() const { return IsRead && IsWrite && IsFree; }
865
867 IsRead |= Other.IsRead;
868 IsWrite |= Other.IsWrite;
869 IsFree |= Other.IsFree;
870 return *this;
871 }
872};
873
874} // end namespace llvm
875
876/// Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone.
879 const SmallPtrSet<Argument *, 8> &SCCNodes) {
880 SmallVector<Use *, 32> Worklist;
882
883 // inalloca arguments are always clobbered by the call.
884 if (A->hasInAllocaAttr() || A->hasPreallocatedAttr())
886
888
889 for (Use &U : A->uses()) {
890 Visited.insert(&U);
891 Worklist.push_back(&U);
892 }
893
894 while (!Worklist.empty()) {
895 if (Props.hasAll())
896 // No point in searching further..
897 return Props;
898
899 Use *U = Worklist.pop_back_val();
900 Instruction *I = cast<Instruction>(U->getUser());
901 if (isa<ReturnInst>(I))
902 continue;
903
905
906 // FIXME: This should really be part of CaptureTracking, but keep it here
907 // for now due to interference with isEscapeSource().
908 if (auto *CB = dyn_cast<CallBase>(I))
909 if (CB->onlyReadsMemory())
910 Info.UseCC &= CaptureComponents::Address;
911
912 if (capturesAnyProvenance(Info.UseCC)) {
913 // Handle indirect access via captured provenance.
914 if (!capturesReadProvenanceOnly(Info.UseCC))
916 Props.IsRead = true;
917 }
918
919 if (capturesAnyProvenance(Info.ResultCC)) {
920 for (Use &UU : I->uses())
921 if (Visited.insert(&UU).second)
922 Worklist.push_back(&UU);
923 }
924
925 if (auto *CB = dyn_cast<CallBase>(I)) {
926 if (CB->isCallee(U)) {
927 Props.IsRead = true;
928 continue;
929 }
930
931 // Given we've explicitly handled the callee operand above, what's left
932 // must be a data operand (e.g. argument or operand bundle)
933 const unsigned UseIndex = CB->getDataOperandNo(U);
934
935 ModRefInfo ArgMR =
937 if (isNoModRef(ArgMR))
938 continue;
939
940 if (Function *F = CB->getCalledFunction())
941 if (CB->isArgOperand(U) && UseIndex < F->arg_size() &&
942 SCCNodes.count(F->getArg(UseIndex)))
943 // This is an argument which is part of the speculative SCC. Note
944 // that only operands corresponding to formal arguments of the callee
945 // can participate in the speculation.
946 continue;
947
948 // The accessors used on call site here do the right thing for calls and
949 // invokes with operand bundles.
950 if (isRefSet(ArgMR) && !CB->onlyWritesMemory(UseIndex))
951 Props.IsRead = true;
952 if (isModSet(ArgMR) && !CB->onlyReadsMemory(UseIndex)) {
953 Props.IsWrite = true;
954 if (CB->isArgOperand(U) && !CB->hasFnAttr(Attribute::NoFree) &&
955 !CB->paramHasAttr(UseIndex, Attribute::NoFree) &&
956 !CB->paramHasAttr(UseIndex, Attribute::NoFreeObj))
957 Props.IsFree = true;
958 }
959 } else {
960 // Ignore value operand for stores.
961 if (isa<StoreInst>(I) &&
962 StoreInst::getPointerOperandIndex() != U->getOperandNo())
963 continue;
964
965 Props.IsRead |= I->mayReadFromMemory();
966 Props.IsWrite |= I->mayWriteToMemory();
967 }
968 }
969
970 return Props;
971}
972
973/// Deduce returned attributes for the SCC.
974static void addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes,
976 // Check each function in turn, determining if an argument is always returned.
977 for (Function *F : SCCNodes) {
978 // We can infer and propagate function attributes only when we know that the
979 // definition we'll get at link time is *exactly* the definition we see now.
980 // For more details, see GlobalValue::mayBeDerefined.
981 if (!F->hasExactDefinition())
982 continue;
983
984 if (F->getReturnType()->isVoidTy())
985 continue;
986
987 // There is nothing to do if an argument is already marked as 'returned'.
988 if (F->getAttributes().hasAttrSomewhere(Attribute::Returned))
989 continue;
990
991 auto FindRetArg = [&]() -> Argument * {
992 Argument *RetArg = nullptr;
993 for (BasicBlock &BB : *F)
994 if (auto *Ret = dyn_cast<ReturnInst>(BB.getTerminator())) {
995 // Note that stripPointerCasts should look through functions with
996 // returned arguments.
997 auto *RetVal =
998 dyn_cast<Argument>(Ret->getReturnValue()->stripPointerCasts());
999 if (!RetVal || RetVal->getType() != F->getReturnType())
1000 return nullptr;
1001
1002 if (!RetArg)
1003 RetArg = RetVal;
1004 else if (RetArg != RetVal)
1005 return nullptr;
1006 }
1007
1008 return RetArg;
1009 };
1010
1011 if (Argument *RetArg = FindRetArg()) {
1012 RetArg->addAttr(Attribute::Returned);
1013 ++NumReturned;
1014 Changed.insert(F);
1015 }
1016 }
1017}
1018
1019/// If a callsite has arguments that are also arguments to the parent function,
1020/// try to propagate attributes from the callsite's arguments to the parent's
1021/// arguments. This may be important because inlining can cause information loss
1022/// when attribute knowledge disappears with the inlined call.
1025 return false;
1026
1027 bool Changed = false;
1028
1029 // For an argument attribute to transfer from a callsite to the parent, the
1030 // call must be guaranteed to execute every time the parent is called.
1031 // Conservatively, just check for calls in the entry block that are guaranteed
1032 // to execute.
1033 // TODO: This could be enhanced by testing if the callsite post-dominates the
1034 // entry block or by doing simple forward walks or backward walks to the
1035 // callsite.
1036 BasicBlock &Entry = F.getEntryBlock();
1037 for (Instruction &I : Entry) {
1038 if (auto *CB = dyn_cast<CallBase>(&I)) {
1039 if (auto *CalledFunc = CB->getCalledFunction()) {
1040 for (auto &CSArg : CalledFunc->args()) {
1041 unsigned ArgNo = CSArg.getArgNo();
1042 auto *FArg = dyn_cast<Argument>(CB->getArgOperand(ArgNo));
1043 if (!FArg)
1044 continue;
1045
1046 if (CSArg.hasNonNullAttr(/*AllowUndefOrPoison=*/false)) {
1047 // If the non-null callsite argument operand is an argument to 'F'
1048 // (the caller) and the call is guaranteed to execute, then the
1049 // value must be non-null throughout 'F'.
1050 if (!FArg->hasNonNullAttr()) {
1051 FArg->addAttr(Attribute::NonNull);
1052 Changed = true;
1053 }
1054 } else if (FPClassTest CSNoFPClass = CB->getParamNoFPClass(ArgNo);
1055 CSNoFPClass != fcNone &&
1056 CB->paramHasAttr(ArgNo, Attribute::NoUndef)) {
1057 FPClassTest ArgNoFPClass = FArg->getNoFPClass();
1058
1059 if ((CSNoFPClass | ArgNoFPClass) != ArgNoFPClass) {
1060 FArg->addAttr(Attribute::getWithNoFPClass(
1061 FArg->getContext(), CSNoFPClass | ArgNoFPClass));
1062 Changed = true;
1063 }
1064 }
1065 }
1066 }
1067 }
1069 break;
1070 }
1071
1072 return Changed;
1073}
1074
1076 assert(A && "Argument must not be null.");
1077
1078 bool Changed = false;
1079 if (!Props.IsFree && !A->hasAttribute(Attribute::NoFree) &&
1080 !A->hasAttribute(Attribute::NoFreeObj)) {
1081 ++NumNoFreeArg;
1082 A->addAttr(Attribute::NoFree);
1083 Changed = true;
1084 }
1085
1086 if (Props.IsRead && Props.IsWrite)
1087 return Changed;
1088
1090 if (Props.IsRead)
1091 Attr = Attribute::ReadOnly;
1092 else if (Props.IsWrite)
1093 Attr = Attribute::WriteOnly;
1094 else
1095 Attr = Attribute::ReadNone;
1096
1097 // If the argument already has the attribute, nothing needs to be done.
1098 if (A->hasAttribute(Attr))
1099 return false;
1100
1101 // Otherwise, remove potentially conflicting attribute, add the new one,
1102 // and update statistics.
1103 A->removeAttr(Attribute::WriteOnly);
1104 A->removeAttr(Attribute::ReadOnly);
1105 A->removeAttr(Attribute::ReadNone);
1106 // Remove conflicting writable attribute.
1107 if (Attr == Attribute::ReadNone || Attr == Attribute::ReadOnly)
1108 A->removeAttr(Attribute::Writable);
1109 A->addAttr(Attr);
1110 if (Attr == Attribute::ReadOnly)
1111 ++NumReadOnlyArg;
1112 else if (Attr == Attribute::WriteOnly)
1113 ++NumWriteOnlyArg;
1114 else
1115 ++NumReadNoneArg;
1116 return true;
1117}
1118
1120 auto ArgumentUses = collectArgumentUsesPerBlock(A, F);
1121 // No write anywhere in the function, bail.
1122 if (!ArgumentUses.HasAnyWrite)
1123 return false;
1124
1125 auto &UsesPerBlock = ArgumentUses.UsesPerBlock;
1126 BasicBlock &EntryBB = F.getEntryBlock();
1127 // A map to store the argument ranges initialized by a BasicBlock (including
1128 // its successors).
1130 // Visit the successors of "BB" block and the instructions in BB (post-order)
1131 // to get the argument ranges initialized by "BB" (including its successors).
1132 // The result will be cached in "Initialized".
1133 auto VisitBlock = [&](const BasicBlock *BB) -> ConstantRangeList {
1134 auto UPB = UsesPerBlock.find(BB);
1136
1137 // Start with intersection of successors.
1138 // If this block has any clobbering use, we're going to clear out the
1139 // ranges at some point in this block anyway, so don't bother looking at
1140 // successors.
1141 if (UPB == UsesPerBlock.end() || !UPB->second.HasUnknownAccess) {
1142 bool HasAddedSuccessor = false;
1143 for (auto *Succ : successors(BB)) {
1144 if (auto SuccI = Initialized.find(Succ); SuccI != Initialized.end()) {
1145 if (HasAddedSuccessor) {
1146 CRL = CRL.intersectWith(SuccI->second);
1147 } else {
1148 CRL = SuccI->second;
1149 HasAddedSuccessor = true;
1150 }
1151 } else {
1152 CRL = ConstantRangeList();
1153 break;
1154 }
1155 }
1156 }
1157
1158 if (UPB != UsesPerBlock.end()) {
1159 // Sort uses in this block by instruction order.
1161 append_range(Insts, UPB->second.Insts);
1162 sort(Insts, [](std::pair<Instruction *, ArgumentAccessInfo> &LHS,
1163 std::pair<Instruction *, ArgumentAccessInfo> &RHS) {
1164 return LHS.first->comesBefore(RHS.first);
1165 });
1166
1167 // From the end of the block to the beginning of the block, set
1168 // initializes ranges.
1169 for (auto &[_, Info] : reverse(Insts)) {
1170 if (Info.ArgAccessType == ArgumentAccessInfo::AccessType::Unknown ||
1171 Info.ArgAccessType ==
1172 ArgumentAccessInfo::AccessType::WriteWithSideEffect)
1173 CRL = ConstantRangeList();
1174 if (!Info.AccessRanges.empty()) {
1175 if (Info.ArgAccessType == ArgumentAccessInfo::AccessType::Write ||
1176 Info.ArgAccessType ==
1177 ArgumentAccessInfo::AccessType::WriteWithSideEffect) {
1178 CRL = CRL.unionWith(Info.AccessRanges);
1179 } else {
1180 assert(Info.ArgAccessType == ArgumentAccessInfo::AccessType::Read);
1181 for (const auto &ReadRange : Info.AccessRanges)
1182 CRL.subtract(ReadRange);
1183 }
1184 }
1185 }
1186 }
1187 return CRL;
1188 };
1189
1190 ConstantRangeList EntryCRL;
1191 // If all write instructions are in the EntryBB, or if the EntryBB has
1192 // a clobbering use, we only need to look at EntryBB.
1193 bool OnlyScanEntryBlock = !ArgumentUses.HasWriteOutsideEntryBB;
1194 if (!OnlyScanEntryBlock)
1195 if (auto EntryUPB = UsesPerBlock.find(&EntryBB);
1196 EntryUPB != UsesPerBlock.end())
1197 OnlyScanEntryBlock = EntryUPB->second.HasUnknownAccess;
1198 if (OnlyScanEntryBlock) {
1199 EntryCRL = VisitBlock(&EntryBB);
1200 if (EntryCRL.empty())
1201 return false;
1202 } else {
1203 // Now we have to go through CFG to get the initialized argument ranges
1204 // across blocks. With dominance and post-dominance, the initialized ranges
1205 // by a block include both accesses inside this block and accesses in its
1206 // (transitive) successors. So visit successors before predecessors with a
1207 // post-order walk of the blocks and memorize the results in "Initialized".
1208 for (const BasicBlock *BB : post_order(&F)) {
1209 ConstantRangeList CRL = VisitBlock(BB);
1210 if (!CRL.empty())
1211 Initialized[BB] = CRL;
1212 }
1213
1214 auto EntryCRLI = Initialized.find(&EntryBB);
1215 if (EntryCRLI == Initialized.end())
1216 return false;
1217
1218 EntryCRL = EntryCRLI->second;
1219 }
1220
1221 assert(!EntryCRL.empty() &&
1222 "should have bailed already if EntryCRL is empty");
1223
1224 if (A.hasAttribute(Attribute::Initializes)) {
1225 ConstantRangeList PreviousCRL =
1226 A.getAttribute(Attribute::Initializes).getValueAsConstantRangeList();
1227 if (PreviousCRL == EntryCRL)
1228 return false;
1229 EntryCRL = EntryCRL.unionWith(PreviousCRL);
1230 }
1231
1232 A.addAttr(Attribute::get(A.getContext(), Attribute::Initializes,
1233 EntryCRL.rangesRef()));
1234
1235 return true;
1236}
1237
1238/// Deduce nocapture attributes for the SCC.
1239static void addArgumentAttrs(const SCCNodeSet &SCCNodes,
1241 bool SkipInitializes) {
1242 ArgumentGraph AG;
1243
1244 auto DetermineAccessAttrsForSingleton = [](Argument *A) {
1246 Self.insert(A);
1248 };
1249
1250 // Check each function in turn, determining which pointer arguments are not
1251 // captured.
1252 for (Function *F : SCCNodes) {
1253 // We can infer and propagate function attributes only when we know that the
1254 // definition we'll get at link time is *exactly* the definition we see now.
1255 // For more details, see GlobalValue::mayBeDerefined.
1256 if (!F->hasExactDefinition())
1257 continue;
1258
1260 Changed.insert(F);
1261
1262 // Functions that are readonly (or readnone) and nounwind and don't return
1263 // a value can't capture arguments. Don't analyze them.
1264 if (F->onlyReadsMemory() && F->doesNotThrow() && F->willReturn() &&
1265 F->getReturnType()->isVoidTy()) {
1266 for (Argument &A : F->args()) {
1267 if (A.getType()->isPointerTy() && !A.hasNoCaptureAttr()) {
1268 A.addAttr(Attribute::getWithCaptureInfo(A.getContext(),
1270 ++NumCapturesNone;
1271 Changed.insert(F);
1272 }
1273 }
1274 continue;
1275 }
1276
1277 for (Argument &A : F->args()) {
1278 if (!A.getType()->isPointerTy())
1279 continue;
1280 bool HasNonLocalUses = false;
1281 CaptureInfo OrigCI = A.getAttributes().getCaptureInfo();
1282 if (!capturesNothing(OrigCI)) {
1283 ArgumentUsesTracker Tracker(SCCNodes);
1284 PointerMayBeCaptured(&A, &Tracker);
1285 CaptureInfo NewCI = Tracker.CI & OrigCI;
1286 if (NewCI != OrigCI) {
1287 if (Tracker.Uses.empty()) {
1288 // If the information is complete, add the attribute now.
1289 A.addAttr(Attribute::getWithCaptureInfo(A.getContext(), NewCI));
1290 addCapturesStat(NewCI);
1291 Changed.insert(F);
1292 } else {
1293 // If it's not trivially captured and not trivially not captured,
1294 // then it must be calling into another function in our SCC. Save
1295 // its particulars for Argument-SCC analysis later.
1296 ArgumentGraphNode *Node = AG[&A];
1297 Node->CC = CaptureComponents(NewCI);
1298 for (Argument *Use : Tracker.Uses) {
1299 Node->Uses.push_back(AG[Use]);
1300 if (Use != &A)
1301 HasNonLocalUses = true;
1302 }
1303 }
1304 }
1305 // Otherwise, it's captured. Don't bother doing SCC analysis on it.
1306 }
1307 if (!HasNonLocalUses && !A.onlyReadsMemory()) {
1308 // Can we determine that it's readonly/readnone/writeonly without doing
1309 // an SCC? Note that we don't allow any calls at all here, or else our
1310 // result will be dependent on the iteration order through the
1311 // functions in the SCC.
1312 if (DetermineAccessAttrsForSingleton(&A))
1313 Changed.insert(F);
1314 }
1315 if (!SkipInitializes && !A.onlyReadsMemory()) {
1316 if (inferInitializes(A, *F))
1317 Changed.insert(F);
1318 }
1319 }
1320 }
1321
1322 // The graph we've collected is partial because we stopped scanning for
1323 // argument uses once we solved the argument trivially. These partial nodes
1324 // show up as ArgumentGraphNode objects with an empty Uses list, and for
1325 // these nodes the final decision about whether they capture has already been
1326 // made. If the definition doesn't have a 'nocapture' attribute by now, it
1327 // captures.
1328
1329 for (scc_iterator<ArgumentGraph *> I = scc_begin(&AG); !I.isAtEnd(); ++I) {
1330 const std::vector<ArgumentGraphNode *> &ArgumentSCC = *I;
1331 if (ArgumentSCC.size() == 1) {
1332 if (!ArgumentSCC[0]->Definition)
1333 continue; // synthetic root node
1334
1335 // eg. "void f(int* x) { if (...) f(x); }"
1336 if (ArgumentSCC[0]->Uses.size() == 1 &&
1337 ArgumentSCC[0]->Uses[0] == ArgumentSCC[0]) {
1338 Argument *A = ArgumentSCC[0]->Definition;
1339 CaptureInfo OrigCI = A->getAttributes().getCaptureInfo();
1340 CaptureInfo NewCI = CaptureInfo(ArgumentSCC[0]->CC) & OrigCI;
1341 if (NewCI != OrigCI) {
1342 A->addAttr(Attribute::getWithCaptureInfo(A->getContext(), NewCI));
1343 addCapturesStat(NewCI);
1344 Changed.insert(A->getParent());
1345 }
1346
1347 // Infer the access attributes given the new captures one
1348 if (DetermineAccessAttrsForSingleton(A))
1349 Changed.insert(A->getParent());
1350 }
1351 continue;
1352 }
1353
1354 SmallPtrSet<Argument *, 8> ArgumentSCCNodes;
1355 // Fill ArgumentSCCNodes with the elements of the ArgumentSCC. Used for
1356 // quickly looking up whether a given Argument is in this ArgumentSCC.
1357 for (ArgumentGraphNode *I : ArgumentSCC) {
1358 ArgumentSCCNodes.insert(I->Definition);
1359 }
1360
1361 // At the SCC level, only track merged CaptureComponents. We're not
1362 // currently prepared to handle propagation of return-only captures across
1363 // the SCC.
1365 for (ArgumentGraphNode *N : ArgumentSCC) {
1366 for (ArgumentGraphNode *Use : N->Uses) {
1367 Argument *A = Use->Definition;
1368 if (ArgumentSCCNodes.count(A))
1369 CC |= Use->CC;
1370 else
1371 CC |= CaptureComponents(A->getAttributes().getCaptureInfo());
1372 break;
1373 }
1374 if (capturesAll(CC))
1375 break;
1376 }
1377
1378 if (!capturesAll(CC)) {
1379 for (ArgumentGraphNode *N : ArgumentSCC) {
1380 Argument *A = N->Definition;
1381 CaptureInfo OrigCI = A->getAttributes().getCaptureInfo();
1382 CaptureInfo NewCI = CaptureInfo(N->CC | CC) & OrigCI;
1383 if (NewCI != OrigCI) {
1384 A->addAttr(Attribute::getWithCaptureInfo(A->getContext(), NewCI));
1385 addCapturesStat(NewCI);
1386 Changed.insert(A->getParent());
1387 }
1388 }
1389 }
1390
1391 if (capturesAnyProvenance(CC)) {
1392 // As the pointer provenance may be captured, determine the pointer
1393 // attributes looking at each argument individually.
1394 for (ArgumentGraphNode *N : ArgumentSCC) {
1395 if (DetermineAccessAttrsForSingleton(N->Definition))
1396 Changed.insert(N->Definition->getParent());
1397 }
1398 continue;
1399 }
1400
1401 // We also want to compute readonly/readnone/writeonly. With a small number
1402 // of false negatives, we can assume that any pointer which is captured
1403 // isn't going to be provably readonly or readnone, since by definition
1404 // we can't analyze all uses of a captured pointer.
1405 //
1406 // The false negatives happen when the pointer is captured by a function
1407 // that promises readonly/readnone behaviour on the pointer, then the
1408 // pointer's lifetime ends before anything that writes to arbitrary memory.
1409 // Also, a readonly/readnone pointer may be returned, but returning a
1410 // pointer is capturing it.
1411
1412 ArgAccessProperties Props;
1413 for (ArgumentGraphNode *N : ArgumentSCC) {
1414 Argument *A = N->Definition;
1415 Props |= determinePointerAccessAttrs(A, ArgumentSCCNodes);
1416 if (Props.hasAll())
1417 break;
1418 }
1419
1420 if (!Props.hasAll()) {
1421 for (ArgumentGraphNode *N : ArgumentSCC) {
1422 Argument *A = N->Definition;
1423 if (addAccessAttrs(A, Props))
1424 Changed.insert(A->getParent());
1425 }
1426 }
1427 }
1428}
1429
1430/// Tests whether a function is "malloc-like".
1431///
1432/// A function is "malloc-like" if it returns either null or a pointer that
1433/// doesn't alias any other pointer visible to the caller.
1434static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes) {
1435 SmallSetVector<Value *, 8> FlowsToReturn;
1436 for (BasicBlock &BB : *F)
1437 if (ReturnInst *Ret = dyn_cast<ReturnInst>(BB.getTerminator()))
1438 FlowsToReturn.insert(Ret->getReturnValue());
1439
1440 for (unsigned i = 0; i != FlowsToReturn.size(); ++i) {
1441 Value *RetVal = FlowsToReturn[i];
1442
1443 if (Constant *C = dyn_cast<Constant>(RetVal)) {
1444 if (!C->isNullValue() && !isa<UndefValue>(C))
1445 return false;
1446
1447 continue;
1448 }
1449
1450 if (isa<Argument>(RetVal))
1451 return false;
1452
1453 if (Instruction *RVI = dyn_cast<Instruction>(RetVal))
1454 switch (RVI->getOpcode()) {
1455 // Extend the analysis by looking upwards.
1456 case Instruction::BitCast:
1457 case Instruction::GetElementPtr:
1458 case Instruction::AddrSpaceCast:
1459 FlowsToReturn.insert(RVI->getOperand(0));
1460 continue;
1461 case Instruction::Select: {
1463 FlowsToReturn.insert(SI->getTrueValue());
1464 FlowsToReturn.insert(SI->getFalseValue());
1465 continue;
1466 }
1467 case Instruction::PHI: {
1468 PHINode *PN = cast<PHINode>(RVI);
1469 FlowsToReturn.insert_range(PN->incoming_values());
1470 continue;
1471 }
1472
1473 // Check whether the pointer came from an allocation.
1474 case Instruction::Alloca:
1475 break;
1476 case Instruction::Call:
1477 case Instruction::Invoke: {
1478 CallBase &CB = cast<CallBase>(*RVI);
1479 if (CB.hasRetAttr(Attribute::NoAlias))
1480 break;
1481 if (CB.getCalledFunction() && SCCNodes.count(CB.getCalledFunction()))
1482 break;
1483 [[fallthrough]];
1484 }
1485 default:
1486 return false; // Did not come from an allocation.
1487 }
1488
1489 if (PointerMayBeCaptured(RetVal, /*ReturnCaptures=*/false))
1490 return false;
1491 }
1492
1493 return true;
1494}
1495
1496/// Deduce noalias attributes for the SCC.
1497static void addNoAliasAttrs(const SCCNodeSet &SCCNodes,
1499 // Check each function in turn, determining which functions return noalias
1500 // pointers.
1501 for (Function *F : SCCNodes) {
1502 // Already noalias.
1503 if (F->returnDoesNotAlias())
1504 continue;
1505
1506 // We can infer and propagate function attributes only when we know that the
1507 // definition we'll get at link time is *exactly* the definition we see now.
1508 // For more details, see GlobalValue::mayBeDerefined.
1509 if (!F->hasExactDefinition())
1510 return;
1511
1512 // We annotate noalias return values, which are only applicable to
1513 // pointer types.
1514 if (!F->getReturnType()->isPointerTy())
1515 continue;
1516
1517 if (!isFunctionMallocLike(F, SCCNodes))
1518 return;
1519 }
1520
1521 for (Function *F : SCCNodes) {
1522 if (F->returnDoesNotAlias() ||
1523 !F->getReturnType()->isPointerTy())
1524 continue;
1525
1526 F->setReturnDoesNotAlias();
1527 ++NumNoAlias;
1528 Changed.insert(F);
1529 }
1530}
1531
1532/// Tests whether this function is known to not return null.
1533///
1534/// Requires that the function returns a pointer.
1535///
1536/// Returns true if it believes the function will not return a null, and sets
1537/// \p Speculative based on whether the returned conclusion is a speculative
1538/// conclusion due to SCC calls.
1539static bool isReturnNonNull(Function *F, const SCCNodeSet &SCCNodes,
1540 bool &Speculative) {
1541 assert(F->getReturnType()->isPointerTy() &&
1542 "nonnull only meaningful on pointer types");
1543 Speculative = false;
1544
1545 SmallSetVector<Value *, 8> FlowsToReturn;
1546 for (BasicBlock &BB : *F)
1547 if (auto *Ret = dyn_cast<ReturnInst>(BB.getTerminator()))
1548 FlowsToReturn.insert(Ret->getReturnValue());
1549
1550 auto &DL = F->getDataLayout();
1551
1552 for (unsigned i = 0; i != FlowsToReturn.size(); ++i) {
1553 Value *RetVal = FlowsToReturn[i];
1554
1555 // If this value is locally known to be non-null, we're good
1556 if (isKnownNonZero(RetVal, DL))
1557 continue;
1558
1559 // Otherwise, we need to look upwards since we can't make any local
1560 // conclusions.
1561 Instruction *RVI = dyn_cast<Instruction>(RetVal);
1562 if (!RVI)
1563 return false;
1564 switch (RVI->getOpcode()) {
1565 // Extend the analysis by looking upwards.
1566 case Instruction::BitCast:
1567 case Instruction::AddrSpaceCast:
1568 FlowsToReturn.insert(RVI->getOperand(0));
1569 continue;
1570 case Instruction::GetElementPtr:
1571 if (cast<GEPOperator>(RVI)->isInBounds()) {
1572 FlowsToReturn.insert(RVI->getOperand(0));
1573 continue;
1574 }
1575 return false;
1576 case Instruction::Select: {
1578 FlowsToReturn.insert(SI->getTrueValue());
1579 FlowsToReturn.insert(SI->getFalseValue());
1580 continue;
1581 }
1582 case Instruction::PHI: {
1583 PHINode *PN = cast<PHINode>(RVI);
1584 for (int i = 0, e = PN->getNumIncomingValues(); i != e; ++i)
1585 FlowsToReturn.insert(PN->getIncomingValue(i));
1586 continue;
1587 }
1588 case Instruction::Call:
1589 case Instruction::Invoke: {
1590 CallBase &CB = cast<CallBase>(*RVI);
1591 Function *Callee = CB.getCalledFunction();
1592 // A call to a node within the SCC is assumed to return null until
1593 // proven otherwise
1594 if (Callee && SCCNodes.count(Callee)) {
1595 Speculative = true;
1596 continue;
1597 }
1598 return false;
1599 }
1600 default:
1601 return false; // Unknown source, may be null
1602 };
1603 llvm_unreachable("should have either continued or returned");
1604 }
1605
1606 return true;
1607}
1608
1609/// Deduce nonnull attributes for the SCC.
1610static void addNonNullAttrs(const SCCNodeSet &SCCNodes,
1612 // Speculative that all functions in the SCC return only nonnull
1613 // pointers. We may refute this as we analyze functions.
1614 bool SCCReturnsNonNull = true;
1615
1616 // Check each function in turn, determining which functions return nonnull
1617 // pointers.
1618 for (Function *F : SCCNodes) {
1619 // Already nonnull.
1620 if (F->getAttributes().hasRetAttr(Attribute::NonNull))
1621 continue;
1622
1623 // We can infer and propagate function attributes only when we know that the
1624 // definition we'll get at link time is *exactly* the definition we see now.
1625 // For more details, see GlobalValue::mayBeDerefined.
1626 if (!F->hasExactDefinition())
1627 return;
1628
1629 // We annotate nonnull return values, which are only applicable to
1630 // pointer types.
1631 if (!F->getReturnType()->isPointerTy())
1632 continue;
1633
1634 bool Speculative = false;
1635 if (isReturnNonNull(F, SCCNodes, Speculative)) {
1636 if (!Speculative) {
1637 // Mark the function eagerly since we may discover a function
1638 // which prevents us from speculating about the entire SCC
1639 LLVM_DEBUG(dbgs() << "Eagerly marking " << F->getName()
1640 << " as nonnull\n");
1641 F->addRetAttr(Attribute::NonNull);
1642 ++NumNonNullReturn;
1643 Changed.insert(F);
1644 }
1645 continue;
1646 }
1647 // At least one function returns something which could be null, can't
1648 // speculate any more.
1649 SCCReturnsNonNull = false;
1650 }
1651
1652 if (SCCReturnsNonNull) {
1653 for (Function *F : SCCNodes) {
1654 if (F->getAttributes().hasRetAttr(Attribute::NonNull) ||
1655 !F->getReturnType()->isPointerTy())
1656 continue;
1657
1658 LLVM_DEBUG(dbgs() << "SCC marking " << F->getName() << " as nonnull\n");
1659 F->addRetAttr(Attribute::NonNull);
1660 ++NumNonNullReturn;
1661 Changed.insert(F);
1662 }
1663 }
1664}
1665
1666/// Deduce noundef attributes for the SCC.
1667static void addNoUndefAttrs(const SCCNodeSet &SCCNodes,
1669 // Check each function in turn, determining which functions return noundef
1670 // values.
1671 for (Function *F : SCCNodes) {
1672 // Already noundef.
1673 AttributeList Attrs = F->getAttributes();
1674 if (Attrs.hasRetAttr(Attribute::NoUndef))
1675 continue;
1676
1677 // We can infer and propagate function attributes only when we know that the
1678 // definition we'll get at link time is *exactly* the definition we see now.
1679 // For more details, see GlobalValue::mayBeDerefined.
1680 if (!F->hasExactDefinition())
1681 return;
1682
1683 // MemorySanitizer assumes that the definition and declaration of a
1684 // function will be consistent. A function with sanitize_memory attribute
1685 // should be skipped from inference.
1686 if (F->hasFnAttribute(Attribute::SanitizeMemory))
1687 continue;
1688
1689 if (F->getReturnType()->isVoidTy())
1690 continue;
1691
1692 const DataLayout &DL = F->getDataLayout();
1693 if (all_of(*F, [&](BasicBlock &BB) {
1694 if (auto *Ret = dyn_cast<ReturnInst>(BB.getTerminator())) {
1695 // TODO: perform context-sensitive analysis?
1696 Value *RetVal = Ret->getReturnValue();
1698 return false;
1699
1700 // We know the original return value is not poison now, but it
1701 // could still be converted to poison by another return attribute.
1702 // Try to explicitly re-prove the relevant attributes.
1703 if (Attrs.hasRetAttr(Attribute::NonNull) &&
1704 !isKnownNonZero(RetVal, DL))
1705 return false;
1706
1707 if (MaybeAlign Align = Attrs.getRetAlignment())
1708 if (RetVal->getPointerAlignment(DL) < *Align)
1709 return false;
1710
1711 Attribute Attr = Attrs.getRetAttr(Attribute::Range);
1712 if (Attr.isValid() &&
1713 !Attr.getRange().contains(
1714 computeConstantRange(RetVal, /*ForSigned=*/false,
1715 SimplifyQuery(F->getDataLayout()))))
1716 return false;
1717
1718 FPClassTest AttrFPClass = Attrs.getRetNoFPClass();
1719 if (AttrFPClass != fcNone) {
1720 KnownFPClass ComputedFPClass = computeKnownFPClass(RetVal, DL);
1721 if (!ComputedFPClass.isKnownNever(AttrFPClass))
1722 return false;
1723 }
1724 }
1725 return true;
1726 })) {
1727 F->addRetAttr(Attribute::NoUndef);
1728 ++NumNoUndefReturn;
1729 Changed.insert(F);
1730 }
1731 }
1732}
1733
1734namespace {
1735
1736/// Collects a set of attribute inference requests and performs them all in one
1737/// go on a single SCC Node. Inference involves scanning function bodies
1738/// looking for instructions that violate attribute assumptions.
1739/// As soon as all the bodies are fine we are free to set the attribute.
1740/// Customization of inference for individual attributes is performed by
1741/// providing a handful of predicates for each attribute.
1742class AttributeInferer {
1743public:
1744 /// Describes a request for inference of a single attribute.
1745 struct InferenceDescriptor {
1746
1747 /// Returns true if this function does not have to be handled.
1748 /// General intent for this predicate is to provide an optimization
1749 /// for functions that do not need this attribute inference at all
1750 /// (say, for functions that already have the attribute).
1751 std::function<bool(const Function &)> SkipFunction;
1752
1753 /// Returns true if this instruction violates attribute assumptions.
1754 std::function<bool(Instruction &)> InstrBreaksAttribute;
1755
1756 /// Sets the inferred attribute for this function.
1757 std::function<void(Function &)> SetAttribute;
1758
1759 /// Attribute we derive.
1760 Attribute::AttrKind AKind;
1761
1762 /// If true, only "exact" definitions can be used to infer this attribute.
1763 /// See GlobalValue::isDefinitionExact.
1764 bool RequiresExactDefinition;
1765
1766 InferenceDescriptor(Attribute::AttrKind AK,
1767 std::function<bool(const Function &)> SkipFunc,
1768 std::function<bool(Instruction &)> InstrScan,
1769 std::function<void(Function &)> SetAttr,
1770 bool ReqExactDef)
1771 : SkipFunction(SkipFunc), InstrBreaksAttribute(InstrScan),
1772 SetAttribute(SetAttr), AKind(AK),
1773 RequiresExactDefinition(ReqExactDef) {}
1774 };
1775
1776private:
1777 SmallVector<InferenceDescriptor, 4> InferenceDescriptors;
1778
1779public:
1780 void registerAttrInference(InferenceDescriptor AttrInference) {
1781 InferenceDescriptors.push_back(AttrInference);
1782 }
1783
1784 void run(const SCCNodeSet &SCCNodes, SmallPtrSet<Function *, 8> &Changed);
1785};
1786
1787/// Perform all the requested attribute inference actions according to the
1788/// attribute predicates stored before.
1789void AttributeInferer::run(const SCCNodeSet &SCCNodes,
1791 SmallVector<InferenceDescriptor, 4> InferInSCC = InferenceDescriptors;
1792 // Go through all the functions in SCC and check corresponding attribute
1793 // assumptions for each of them. Attributes that are invalid for this SCC
1794 // will be removed from InferInSCC.
1795 for (Function *F : SCCNodes) {
1796
1797 // No attributes whose assumptions are still valid - done.
1798 if (InferInSCC.empty())
1799 return;
1800
1801 // Check if our attributes ever need scanning/can be scanned.
1802 llvm::erase_if(InferInSCC, [F](const InferenceDescriptor &ID) {
1803 if (ID.SkipFunction(*F))
1804 return false;
1805
1806 // Remove from further inference (invalidate) when visiting a function
1807 // that has no instructions to scan/has an unsuitable definition.
1808 return F->isDeclaration() ||
1809 (ID.RequiresExactDefinition && !F->hasExactDefinition());
1810 });
1811
1812 // For each attribute still in InferInSCC that doesn't explicitly skip F,
1813 // set up the F instructions scan to verify assumptions of the attribute.
1816 InferInSCC, std::back_inserter(InferInThisFunc),
1817 [F](const InferenceDescriptor &ID) { return !ID.SkipFunction(*F); });
1818
1819 if (InferInThisFunc.empty())
1820 continue;
1821
1822 // Start instruction scan.
1823 for (Instruction &I : instructions(*F)) {
1824 llvm::erase_if(InferInThisFunc, [&](const InferenceDescriptor &ID) {
1825 if (!ID.InstrBreaksAttribute(I))
1826 return false;
1827 // Remove attribute from further inference on any other functions
1828 // because attribute assumptions have just been violated.
1829 llvm::erase_if(InferInSCC, [&ID](const InferenceDescriptor &D) {
1830 return D.AKind == ID.AKind;
1831 });
1832 // Remove attribute from the rest of current instruction scan.
1833 return true;
1834 });
1835
1836 if (InferInThisFunc.empty())
1837 break;
1838 }
1839 }
1840
1841 if (InferInSCC.empty())
1842 return;
1843
1844 for (Function *F : SCCNodes)
1845 // At this point InferInSCC contains only functions that were either:
1846 // - explicitly skipped from scan/inference, or
1847 // - verified to have no instructions that break attribute assumptions.
1848 // Hence we just go and force the attribute for all non-skipped functions.
1849 for (auto &ID : InferInSCC) {
1850 if (ID.SkipFunction(*F))
1851 continue;
1852 Changed.insert(F);
1853 ID.SetAttribute(*F);
1854 }
1855}
1856
1857struct SCCNodesResult {
1858 SCCNodeSet SCCNodes;
1859};
1860
1861} // end anonymous namespace
1862
1863/// Helper for non-Convergent inference predicate InstrBreaksAttribute.
1865 const SCCNodeSet &SCCNodes) {
1866 const CallBase *CB = dyn_cast<CallBase>(&I);
1867 // Breaks non-convergent assumption if CS is a convergent call to a function
1868 // not in the SCC.
1869 return CB && CB->isConvergent() &&
1870 !SCCNodes.contains(CB->getCalledFunction());
1871}
1872
1873/// Helper for NoUnwind inference predicate InstrBreaksAttribute.
1874static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes) {
1875 if (!I.mayThrow(/* IncludePhaseOneUnwind */ true))
1876 return false;
1877 if (const auto *CI = dyn_cast<CallInst>(&I)) {
1878 if (Function *Callee = CI->getCalledFunction()) {
1879 // I is a may-throw call to a function inside our SCC. This doesn't
1880 // invalidate our current working assumption that the SCC is no-throw; we
1881 // just have to scan that other function.
1882 if (SCCNodes.contains(Callee))
1883 return false;
1884 }
1885 }
1886 return true;
1887}
1888
1889/// Helper for NoFree inference predicate InstrBreaksAttribute.
1890static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes) {
1892 if (!CB) {
1893 // Synchronization may establish happens-before with a free on another
1894 // thread.
1895 return I.maySynchronize();
1896 }
1897
1898 if (CB->hasFnAttr(Attribute::NoFree))
1899 return false;
1900
1901 // Speculatively assume in SCC.
1902 if (Function *Callee = CB->getCalledFunction())
1903 if (SCCNodes.contains(Callee))
1904 return false;
1905
1906 return true;
1907}
1908
1909static bool InstrBreaksNoSync(Instruction &I, const SCCNodeSet &SCCNodes) {
1910 if (!I.maySynchronize())
1911 return false;
1912
1913 // Optimistically assume calls within the SCC are nosync: if nothing else in
1914 // the SCC synchronizes, the assumption holds.
1915 if (auto *CB = dyn_cast<CallBase>(&I))
1916 if (Function *Callee = CB->getCalledFunction())
1917 if (SCCNodes.contains(Callee))
1918 return false;
1919
1920 return true;
1921}
1922
1923/// Attempt to remove convergent function attribute when possible.
1924///
1925/// Returns true if any changes to function attributes were made.
1926static void inferConvergent(const SCCNodeSet &SCCNodes,
1928 AttributeInferer AI;
1929
1930 // Request to remove the convergent attribute from all functions in the SCC
1931 // if every callsite within the SCC is not convergent (except for calls
1932 // to functions within the SCC).
1933 // Note: Removal of the attr from the callsites will happen in
1934 // InstCombineCalls separately.
1935 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1936 Attribute::Convergent,
1937 // Skip non-convergent functions.
1938 [](const Function &F) { return !F.isConvergent(); },
1939 // Instructions that break non-convergent assumption.
1940 [SCCNodes](Instruction &I) {
1941 return InstrBreaksNonConvergent(I, SCCNodes);
1942 },
1943 [](Function &F) {
1944 LLVM_DEBUG(dbgs() << "Removing convergent attr from fn " << F.getName()
1945 << "\n");
1946 F.setNotConvergent();
1947 },
1948 /* RequiresExactDefinition= */ false});
1949 // Perform all the requested attribute inference actions.
1950 AI.run(SCCNodes, Changed);
1951}
1952
1953/// Infer attributes from all functions in the SCC by scanning every
1954/// instruction for compliance to the attribute assumptions.
1955///
1956/// Returns true if any changes to function attributes were made.
1957static void inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes,
1959 AttributeInferer AI;
1960
1962 // Request to infer nounwind attribute for all the functions in the SCC if
1963 // every callsite within the SCC is not throwing (except for calls to
1964 // functions within the SCC). Note that nounwind attribute suffers from
1965 // derefinement - results may change depending on how functions are
1966 // optimized. Thus it can be inferred only from exact definitions.
1967 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1968 Attribute::NoUnwind,
1969 // Skip non-throwing functions.
1970 [](const Function &F) { return F.doesNotThrow(); },
1971 // Instructions that break non-throwing assumption.
1972 [&SCCNodes](Instruction &I) {
1973 return InstrBreaksNonThrowing(I, SCCNodes);
1974 },
1975 [](Function &F) {
1977 << "Adding nounwind attr to fn " << F.getName() << "\n");
1978 F.setDoesNotThrow();
1979 ++NumNoUnwind;
1980 },
1981 /* RequiresExactDefinition= */ true});
1982
1984 // Request to infer nofree attribute for all the functions in the SCC if
1985 // every callsite within the SCC does not directly or indirectly free
1986 // memory (except for calls to functions within the SCC). Note that nofree
1987 // attribute suffers from derefinement - results may change depending on
1988 // how functions are optimized. Thus it can be inferred only from exact
1989 // definitions.
1990 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
1991 Attribute::NoFree,
1992 // Skip functions known not to free memory.
1993 [](const Function &F) { return F.doesNotFreeMemory(); },
1994 // Instructions that break non-deallocating assumption.
1995 [&SCCNodes](Instruction &I) {
1996 return InstrBreaksNoFree(I, SCCNodes);
1997 },
1998 [](Function &F) {
2000 << "Adding nofree attr to fn " << F.getName() << "\n");
2001 F.setDoesNotFreeMemory();
2002 ++NumNoFree;
2003 },
2004 /* RequiresExactDefinition= */ true});
2005
2006 AI.registerAttrInference(AttributeInferer::InferenceDescriptor{
2007 Attribute::NoSync,
2008 // Skip already marked functions.
2009 [](const Function &F) { return F.hasNoSync(); },
2010 // Instructions that break nosync assumption.
2011 [&SCCNodes](Instruction &I) {
2012 return InstrBreaksNoSync(I, SCCNodes);
2013 },
2014 [](Function &F) {
2016 << "Adding nosync attr to fn " << F.getName() << "\n");
2017 F.setNoSync();
2018 ++NumNoSync;
2019 },
2020 /* RequiresExactDefinition= */ true});
2021
2022 // Perform all the requested attribute inference actions.
2023 AI.run(SCCNodes, Changed);
2024}
2025
2026// Determines if the function 'F' can be marked 'norecurse'.
2027// It returns true if any call within 'F' could lead to a recursive
2028// call back to 'F', and false otherwise.
2029// The 'AnyFunctionsAddressIsTaken' parameter is a module-wide flag
2030// that is true if any function's address is taken, or if any function
2031// has external linkage. This is used to determine the safety of
2032// external/library calls.
2034 bool AnyFunctionsAddressIsTaken = true) {
2035 for (const auto &BB : F) {
2036 for (const auto &I : BB) {
2037 if (const auto *CB = dyn_cast<CallBase>(&I)) {
2038 const Function *Callee = CB->getCalledFunction();
2039 if (!Callee || Callee == &F)
2040 return true;
2041
2042 if (Callee->doesNotRecurse())
2043 continue;
2044
2045 if (!AnyFunctionsAddressIsTaken ||
2046 (Callee->isDeclaration() &&
2047 Callee->hasFnAttribute(Attribute::NoCallback)))
2048 continue;
2049 return true;
2050 }
2051 }
2052 }
2053 return false;
2054}
2055
2056static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes,
2058 // Try and identify functions that do not recurse.
2059
2060 // If the SCC contains multiple nodes we know for sure there is recursion.
2061 if (SCCNodes.size() != 1)
2062 return;
2063
2064 Function *F = *SCCNodes.begin();
2065 if (!F || !F->hasExactDefinition() || F->doesNotRecurse())
2066 return;
2067 if (!mayHaveRecursiveCallee(*F)) {
2068 // Every call was to a non-recursive function other than this function, and
2069 // we have no indirect recursion as the SCC size is one. This function
2070 // cannot recurse.
2071 F->setDoesNotRecurse();
2072 ++NumNoRecurse;
2073 Changed.insert(F);
2074 }
2075}
2076
2077// Set the noreturn function attribute if possible.
2078static void addNoReturnAttrs(const SCCNodeSet &SCCNodes,
2080 for (Function *F : SCCNodes) {
2081 if (!F || !F->hasExactDefinition() || F->hasFnAttribute(Attribute::Naked) ||
2082 F->doesNotReturn())
2083 continue;
2084
2085 if (!canReturn(*F)) {
2086 F->setDoesNotReturn();
2087 Changed.insert(F);
2088 }
2089 }
2090}
2091
2094 ColdPaths[&F.front()] = false;
2096 Jobs.push_back(&F.front());
2097
2098 while (!Jobs.empty()) {
2099 BasicBlock *BB = Jobs.pop_back_val();
2100
2101 // If block contains a cold callsite this path through the CG is cold.
2102 // Ignore whether the instructions actually are guaranteed to transfer
2103 // execution. Divergent behavior is considered unlikely.
2104 if (any_of(*BB, [](Instruction &I) {
2105 if (auto *CB = dyn_cast<CallBase>(&I))
2106 return CB->hasFnAttr(Attribute::Cold);
2107 return false;
2108 })) {
2109 ColdPaths[BB] = true;
2110 continue;
2111 }
2112
2113 auto Succs = successors(BB);
2114 // We found a path that doesn't go through any cold callsite.
2115 if (Succs.empty())
2116 return false;
2117
2118 // We didn't find a cold callsite in this BB, so check that all successors
2119 // contain a cold callsite (or that their successors do).
2120 // Potential TODO: We could use static branch hints to assume certain
2121 // successor paths are inherently cold, irrespective of if they contain a
2122 // cold callsite.
2123 for (BasicBlock *Succ : Succs) {
2124 // Start with false, this is necessary to ensure we don't turn loops into
2125 // cold.
2126 auto [Iter, Inserted] = ColdPaths.try_emplace(Succ, false);
2127 if (!Inserted) {
2128 if (Iter->second)
2129 continue;
2130 return false;
2131 }
2132 Jobs.push_back(Succ);
2133 }
2134 }
2135 return true;
2136}
2137
2138// Set the cold function attribute if possible.
2139static void addColdAttrs(const SCCNodeSet &SCCNodes,
2141 for (Function *F : SCCNodes) {
2142 if (!F || !F->hasExactDefinition() || F->hasFnAttribute(Attribute::Naked) ||
2143 F->hasFnAttribute(Attribute::Cold) || F->hasFnAttribute(Attribute::Hot))
2144 continue;
2145
2146 // Potential TODO: We could add attribute `cold` on functions with `coldcc`.
2147 if (allPathsGoThroughCold(*F)) {
2148 F->addFnAttr(Attribute::Cold);
2149 ++NumCold;
2150 Changed.insert(F);
2151 continue;
2152 }
2153 }
2154}
2155
2156static bool functionWillReturn(const Function &F) {
2157 // We can infer and propagate function attributes only when we know that the
2158 // definition we'll get at link time is *exactly* the definition we see now.
2159 // For more details, see GlobalValue::mayBeDerefined.
2160 if (!F.hasExactDefinition())
2161 return false;
2162
2163 // Must-progress function without side-effects must return.
2164 if (F.mustProgress() && F.onlyReadsMemory())
2165 return true;
2166
2167 // Can only analyze functions with a definition.
2168 if (F.isDeclaration())
2169 return false;
2170
2171 // Functions with loops require more sophisticated analysis, as the loop
2172 // may be infinite. For now, don't try to handle them.
2174 FindFunctionBackedges(F, Backedges);
2175 if (!Backedges.empty())
2176 return false;
2177
2178 // If there are no loops, then the function is willreturn if all calls in
2179 // it are willreturn.
2180 return all_of(instructions(F), [](const Instruction &I) {
2181 return I.willReturn();
2182 });
2183}
2184
2185// Set the willreturn function attribute if possible.
2186static void addWillReturn(const SCCNodeSet &SCCNodes,
2188 for (Function *F : SCCNodes) {
2189 if (!F || F->willReturn() || !functionWillReturn(*F))
2190 continue;
2191
2192 F->setWillReturn();
2193 NumWillReturn++;
2194 Changed.insert(F);
2195 }
2196}
2197
2198static SCCNodesResult createSCCNodeSet(ArrayRef<Function *> Functions) {
2199 SCCNodesResult Res;
2200 for (Function *F : Functions) {
2201 if (!F || F->hasOptNone() || F->hasFnAttribute(Attribute::Naked) ||
2202 F->isPresplitCoroutine()) {
2203 // Omit any functions we're trying not to optimize from the set.
2204 continue;
2205 }
2206
2207 Res.SCCNodes.insert(F);
2208 }
2209 return Res;
2210}
2211
2212template <typename AARGetterT>
2213static SmallPtrSet<Function *, 8>
2214deriveAttrsInPostOrder(ArrayRef<Function *> Functions, AARGetterT &&AARGetter,
2215 bool ArgAttrsOnly) {
2216 SCCNodesResult Nodes = createSCCNodeSet(Functions);
2217
2218 // Bail if the SCC only contains optnone functions.
2219 if (Nodes.SCCNodes.empty())
2220 return {};
2221
2223 if (ArgAttrsOnly) {
2224 // ArgAttrsOnly means to only infer attributes that may aid optimizations
2225 // on the *current* function. "initializes" attribute is to aid
2226 // optimizations (like DSE) on the callers, so skip "initializes" here.
2227 addArgumentAttrs(Nodes.SCCNodes, Changed, /*SkipInitializes=*/true);
2228 return Changed;
2229 }
2230
2231 addArgumentReturnedAttrs(Nodes.SCCNodes, Changed);
2232 addMemoryAttrs(Nodes.SCCNodes, AARGetter, Changed);
2233 addArgumentAttrs(Nodes.SCCNodes, Changed, /*SkipInitializes=*/false);
2234 inferConvergent(Nodes.SCCNodes, Changed);
2235 addNoReturnAttrs(Nodes.SCCNodes, Changed);
2236 addColdAttrs(Nodes.SCCNodes, Changed);
2237 addWillReturn(Nodes.SCCNodes, Changed);
2238 addNoUndefAttrs(Nodes.SCCNodes, Changed);
2239 addNoAliasAttrs(Nodes.SCCNodes, Changed);
2240 addNonNullAttrs(Nodes.SCCNodes, Changed);
2241 inferAttrsFromFunctionBodies(Nodes.SCCNodes, Changed);
2242 addNoRecurseAttrs(Nodes.SCCNodes, Changed);
2243
2244 // Finally, infer the maximal set of attributes from the ones we've inferred
2245 // above. This is handling the cases where one attribute on a signature
2246 // implies another, but for implementation reasons the inference rule for
2247 // the later is missing (or simply less sophisticated).
2248 for (Function *F : Nodes.SCCNodes)
2249 if (F)
2251 Changed.insert(F);
2252
2253 return Changed;
2254}
2255
2258 LazyCallGraph &CG,
2260 // Skip non-recursive functions if requested.
2261 // Only infer argument attributes for non-recursive functions, because
2262 // it can affect optimization behavior in conjunction with noalias.
2263 bool ArgAttrsOnly = false;
2264 if (C.size() == 1 && SkipNonRecursive) {
2265 LazyCallGraph::Node &N = *C.begin();
2266 if (!N->lookup(N))
2267 ArgAttrsOnly = true;
2268 }
2269
2271 AM.getResult<FunctionAnalysisManagerCGSCCProxy>(C, CG).getManager();
2272
2273 // We pass a lambda into functions to wire them up to the analysis manager
2274 // for getting function analyses.
2275 auto AARGetter = [&](Function &F) -> AAResults & {
2276 return FAM.getResult<AAManager>(F);
2277 };
2278
2280 for (LazyCallGraph::Node &N : C) {
2281 Functions.push_back(&N.getFunction());
2282 }
2283
2284 auto ChangedFunctions =
2285 deriveAttrsInPostOrder(Functions, AARGetter, ArgAttrsOnly);
2286 if (ChangedFunctions.empty())
2287 return PreservedAnalyses::all();
2288
2289 // Invalidate analyses for modified functions so that we don't have to
2290 // invalidate all analyses for all functions in this SCC.
2291 PreservedAnalyses FuncPA;
2292 // We haven't changed the CFG for modified functions.
2293 FuncPA.preserveSet<CFGAnalyses>();
2294 for (Function *Changed : ChangedFunctions) {
2295 FAM.invalidate(*Changed, FuncPA);
2296 // Also invalidate any direct callers of changed functions since analyses
2297 // may care about attributes of direct callees. For example, MemorySSA cares
2298 // about whether or not a call's callee modifies memory and queries that
2299 // through function attributes.
2300 for (auto *U : Changed->users()) {
2301 if (auto *Call = dyn_cast<CallBase>(U)) {
2302 if (Call->getCalledOperand() == Changed)
2303 FAM.invalidate(*Call->getFunction(), FuncPA);
2304 }
2305 }
2306 }
2307
2309 // We have not added or removed functions.
2311 // We already invalidated all relevant function analyses above.
2313 return PA;
2314}
2315
2317 raw_ostream &OS, function_ref<StringRef(StringRef)> MapClassName2PassName) {
2318 static_cast<PassInfoMixin<PostOrderFunctionAttrsPass> *>(this)->printPipeline(
2319 OS, MapClassName2PassName);
2320 if (SkipNonRecursive)
2321 OS << "<skip-non-recursive-function-attrs>";
2322}
2323
2325 if (F.doesNotRecurse())
2326 return false;
2327
2328 // We check the preconditions for the function prior to calling this to avoid
2329 // the cost of building up a reversible post-order list. We assert them here
2330 // to make sure none of the invariants this relies on were violated.
2331 assert(!F.isDeclaration() && "Cannot deduce norecurse without a definition!");
2332 assert(F.hasInternalLinkage() &&
2333 "Can only do top-down deduction for internal linkage functions!");
2334
2335 // If F is internal and all of its uses are calls from a non-recursive
2336 // functions, then none of its calls could in fact recurse without going
2337 // through a function marked norecurse, and so we can mark this function too
2338 // as norecurse. Note that the uses must actually be calls -- otherwise
2339 // a pointer to this function could be returned from a norecurse function but
2340 // this function could be recursively (indirectly) called. Note that this
2341 // also detects if F is directly recursive as F is not yet marked as
2342 // a norecurse function.
2343 for (auto &U : F.uses()) {
2344 const CallBase *CB = dyn_cast<CallBase>(U.getUser());
2345 if (!CB || !CB->isCallee(&U) ||
2346 !CB->getParent()->getParent()->doesNotRecurse())
2347 return false;
2348 }
2349 F.setDoesNotRecurse();
2350 ++NumNoRecurse;
2351 return true;
2352}
2353
2355 assert(!F.isDeclaration() && "Cannot deduce nofpclass without a definition!");
2356 unsigned NumArgs = F.arg_size();
2357 SmallVector<FPClassTest, 8> ArgsNoFPClass(NumArgs, fcAllFlags);
2358 FPClassTest RetNoFPClass = fcAllFlags;
2359
2360 bool Changed = false;
2361 for (User *U : F.users()) {
2362 auto *CB = dyn_cast<CallBase>(U);
2363 if (!CB || CB->getCalledFunction() != &F)
2364 return false;
2365
2366 RetNoFPClass &= CB->getRetNoFPClass();
2367 for (unsigned I = 0; I != NumArgs; ++I) {
2368 // TODO: Consider computeKnownFPClass, at least with a small search
2369 // depth. This will currently not catch non-splat vectors.
2370 const APFloat *Cst;
2371 if (match(CB->getArgOperand(I), m_APFloat(Cst)))
2372 ArgsNoFPClass[I] &= ~Cst->classify();
2373 else
2374 ArgsNoFPClass[I] &= CB->getParamNoFPClass(I);
2375 }
2376 }
2377
2378 LLVMContext &Ctx = F.getContext();
2379
2380 if (RetNoFPClass != fcNone) {
2381 FPClassTest OldAttr = F.getAttributes().getRetNoFPClass();
2382 if (OldAttr != RetNoFPClass) {
2383 F.addRetAttr(Attribute::getWithNoFPClass(Ctx, RetNoFPClass));
2384 Changed = true;
2385 }
2386 }
2387
2388 for (unsigned I = 0; I != NumArgs; ++I) {
2389 FPClassTest ArgNoFPClass = ArgsNoFPClass[I];
2390 if (ArgNoFPClass == fcNone)
2391 continue;
2392 FPClassTest OldAttr = F.getParamNoFPClass(I);
2393 if (OldAttr == ArgNoFPClass)
2394 continue;
2395
2396 F.addParamAttr(I, Attribute::getWithNoFPClass(Ctx, ArgNoFPClass));
2397 Changed = true;
2398 }
2399
2400 return Changed;
2401}
2402
2404 // We only have a post-order SCC traversal (because SCCs are inherently
2405 // discovered in post-order), so we accumulate them in a vector and then walk
2406 // it in reverse. This is simpler than using the RPO iterator infrastructure
2407 // because we need to combine SCC detection and the PO walk of the call
2408 // graph. We can also cheat egregiously because we're primarily interested in
2409 // synthesizing norecurse and so we can only save the singular SCCs as SCCs
2410 // with multiple functions in them will clearly be recursive.
2411
2413 CG.buildRefSCCs();
2414 for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs()) {
2415 for (LazyCallGraph::SCC &SCC : RC) {
2416 if (SCC.size() != 1)
2417 continue;
2418 Function &F = SCC.begin()->getFunction();
2419 if (!F.isDeclaration() && F.hasInternalLinkage() && !F.use_empty())
2420 Worklist.push_back(&F);
2421 }
2422 }
2423 bool Changed = false;
2424 for (auto *F : llvm::reverse(Worklist)) {
2427 }
2428
2429 return Changed;
2430}
2431
2432PreservedAnalyses
2434 auto &CG = AM.getResult<LazyCallGraphAnalysis>(M);
2435
2436 if (!deduceFunctionAttributeInRPO(M, CG))
2437 return PreservedAnalyses::all();
2438
2441 return PA;
2442}
2443
2446
2447 // Check if any function in the whole program has its address taken or has
2448 // potentially external linkage.
2449 // We use this information when inferring norecurse attribute: If there is
2450 // no function whose address is taken and all functions have internal
2451 // linkage, there is no path for a callback to any user function.
2452 bool AnyFunctionsAddressIsTaken = false;
2453 for (Function &F : M) {
2454 if (F.isDeclaration() || F.doesNotRecurse())
2455 continue;
2456 if (!F.hasLocalLinkage() || F.hasAddressTaken()) {
2457 AnyFunctionsAddressIsTaken = true;
2458 break;
2459 }
2460 }
2461
2462 // Run norecurse inference on all RefSCCs in the LazyCallGraph for this
2463 // module.
2464 bool Changed = false;
2465 LazyCallGraph &CG = MAM.getResult<LazyCallGraphAnalysis>(M);
2466 CG.buildRefSCCs();
2467
2468 for (LazyCallGraph::RefSCC &RC : CG.postorder_ref_sccs()) {
2469 // Skip any RefSCC that is part of a call cycle. A RefSCC containing more
2470 // than one SCC indicates a recursive relationship involving indirect calls.
2471 if (RC.size() > 1)
2472 continue;
2473
2474 // RefSCC contains a single-SCC. SCC size > 1 indicates mutually recursive
2475 // functions. Ex: foo1 -> foo2 -> foo3 -> foo1.
2476 LazyCallGraph::SCC &S = *RC.begin();
2477 if (S.size() > 1)
2478 continue;
2479
2480 // Get the single function from this SCC.
2481 Function &F = S.begin()->getFunction();
2482 if (!F.hasExactDefinition() || F.doesNotRecurse())
2483 continue;
2484
2485 // If the analysis confirms that this function has no recursive calls
2486 // (either direct, indirect, or through external linkages),
2487 // we can safely apply the norecurse attribute.
2488 if (!mayHaveRecursiveCallee(F, AnyFunctionsAddressIsTaken)) {
2489 F.setDoesNotRecurse();
2490 ++NumNoRecurse;
2491 Changed = true;
2492 }
2493 }
2494
2496 if (Changed)
2498 else
2500 return PA;
2501}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Expand Atomic instructions
This file contains the simple types necessary to represent the attributes associated with functions a...
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< ErlangGC > A("erlang", "erlang-compatible garbage collector")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
This header provides classes for managing passes over SCCs of the call graph.
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
This file contains the declarations for the subclasses of Constant, which represent the different fla...
DXIL Finalize Linkage
DXIL Resource Access
This file defines the DenseMap class.
static SmallPtrSet< Function *, 8 > deriveAttrsInPostOrder(ArrayRef< Function * > Functions, AARGetterT &&AARGetter, bool ArgAttrsOnly)
static cl::opt< bool > DisableNoFreeInference("disable-nofree-inference", cl::Hidden, cl::desc("Stop inferring nofree attribute during function-attrs pass"))
static bool inferInitializes(Argument &A, Function &F)
static bool allPathsGoThroughCold(Function &F)
static FunctionSummary * calculatePrevailingSummary(ValueInfo VI, DenseMap< ValueInfo, FunctionSummary * > &CachedPrevailingSummary, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> IsPrevailing)
static void addMemoryAttrs(const SCCNodeSet &SCCNodes, AARGetterT &&AARGetter, SmallPtrSet< Function *, 8 > &Changed)
Deduce readonly/readnone/writeonly attributes for the SCC.
static bool addArgumentAttrsFromCallsites(Function &F)
If a callsite has arguments that are also arguments to the parent function, try to propagate attribut...
static void addCapturesStat(CaptureInfo CI)
static void addArgLocs(MemoryEffects &ME, const CallBase *Call, ModRefInfo ArgMR, AAResults &AAR)
static bool isFunctionMallocLike(Function *F, const SCCNodeSet &SCCNodes)
Tests whether a function is "malloc-like".
static void addColdAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static bool mayHaveRecursiveCallee(Function &F, bool AnyFunctionsAddressIsTaken=true)
static void addNoReturnAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static bool addNoFPClassAttrsTopDown(Function &F)
static cl::opt< bool > DisableNoUnwindInference("disable-nounwind-inference", cl::Hidden, cl::desc("Stop inferring nounwind attribute during function-attrs pass"))
static void addWillReturn(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static void addNonNullAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce nonnull attributes for the SCC.
static std::pair< MemoryEffects, MemoryEffects > checkFunctionMemoryAccess(Function &F, bool ThisBody, AAResults &AAR, const SCCNodeSet &SCCNodes)
Returns the memory access attribute for function F using AAR for AA results, where SCCNodes is the cu...
static bool InstrBreaksNonThrowing(Instruction &I, const SCCNodeSet &SCCNodes)
Helper for NoUnwind inference predicate InstrBreaksAttribute.
static void inferAttrsFromFunctionBodies(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Infer attributes from all functions in the SCC by scanning every instruction for compliance to the at...
static bool isReturnNonNull(Function *F, const SCCNodeSet &SCCNodes, bool &Speculative)
Tests whether this function is known to not return null.
static bool InstrBreaksNoSync(Instruction &I, const SCCNodeSet &SCCNodes)
static bool deduceFunctionAttributeInRPO(Module &M, LazyCallGraph &CG)
static ArgAccessProperties determinePointerAccessAttrs(Argument *A, const SmallPtrSet< Argument *, 8 > &SCCNodes)
Returns Attribute::None, Attribute::ReadOnly or Attribute::ReadNone.
static bool InstrBreaksNoFree(Instruction &I, const SCCNodeSet &SCCNodes)
Helper for NoFree inference predicate InstrBreaksAttribute.
static cl::opt< bool > EnablePoisonArgAttrPropagation("enable-poison-arg-attr-prop", cl::init(true), cl::Hidden, cl::desc("Try to propagate nonnull and nofpclass argument attributes from " "callsites to caller functions."))
static bool addAccessAttrs(Argument *A, ArgAccessProperties Props)
static void addNoAliasAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce noalias attributes for the SCC.
static bool addNoRecurseAttrsTopDown(Function &F)
static void addLocAccess(MemoryEffects &ME, const MemoryLocation &Loc, ModRefInfo MR, AAResults &AAR)
static void inferConvergent(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Attempt to remove convergent function attribute when possible.
static cl::opt< bool > DisableThinLTOPropagation("disable-thinlto-funcattrs", cl::init(true), cl::Hidden, cl::desc("Don't propagate function-attrs in thinLTO"))
static SCCNodesResult createSCCNodeSet(ArrayRef< Function * > Functions)
static bool InstrBreaksNonConvergent(Instruction &I, const SCCNodeSet &SCCNodes)
Helper for non-Convergent inference predicate InstrBreaksAttribute.
static void addArgumentAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed, bool SkipInitializes)
Deduce nocapture attributes for the SCC.
static void addNoRecurseAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
static bool functionWillReturn(const Function &F)
static void addNoUndefAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce noundef attributes for the SCC.
static void addArgumentReturnedAttrs(const SCCNodeSet &SCCNodes, SmallPtrSet< Function *, 8 > &Changed)
Deduce returned attributes for the SCC.
Provides passes for computing function attributes based on interprocedural analyses.
Hexagon Common GEP
#define _
This header defines various interfaces for pass management in LLVM.
This defines the Use class.
Implements a lazy call graph analysis and related passes for the new pass manager.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
This file provides utility analysis objects describing memory locations.
This file contains the declarations for metadata subclasses.
ModuleSummaryIndex.h This file contains the declarations the classes that hold the module index and s...
uint64_t High
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
This file builds on the ADT/GraphTraits.h file to build a generic graph post order iterator.
Remove Loads Into Fake Uses
This builds on the llvm/ADT/GraphTraits.h file to find the strongly connected components (SCCs) of a ...
This file contains some templates that are useful if you are working with the STL at all.
This file implements a set that has insertion order iteration characteristics.
This file defines the SmallPtrSet class.
This file defines the SmallVector class.
This file defines the 'Statistic' class, which is designed to be an easy way to expose various metric...
#define STATISTIC(VARNAME, DESC)
Definition Statistic.h:171
#define LLVM_DEBUG(...)
Definition Debug.h:119
Value * RHS
Value * LHS
A manager for alias analyses.
LLVM_ABI ModRefInfo getModRefInfoMask(const MemoryLocation &Loc, bool IgnoreLocals=false)
Returns a bitmask that should be unconditionally applied to the ModRef info of a memory location.
LLVM_ABI MemoryEffects getMemoryEffects(const CallBase *Call)
Return the behavior of the given call site.
Class for arbitrary precision integers.
Definition APInt.h:78
This templated class represents "all analyses that operate over <aparticular IR unit>" (e....
Definition Analysis.h:50
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
This class represents an incoming formal argument to a Function.
Definition Argument.h:32
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
Functions, function parameters, and return types can have attributes to indicate how they should be t...
Definition Attributes.h:105
LLVM_ABI const ConstantRange & getRange() const
Returns the value of the range attribute.
static LLVM_ABI Attribute get(LLVMContext &Context, AttrKind Kind, uint64_t Val=0)
Return a uniquified Attribute object.
LLVM_ABI ArrayRef< ConstantRange > getValueAsConstantRangeList() const
Return the attribute's value as a ConstantRange array.
static LLVM_ABI Attribute getWithNoFPClass(LLVMContext &Context, FPClassTest Mask)
AttrKind
This enumeration lists the attributes that can be associated with parameters, function results,...
Definition Attributes.h:124
static LLVM_ABI Attribute getWithCaptureInfo(LLVMContext &Context, CaptureInfo CI)
bool isValid() const
Return true if the attribute is any kind of attribute.
Definition Attributes.h:261
LLVM Basic Block Representation.
Definition BasicBlock.h:62
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Represents analyses that only rely on functions' control flow.
Definition Analysis.h:73
Base class for all callable instructions (InvokeInst and CallInst) Holds everything related to callin...
LLVM_ABI FPClassTest getParamNoFPClass(unsigned i) const
Extract a test mask for disallowed floating-point value classes for the parameter.
LLVM_ABI FPClassTest getRetNoFPClass() const
Extract a test mask for disallowed floating-point value classes for the return value.
LLVM_ABI MemoryEffects getMemoryEffects() const
bool doesNotCapture(unsigned OpNo) const
Determine whether this data operand is not captured.
Function * getCalledFunction() const
Returns the function called, or null if this is an indirect function invocation or the function signa...
bool hasFnAttr(Attribute::AttrKind Kind) const
Determine whether this call has the given attribute.
bool hasRetAttr(Attribute::AttrKind Kind) const
Determine whether the return value has the given attribute.
unsigned getDataOperandNo(Value::const_user_iterator UI) const
Given a value use iterator, return the data operand corresponding to it.
LLVM_ABI bool paramHasAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Determine whether the argument or parameter has the given attribute.
Attribute getParamAttr(unsigned ArgNo, Attribute::AttrKind Kind) const
Get the attribute of a given kind from a given arg.
bool isByValArgument(unsigned ArgNo) const
Determine whether this argument is passed by value.
bool onlyWritesMemory(unsigned OpNo) const
bool isCallee(Value::const_user_iterator UI) const
Determine whether the passed iterator points to the callee operand's Use.
bool onlyReadsMemory(unsigned OpNo) const
Value * getArgOperand(unsigned i) const
bool isConvergent() const
Determine if the invoke is convergent.
unsigned getArgOperandNo(const Use *U) const
Given a use for a arg operand, get the arg operand number that corresponds to it.
unsigned arg_size() const
bool isArgOperand(const Use *U) const
bool hasOperandBundles() const
Return true if this User has any operand bundles.
Represents which components of the pointer may be captured in which location.
Definition ModRef.h:414
static CaptureInfo none()
Create CaptureInfo that does not capture any components of the pointer.
Definition ModRef.h:427
static CaptureInfo retOnly(CaptureComponents RetComponents=CaptureComponents::All)
Create CaptureInfo that may only capture via the return value.
Definition ModRef.h:434
static CaptureInfo all()
Create CaptureInfo that may capture all components of the pointer.
Definition ModRef.h:430
This class represents a list of constant ranges.
LLVM_ABI void subtract(const ConstantRange &SubRange)
LLVM_ABI void insert(const ConstantRange &NewRange)
Insert a new range to Ranges and keep the list ordered.
bool empty() const
Return true if this list contains no members.
ArrayRef< ConstantRange > rangesRef() const
LLVM_ABI ConstantRangeList intersectWith(const ConstantRangeList &CRL) const
Return the range list that results from the intersection of this ConstantRangeList with another Const...
LLVM_ABI ConstantRangeList unionWith(const ConstantRangeList &CRL) const
Return the range list that results from the union of this ConstantRangeList with another ConstantRang...
This class represents a range of values.
LLVM_ABI bool contains(const APInt &Val) const
Return true if the specified value is in the set.
This is an important base class in LLVM.
Definition Constant.h:43
A parsed version of the target data layout string in and methods for querying it.
Definition DataLayout.h:64
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:223
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:299
iterator end()
Definition DenseMap.h:141
A proxy from a FunctionAnalysisManager to an SCC.
Function summary information to aid decisions and implementation of importing.
ArrayRef< EdgeTy > calls() const
Return the list of <CalleeValueInfo, CalleeInfo> pairs.
FFlags fflags() const
Get function summary flags.
Function and variable summary information to aid decisions and implementation of importing.
static bool isWeakAnyLinkage(LinkageTypes Linkage)
static bool isLinkOnceAnyLinkage(LinkageTypes Linkage)
static bool isLocalLinkage(LinkageTypes Linkage)
static bool isWeakODRLinkage(LinkageTypes Linkage)
uint64_t GUID
Declare a type to represent a global unique identifier for a global value.
static bool isAvailableExternallyLinkage(LinkageTypes Linkage)
static bool isExternalLinkage(LinkageTypes Linkage)
static bool isLinkOnceODRLinkage(LinkageTypes Linkage)
unsigned getOpcode() const
Returns a member of one of the enums like Instruction::Add.
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:68
An analysis pass which computes the call graph for a module.
A node in the call graph.
A RefSCC of the call graph.
An SCC of the call graph.
A lazily constructed view of the call graph of a module.
LLVM_ABI void buildRefSCCs()
iterator_range< postorder_ref_scc_iterator > postorder_ref_sccs()
MemoryEffectsBase getWithoutLoc(Location Loc) const
Get new MemoryEffectsBase with NoModRef on the given Loc.
Definition ModRef.h:231
bool doesNotAccessMemory() const
Whether this function accesses no memory.
Definition ModRef.h:246
static MemoryEffectsBase argMemOnly(ModRefInfo MR=ModRefInfo::ModRef)
Definition ModRef.h:143
ModRefInfo getModRef(Location Loc) const
Get ModRefInfo for the given Location.
Definition ModRef.h:219
static MemoryEffectsBase none()
Definition ModRef.h:128
static MemoryEffectsBase unknown()
Definition ModRef.h:123
Representation for a specific memory location.
static MemoryLocation getBeforeOrAfter(const Value *Ptr, const AAMDNodes &AATags=AAMDNodes())
Return a location that may access any location before or after Ptr, while remaining within the underl...
static LLVM_ABI std::optional< MemoryLocation > getOrNone(const Instruction *Inst)
Class to hold module path string table and global value map, and encapsulate methods for operating on...
A Module instance is used to store all the information related to an LLVM module.
Definition Module.h:67
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &MAM)
op_range incoming_values()
Value * getIncomingValue(unsigned i) const
Return incoming value number x.
unsigned getNumIncomingValues() const
Return the number of incoming edges.
A set of analyses that are preserved following a run of a transformation pass.
Definition Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
PreservedAnalyses & preserveSet()
Mark an analysis set as preserved.
Definition Analysis.h:151
PreservedAnalyses & preserve()
Mark an analysis as preserved.
Definition Analysis.h:132
Return a value (possibly void), from a function.
LLVM_ABI PreservedAnalyses run(Module &M, ModuleAnalysisManager &AM)
This class represents the LLVM 'select' instruction.
size_type size() const
Determine the number of elements in the SetVector.
Definition SetVector.h:103
void insert_range(Range &&R)
Definition SetVector.h:182
bool insert(const value_type &X)
Insert a new element into the SetVector.
Definition SetVector.h:157
size_type count(ConstPtrType Ptr) const
count - Return 1 if the specified pointer is in the set, 0 otherwise.
std::pair< iterator, bool > insert(PtrType Ptr)
Inserts Ptr if and only if there is no element in the container equal to Ptr.
SmallPtrSet - This class implements a set which is optimized for holding SmallSize or less elements.
A SetVector that performs no allocations if smaller than a certain size.
Definition SetVector.h:345
typename SuperClass::iterator iterator
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
static unsigned getPointerOperandIndex()
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
The instances of the Type class are immutable: once they are created, they are never changed.
Definition Type.h:46
A Use represents the edge between a Value definition and its users.
Definition Use.h:35
Value * getOperand(unsigned i) const
Definition User.h:207
LLVM Value Representation.
Definition Value.h:75
LLVM_ABI Align getPointerAlignment(const DataLayout &DL) const
Returns an alignment of the pointer value.
Definition Value.cpp:1002
constexpr ScalarTy getFixedValue() const
Definition TypeSize.h:200
constexpr bool isScalable() const
Returns whether the quantity is scaled by a runtime quantity (vscale).
Definition TypeSize.h:168
An efficient, type-erasing, non-owning reference to a callable.
const ParentTy * getParent() const
Definition ilist_node.h:34
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Enumerate the SCCs of a directed graph in reverse topological order of the SCC DAG.
Definition SCCIterator.h:48
CallInst * Call
Changed
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
bool match(Val *V, const Pattern &P)
ap_match< APFloat > m_APFloat(const APFloat *&Res)
Match a ConstantFP or splatted ConstantVector, binding the specified pointer to the contained APFloat...
initializer< Ty > init(const Ty &Val)
DXILDebugInfoMap run(Module &M)
NodeAddr< UseNode * > Use
Definition RDFGraph.h:385
NodeAddr< NodeBase * > Node
Definition RDFGraph.h:381
iterator end() const
Definition BasicBlock.h:89
LLVM_ABI iterator begin() const
This is an optimization pass for GlobalISel generic memory operations.
@ Low
Lower the current thread's priority such that it does not affect foreground tasks significantly.
Definition Threading.h:280
@ Offset
Definition DWP.cpp:578
@ Length
Definition DWP.cpp:578
bool capturesReadProvenanceOnly(CaptureComponents CC)
Definition ModRef.h:391
LLVM_ABI KnownFPClass computeKnownFPClass(const Value *V, const APInt &DemandedElts, FPClassTest InterestedClasses, const SimplifyQuery &SQ, unsigned Depth=0)
Determine which floating-point classes are valid for V, and return them in KnownFPClass bit sets.
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1739
LLVM_ABI MemoryEffects computeFunctionBodyMemoryAccess(Function &F, AAResults &AAR)
Returns the memory access properties of this copy of the function.
@ Unknown
Not known to have no common set bits.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
auto successors(const MachineBasicBlock *BB)
void append_range(Container &C, Range &&R)
Wrapper function to append range R to container C.
Definition STLExtras.h:2208
scc_iterator< T > scc_begin(const T &G)
Construct the begin iterator for a deduced graph type T.
MemoryEffectsBase< IRMemLocation > MemoryEffects
Summary of how a function affects memory in the program.
Definition ModRef.h:356
LLVM_ABI bool thinLTOPropagateFunctionAttrs(ModuleSummaryIndex &Index, function_ref< bool(GlobalValue::GUID, const GlobalValueSummary *)> isPrevailing)
Propagate function attributes for function summaries along the index's callgraph during thinlink.
OutputIt copy_if(R &&Range, OutputIt Out, UnaryPredicate P)
Provide wrappers to std::copy_if which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1791
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1746
auto reverse(ContainerTy &&C)
Definition STLExtras.h:407
bool isModSet(const ModRefInfo MRI)
Definition ModRef.h:49
void sort(IteratorTy Start, IteratorTy End)
Definition STLExtras.h:1636
FPClassTest
Floating-point class tests, supported by 'is_fpclass' intrinsic.
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition Debug.cpp:209
CaptureComponents
Components of the pointer that may be captured.
Definition ModRef.h:365
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
auto post_order(const T &G)
Post-order traversal of a graph.
bool isa(const From &Val)
isa<X> - Return true if the parameter to the template is an instance of one of the template type argu...
Definition Casting.h:547
LLVM_ABI bool isKnownNonZero(const Value *V, const SimplifyQuery &Q, unsigned Depth=0)
Return true if the given value is known to be non-zero when defined.
ModRefInfo
Flags indicating whether a memory access modifies or references memory.
Definition ModRef.h:28
@ ModRef
The access may reference and may modify the value stored in memory.
Definition ModRef.h:36
@ NoModRef
The access neither references nor modifies the value stored in memory.
Definition ModRef.h:30
@ ErrnoMem
Errno memory.
Definition ModRef.h:66
@ ArgMem
Access to memory via argument pointers.
Definition ModRef.h:62
@ Other
Any other memory.
Definition ModRef.h:68
LLVM_ABI const Value * getUnderlyingObjectAggressive(const Value *V)
Like getUnderlyingObject(), but will try harder to find a single underlying object.
LLVM_ABI bool PointerMayBeCaptured(const Value *V, bool ReturnCaptures, unsigned MaxUsesToExplore=0)
PointerMayBeCaptured - Return true if this pointer value may be captured by the enclosing function (w...
LLVM_ABI bool isGuaranteedNotToBeUndefOrPoison(const Value *V, AssumptionCache *AC=nullptr, const Instruction *CtxI=nullptr, const DominatorTree *DT=nullptr, unsigned Depth=0)
Return true if this function can prove that V does not have undef bits and is never poison.
LLVM_ABI bool isGuaranteedToTransferExecutionToSuccessor(const Instruction *I)
Return true if this function can prove that the instruction I will always transfer execution to one o...
decltype(auto) cast(const From &Val)
cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:559
void erase_if(Container &C, UnaryPredicate P)
Provide a container algorithm similar to C++ Library Fundamentals v2's erase_if which is equivalent t...
Definition STLExtras.h:2192
@ Continue
Definition DWP.h:26
LLVM_ABI bool inferAttributesFromOthers(Function &F)
If we can infer one attribute from another on the declaration of a function, explicitly materialize t...
Definition Local.cpp:4025
LLVM_ABI UseCaptureInfo DetermineUseCaptureKind(const Use &U, const Value *Base)
Determine what kind of capture behaviour U may exhibit.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
bool capturesAll(CaptureComponents CC)
Definition ModRef.h:404
bool capturesNothing(CaptureComponents CC)
Definition ModRef.h:375
bool isNoModRef(const ModRefInfo MRI)
Definition ModRef.h:40
LLVM_ABI void FindFunctionBackedges(const Function &F, SmallVectorImpl< std::pair< const BasicBlock *, const BasicBlock * > > &Result)
Analyze the specified function to find all of the loop backedges in the function and return them.
Definition CFG.cpp:36
LLVM_ABI bool isIdentifiedObject(const Value *V)
Return true if this pointer refers to a distinct and identifiable object.
bool capturesAnyProvenance(CaptureComponents CC)
Definition ModRef.h:400
bool isRefSet(const ModRefInfo MRI)
Definition ModRef.h:52
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
LLVM_ABI bool canReturn(const Function &F)
Return true if there is at least a path through which F can return, false if there is no such path.
Definition CFG.cpp:405
LLVM_ABI ConstantRange computeConstantRange(const Value *V, bool ForSigned, const SimplifyQuery &SQ, unsigned Depth=0)
Determine the possible constant range of an integer or vector of integer value.
#define N
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition Alignment.h:39
static ArgAccessProperties all()
ArgAccessProperties & operator|=(const ArgAccessProperties &Other)
Support structure for SCC passes to communicate updates the call graph back to the CGSCC pass manager...
This callback is used in conjunction with PointerMayBeCaptured.
Flags specific to function summaries.
SmallVectorImpl< ArgumentGraphNode * >::iterator ChildIteratorType
static ChildIteratorType child_begin(NodeRef N)
static ChildIteratorType child_end(NodeRef N)
static ChildIteratorType nodes_end(ArgumentGraph *AG)
static NodeRef getEntryNode(ArgumentGraph *AG)
static ChildIteratorType nodes_begin(ArgumentGraph *AG)
typename ArgumentGraph *::UnknownGraphTypeError NodeRef
Definition GraphTraits.h:95
bool isKnownNever(FPClassTest Mask) const
Return true if it's known this can never be one of the mask entries.
This struct is a compact representation of a valid (power of two) or undefined (0) alignment.
Definition Alignment.h:106
LLVM_ABI PreservedAnalyses run(LazyCallGraph::SCC &C, CGSCCAnalysisManager &AM, LazyCallGraph &CG, CGSCCUpdateResult &UR)
LLVM_ABI void printPipeline(raw_ostream &OS, function_ref< StringRef(StringRef)> MapClassName2PassName)
Capture information for a specific Use.
CaptureComponents UseCC
Components captured by this use.
Struct that holds a reference to a particular GUID in a global value summary.